一、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开发方法的更多相关文章

  1. Mybatis笔记 - 原始Dao开发方法

    使用Mybatis开发Dao,通常有两个方法,即原始Dao开发方法和Mapper接口开发方法.原始Dao的开发方式是基于入门程序的基础上,对 控制程序 进行分层开发,程序员需要 编写 Dao接口 和 ...

  2. Mybatis学习2传统dao开发

    传统dao开发 在mybati基础上 dao和daoimpl 1.工厂工具类 获得SqlSessionFactory SqlSessionFactoryUtil.java package util; ...

  3. MyBatis学习笔记(三) Configuration类

    一.初探Configuration类 我们先来看一下MyBatis的XML配置文件的结构,(摘自mybatis.org) 下面这个是Configuration类的部分变量 一点不一样是不是??? 其实 ...

  4. MyBatis学习笔记(三) 关联关系

    首先给大家推荐几个网页: http://blog.csdn.net/isea533/article/category/2092001 没事看看 - MyBatis工具:www.mybatis.tk h ...

  5. NLP自然语言处理学习笔记三(集成开发环境)

    前言: 我们在做自然语言学习的过程中使用Python进行编程.是用解析器的方式确实有些麻烦.在这里给大家推荐一款集成开发环境IDE可以很方便的对Python进行项目管理,代码自动提示,运行调试等. 简 ...

  6. mybatis学习笔记三(关联关系)

    学习mybatis的关联关系,主要注解在代码上,这里不做解释.配置文件一样的就不贴了 1.关联关系表创建(学生对应老师 多对一) 学生老师表 2.表对应的实体类 package com.home.en ...

  7. MyBatis学习笔记(三)——优化MyBatis配置文件中的配置

    转自孤傲苍狼的博客:http://www.cnblogs.com/xdp-gacl/p/4264301.html 一.连接数据库的配置单独放在一个properties文件中 之前,我们是直接将数据库的 ...

  8. Mybatis学习笔记三

    一.延迟加载 延迟加载即加载延迟了,并不是一次性加载完而是按需加载,感觉应该是针对多表查询而言的,即先查询单表等需要另一张表的信息时再去加载,这样能提高数据库的性能: 需要注意的是,mybatis提供 ...

  9. mybatis学习笔记(三)-- 优化数据库连接配置

    原来直接把数据库连接配置信息写在conf.xml配置中,如下 <?xml version="1.0" encoding="UTF-8"?> < ...

随机推荐

  1. python的面向对象编程

    面向对象编程是一种程序的范式,它把程序看成是对不同对象的相互调用,对现实世界建立的一种模型. 面向对象编程的基本思想,类和实例.类用于定义抽象对象,实例根据类的定义被创建出来. 在python当中我们 ...

  2. 窗体控件JFrame的使用

    ---------------siwuxie095 工程名:TestUI 包名:com.siwuxie095.ui 类名:MyFrame.java 工程结构目录如下: 在 Source 界面和 Des ...

  3. Python 网络爬虫 004 (编程) 如何编写一个网络爬虫,来下载(或叫:爬取)一个站点里的所有网页

    爬取目标站点里所有的网页 使用的系统:Windows 10 64位 Python语言版本:Python 3.5.0 V 使用的编程Python的集成开发环境:PyCharm 2016 04 一 . 首 ...

  4. Arduino 003 Ubuntu(Linux) 系统下,如何给板子烧写程序

    Ubuntu/Linux 系统下,如何给Arduino板子烧写程序 使用的虚拟机软件:VMware 11 我的Ubuntu系统:Ubuntu 14.04.10 TLS Arduino 软件的版本:Ar ...

  5. (转)typedef和#define的用法与区别

    typedef和#define的用法与区别 一.typedef的用法 在C/C++语言中,typedef常用来定义一个标识符及关键字的别名,它是语言编译过程的一部分,但它并不实际分配内存空间,实例像: ...

  6. Android 菜单之子菜单SubMenu

    子菜单就是在点击了菜单中的选项后弹出的要对菜单中选项操作的菜单           他的操作与之前的两种类型的菜单操作差不多 动态添加 @Override public boolean onCreat ...

  7. parseXXX的用法

    转换字符串. parseXXX是Integer类.等基本数据类型包装类的方法,用于实现String和int型数据的转换.例如, Integer.getInteger(String s) 从字符串中获取 ...

  8. Entity Framework Tutorial Basics(34):Table-Valued Function

    Table-Valued Function in Entity Framework 5.0 Entity Framework 5.0 supports Table-valued functions o ...

  9. 安装visual_Paradigm,时序图的应用

    此安装包已经上传到sunny的百度网盘. 删除,即,右击别的地方,然后,选择delete即可. 拖箭头,拖到某个实体上,再松开,会自动连线. 很好的一款画图工具.

  10. python sort、sorted、reverse、reverd的区别

    sort.sorted.reverse.reversed的区别 !!! error 首先应该区分的是,sort和reverse是列表的一个方法.字符串.元组.字典.集合是没有这两个方法的.而sorte ...