Mybatis学习笔记(三) —— DAO开发方法
一、SqlSession的使用范围
SqlSession中封装了对数据库的操作,如:查询、插入、更新、删除等。
SqlSession通过SqlSessionFactory创建。
SqlSessionFactory是通过SqlSessionFactoryBuilder进行创建。
1.1 SqlSessionFactoryBuilder
SqlSessionFactoryBuilder用于创建SqlSessionFacoty,SqlSessionFacoty一旦创建完成就不需要SqlSessionFactoryBuilder了,因为SqlSession是通过SqlSessionFactory创建的。所以可以将SqlSessionFactoryBuilder当成一个工具类使用,最佳使用范围是方法范围即方法体内局部变量。
1.2 SqlSessionFactory
SqlSessionFactory是一个接口,接口中定义了openSession的不同重载方法,SqlSessionFactory的最佳使用范围是整个应用运行期间,一旦创建后可以重复使用,通常以单例模式管理SqlSessionFactory。
1.3 SqlSession
SqlSession是一个面向用户的接口,sqlSession中定义了数据库操作方法。
每个线程都应该有它自己的SqlSession实例。SqlSession的实例不能共享使用,它也是线程不安全的。因此最佳的范围是请求或方法范围。绝对不能将SqlSession实例的引用放在一个类的静态字段或实例字段中。
打开一个 SqlSession;使用完毕就要关闭它。通常把这个关闭操作放到 finally 块中以确保每次都能执行关闭。如下:
SqlSession session = sqlSessionFactory.openSession();
try {
// do work
} finally {
session.close();
}
二、原始Dao开发方法(了解)
原始Dao开发方法需要程序员编写Dao接口和Dao实现类。
2.1 映射文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- namespace:命名空间,用于隔离sql,还有一个很重要的作用,后面会讲 -->
<mapper namespace="test"> <!-- 根据id查询用户 -->
<select id="queryUserById" parameterType="int"
resultType="cn.itcast.mybatis.pojo.User">
select * from user where id = #{id}
</select> <!-- 根据username模糊查询用户 -->
<select id="queryUserByUsername" parameterType="string"
resultType="cn.itcast.mybatis.pojo.User">
select * from user where username like '%${value}%'
</select> <!-- 保存用户 -->
<insert id="saveUser" parameterType="cn.itcast.mybatis.pojo.User">
<selectKey keyProperty="id" keyColumn="id" order="AFTER"
resultType="int">
SELECT LAST_INSERT_ID()
</selectKey>
insert into user(username,birthday,sex,address)
values(#{username},#{birthday},#{sex},#{address})
</insert> </mapper>
2.2 DAO接口
public interface UserDao {
/**
* 根据id查询用户
*
* @param id
* @return
*/
User queryUserById(int id);
/**
* 根据用户名模糊查询用户
*
* @param username
* @return
*/
List<User> queryUserByUsername(String username);
/**
* 保存用户
*
* @param user
*/
void saveUser(User user);
}
2.3 DAO实现类
public class UserDaoImpl implements UserDao {
private SqlSessionFactory sqlSessionFactory;
public UserDaoImpl(SqlSessionFactory sqlSessionFactory) {
super();
this.sqlSessionFactory = sqlSessionFactory;
}
@Override
public User queryUserById(int id) {
// 创建SqlSession
SqlSession sqlSession = this.sqlSessionFactory.openSession();
// 执行查询逻辑
User user = sqlSession.selectOne("queryUserById", id);
// 释放资源
sqlSession.close();
return user;
}
@Override
public List<User> queryUserByUsername(String username) {
// 创建SqlSession
SqlSession sqlSession = this.sqlSessionFactory.openSession();
// 执行查询逻辑
List<User> list = sqlSession.selectList("queryUserByUsername", username);
// 释放资源
sqlSession.close();
return list;
}
@Override
public void saveUser(User user) {
// 创建SqlSession
SqlSession sqlSession = this.sqlSessionFactory.openSession();
// 执行保存逻辑
sqlSession.insert("saveUser", user);
// 提交事务
sqlSession.commit();
// 释放资源
sqlSession.close();
}
}
2.4 DAO测试
public class UserDaoTest {
private SqlSessionFactory sqlSessionFactory;
@Before
public void init() throws Exception {
// 创建SqlSessionFactoryBuilder
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
// 加载SqlMapConfig.xml配置文件
InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
// 创建SqlsessionFactory
this.sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);
}
@Test
public void testQueryUserById() {
// 创建DAO
UserDao userDao = new UserDaoImpl(this.sqlSessionFactory);
// 执行查询
User user = userDao.queryUserById(1);
System.out.println(user);
}
@Test
public void testQueryUserByUsername() {
// 创建DAO
UserDao userDao = new UserDaoImpl(this.sqlSessionFactory);
// 执行查询
List<User> list = userDao.queryUserByUsername("张");
for (User user : list) {
System.out.println(user);
}
}
@Test
public void testSaveUser() {
// 创建DAO
UserDao userDao = new UserDaoImpl(this.sqlSessionFactory);
// 创建保存对象
User user = new User();
user.setUsername("刘备");
user.setBirthday(new Date());
user.setSex("1");
user.setAddress("蜀国");
// 执行保存
userDao.saveUser(user);
System.out.println(user);
}
}
2.5 存在的问题
Dao方法体存在重复代码:通过SqlSessionFactory创建SqlSession,调用SqlSession的数据库操作方法
调用sqlSession的数据库操作方法需要指定statement的id,这里存在硬编码,不得于开发维护。
三、Mapper动态代理方式 (重点)
3.1 开发规范
Mapper接口开发方法只需要程序员编写Mapper接口(相当于Dao接口),由Mybatis框架根据接口定义创建接口的动态代理对象,代理对象的方法体同上边Dao接口实现类方法。
Mapper接口开发需要遵循以下规范:
1、Mapper.xml文件中的namespace与mapper接口的类路径相同。
2、Mapper接口方法名和Mapper.xml中定义的每个statement的id相同
3、Mapper接口方法的输入参数类型和mapper.xml中定义的每个sql 的parameterType的类型相同
4、Mapper接口方法的输出参数类型和mapper.xml中定义的每个sql的resultType的类型相同
3.2 Mapper.xml(映射文件)
定义mapper映射文件UserMapper.xml
将UserMapper.xml放在config下mapper目录下,效果如下:

UserMapper.xml配置文件内容:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!-- namespace:命名空间,用于隔离sql -->
<!-- 还有一个很重要的作用:使用动态代理开发DAO,namespace必须和Mapper接口路径一致 -->
<mapper namespace="cn.itcast.mybatis.mapper.UserMapper">
<!-- 根据用户id查询用户 -->
<!-- id必须和Mapper接口方法名一致 -->
<!-- parameterType必须和接口方法参数类型一致 -->
<!-- resultType必须和接口方法返回值类型一致 -->
<select id="queryUserById" parameterType="int" resultType="cn.itcast.mybatis.pojo.User">
SELECT * FROM `user` WHERE id = #{id}
</select> <!-- 根据用户名模糊查询用户 -->
<select id="queryUserByUsername" parameterType="string" resultType="cn.itcast.mybatis.pojo.User">
SELECT * FROM `user` WHERE username LIKE '%${value}%'
</select> <!-- 保存用户 -->
<insert id="saveUser" parameterType="cn.itcast.mybatis.pojo.User">
<selectKey keyColumn="id" keyProperty="id" order="AFTER" resultType="int">
SELECT LAST_INSERT_ID()
</selectKey> INSERT INTO `user`(username,birthday,sex,address) VALUES
(#{username},#{birthday},#{sex},#{address});
</insert>
</mapper>
3.3 UserMapper(接口文件)
public interface UserMapper {
/**
* 根据用户id查询用户
* @param id
* @return
*/
User queryUserById(int id);
/**
* 根据用户名模糊查询用户
* @param username
* @return
*/
List<User> queryUserByUsername(String username);
/**
* 保存用户
* @param user
*/
void saveUser(User user);
}
3.4 加载UserMapper.xml文件
修改SqlMapConfig.xml文件,添加以下所示的内容:
<!-- 加载映射文件 -->
<mappers>
<mapper resource="sqlmap/User.xml" />
<mapper resource="mapper/UserMapper.xml" />
</mappers>
3.5 测试
public class UserMapperTest {
private SqlSessionFactory sqlSessionFactory;
@Before
public void init() throws Exception{
// 创建SqlSessionFactoryBuilder对象
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
// 加载SqlMapConfig.xml配置文件
InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
// 创建sqlSessionFactory
sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);
}
@Test
public void testQueryUserById() throws Exception {
// 获取sqlSession,和spring整合后由spring管理
SqlSession sqlSession = sqlSessionFactory.openSession();
// 从sqlSession中获取Mapper接口的代理对象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
// 执行查询方法
User user = userMapper.queryUserById(32);
System.out.println(user);
// 和spring整合后由spring管理
sqlSession.close();
}
@Test
public void testQueryUserByUsername() throws Exception {
// 获取sqlSession,和spring整合后由spring管理
SqlSession sqlSession = sqlSessionFactory.openSession();
// 从sqlSession中获取Mapper接口的代理对象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
// 执行查询方法
List<User> list = userMapper.queryUserByUsername("王");
for (User user : list) {
System.out.println(user);
}
// 和spring整合后由spring管理
sqlSession.close();
}
@Test
public void testSaveUser() throws Exception {
// 获取sqlSession,和spring整合后由spring管理
SqlSession sqlSession = sqlSessionFactory.openSession();
// 从sqlSession中获取Mapper接口的代理对象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
// 创建保存对象
User user = new User();
user.setUsername("张飞");
user.setAddress("蜀国");
user.setSex("男");
user.setBirthday(new Date());
// 执行保存方法
userMapper.saveUser(user);
// 和spring整合后由spring管理
sqlSession.commit();
sqlSession.close();
}
}
Mybatis学习笔记(三) —— DAO开发方法的更多相关文章
- Mybatis笔记 - 原始Dao开发方法
使用Mybatis开发Dao,通常有两个方法,即原始Dao开发方法和Mapper接口开发方法.原始Dao的开发方式是基于入门程序的基础上,对 控制程序 进行分层开发,程序员需要 编写 Dao接口 和 ...
- Mybatis学习2传统dao开发
传统dao开发 在mybati基础上 dao和daoimpl 1.工厂工具类 获得SqlSessionFactory SqlSessionFactoryUtil.java package util; ...
- MyBatis学习笔记(三) Configuration类
一.初探Configuration类 我们先来看一下MyBatis的XML配置文件的结构,(摘自mybatis.org) 下面这个是Configuration类的部分变量 一点不一样是不是??? 其实 ...
- MyBatis学习笔记(三) 关联关系
首先给大家推荐几个网页: http://blog.csdn.net/isea533/article/category/2092001 没事看看 - MyBatis工具:www.mybatis.tk h ...
- NLP自然语言处理学习笔记三(集成开发环境)
前言: 我们在做自然语言学习的过程中使用Python进行编程.是用解析器的方式确实有些麻烦.在这里给大家推荐一款集成开发环境IDE可以很方便的对Python进行项目管理,代码自动提示,运行调试等. 简 ...
- mybatis学习笔记三(关联关系)
学习mybatis的关联关系,主要注解在代码上,这里不做解释.配置文件一样的就不贴了 1.关联关系表创建(学生对应老师 多对一) 学生老师表 2.表对应的实体类 package com.home.en ...
- MyBatis学习笔记(三)——优化MyBatis配置文件中的配置
转自孤傲苍狼的博客:http://www.cnblogs.com/xdp-gacl/p/4264301.html 一.连接数据库的配置单独放在一个properties文件中 之前,我们是直接将数据库的 ...
- Mybatis学习笔记三
一.延迟加载 延迟加载即加载延迟了,并不是一次性加载完而是按需加载,感觉应该是针对多表查询而言的,即先查询单表等需要另一张表的信息时再去加载,这样能提高数据库的性能: 需要注意的是,mybatis提供 ...
- mybatis学习笔记(三)-- 优化数据库连接配置
原来直接把数据库连接配置信息写在conf.xml配置中,如下 <?xml version="1.0" encoding="UTF-8"?> < ...
随机推荐
- 控制器对应view生命周期
一.控制器view创建的六种方式 1.有没有同名xib创建2.通过 storyboard 创建3.有指定xib情况下创建4.有同名xib情况5.有同名去掉controll的情况6.loadveiw ...
- struts2学习笔记(4)接收参数
①用action属性接收 登录界面例子 在webroot下创建login.jsp和success.jsp login.jsp中加入表单: <form action="LoginActi ...
- WEB-INF与Webroot
WEB-INF:放在WEB-INF下的资源是浏览器访问不到的,但后台程序能跳转到的,但重定向不行
- TextView下划线,部分文字并响应点击事件(SpannableString)
TextView useInfo = (TextView) findViewById(R.id.info); useInfo.setText("开始即表示您同意遵守"); Stri ...
- wenfrom的简单控件和repeater控件
简单控件 lable 转换成<span>标记 literal 空的 什么也没转换 Literal.Text=<script>alter('你好');</scrip ...
- (转)Linux网络协议栈(三)——网络设备(1)
网络设备(network device)是内核对网络适配器(硬件)的抽象与封装,并为各个协议实例提供统一的接口,它是硬件与内核的接口,它有两个特征:(1) 作为基于硬件的网络适配器与基于软件的协 ...
- acrord32 pdf自动化
这个东西就是帮助用户自动化处理pdf的 . 可以看作是adobe reader的命令行
- rest-framework组件 之 分页
分页 简单分页 from rest_framework.pagination import PageNumberPagination,LimitOffsetPagination class PNPag ...
- bootstrap学习网址
http://www.bootcss.com/ bootstrap中文学习网址
- 数据结构_stack
问题描述 一天,小 L 发现了一台支持一下操作的机器:IN x:将整数 x 入栈POP:将栈顶元素出栈ASUB:出栈两个数,将两数差的绝对值入栈COPY:将栈顶元素(如果有的话)复制一份,入栈现在小 ...