MyBatis学习教程之开发Dao的方法教程

简介

使用Mybatis开发Dao,通常有两个方法,即原始Dao开发方法和Mapper接口开发方法。下面话不多说,来一起看看详细的介绍:

主要概念介绍:

MyBatis中进行Dao开发时候有几个重要的类,它们是SqlSessionFactoryBuilder、SqlSessionFactory、SqlSession。

SqlSession中封装了对数据库的操作,如:查询、插入、更新、删除等。通过SqlSessionFactory创建SqlSession,而SqlSessionFactory是通过SqlSessionFactoryBuilder进行创建。

1、SqlSessionFactoryBuilder

  SqlSessionFactoryBuilder用于创建SqlSessionFacoty,SqlSessionFacoty一旦创建完成就不需要SqlSessionFactoryBuilder了,因为SqlSession是通过SqlSessionFactory生产,所以可以将SqlSessionFactoryBuilder当成一个工具类使用,最佳使用范围是方法范围即方法体内局部变量。

2、SqlSessionFactory

  SqlSessionFactory是一个接口,接口中定义了openSession的不同重载方法,SqlSessionFactory的最佳使用范围是整个应用运行期间,一旦创建后可以重复使用,通常以单例模式管理SqlSessionFactory。

3、SqlSession

  SqlSession是一个面向用户的接口, sqlSession中定义了数据库操作,默认使用DefaultSqlSession实现类。

  SqlSession中提供了很多操作数据库的方法:如:selectOne(返回单个对象)、selectList(返回单个或多个对象),SqlSession是线程不安全的,在SqlSesion实现类中除了有接口中的方法(操作数据库的方法)还有数据域属性,SqlSession最佳应用场合在方法体内,定义成局部变量使用,绝对不能将SqlSession实例的引用放在一个类的静态字段或实例字段中。

打开一个 SqlSession;使用完毕就要关闭它。通常把这个关闭操作放到 finally 块中以确保每次都能执行关闭。

如下:

SqlSession session = sqlSessionFactory.openSession();
try {
  // do work
} finally {
  session.close();
}

原始Dao开发方式

原始Dao开发方法需要程序员编写Dao接口和Dao实现类。

还是以前文提到的简单的增删改查为例,来简单介绍原始Dao开发方式。

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">
<mapper namespace="user">
 <!-- 根据id获取用户信息 -->
 <select id="findUserById" parameterType="int" resultType="user">
  select * from user where id = #{id}
 </select>
 <!-- 根据username模糊查询用户信息 -->
 <select id="findUserByName" parameterType="java.lang.String" resultType="com.luchao.mybatis.first.po.User">
  select * from user where username like '%${value}%'
 </select>
 <!-- 添加用户信息 -->
 <insert id="insertUser" parameterType="com.luchao.mybatis.first.po.User">
  <selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">
   select LAST_INSERT_ID()
  </selectKey>
  insert into user(username,birthday,sex,address) value (#{username},#{birthday},#{sex},#{address});
 </insert>
 <!-- 根据id删除用户信息 -->
 <delete id="deleteUser" parameterType="int">
  delete from user where id=#{id}
 </delete>
 <!-- 修改用户信息 -->
 <update id="updateUser" parameterType="com.luchao.mybatis.first.po.User">
  update user set username=#{username},birthday=#{birthday},sex=#{sex},address=#{address}
  where id=#{id}
 </update>
</mapper>

2、Dao接口

public interface UserDao {
 //根据ID查询用户信息
 public User findUserById(int id) throws Exception;
 //添加用户信息
 public void insertUser(User user) throws Exception;
 //删除用户信息
 public void deleteUser(int id) throws Exception;
}

3、Dao接口实现类

public class UserDaoImpl implements UserDao{

 // 需要向dao实现类中注入SqlSessionFactory
 // 这里通过构造方法注入
 private SqlSessionFactory sqlSessionFactory;

 public UserDaoImpl(SqlSessionFactory sqlSessionFactory) {
  super();
  this.sqlSessionFactory = sqlSessionFactory;
 }
 @Override
 public void deleteUser(int id) throws Exception {
  SqlSession sqlSession = sqlSessionFactory.openSession();
  //执行删除操作
  sqlSession.insert("user.deleteUser", id);
  // 提交事务
  sqlSession.commit();
  // 释放资源
  sqlSession.close();
 }
 @Override
 public User findUserById(int id) throws Exception {
  SqlSession sqlSession = sqlSessionFactory.openSession();//获取sqlSession
  User user = sqlSession.selectOne("user.findUserById", id);
  sqlSession.close();//关闭资源
  return user;
 }
 @Override
 public void insertUser(User user) throws Exception {
  SqlSession sqlSession = sqlSessionFactory.openSession();
  //执行插入操作
  sqlSession.insert("user.insertUser", user);
  // 提交事务
  sqlSession.commit();
  // 释放资源
  sqlSession.close();
 }
}

4、测试代码:

public class MyBatis_dao_test {
 private SqlSessionFactory sqlSessionFactory;
 @Before
 public void init() throws IOException{
  //创建sqlSessionFactory
  //MyBatis配置文件
  String resource = "SqlMapConfig.xml";
  //得到配置文件流
  InputStream inputStream = Resources.getResourceAsStream(resource);
  //创建会话工厂,传入MyBatis的配置信息
  sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
 }
 @Test
 public void testFindUserById() throws Exception{
  //创建UserDao对象
  UserDao userDao = new UserDaoImpl(sqlSessionFactory);
  //调用UserDao的方法,根据ID查找user
  User user = userDao.findUserById(10);
  //打印客户信息
  System.out.println(user);
 }
}

5、原始Dao方法总结:

  (1)、dao接口实现类方法中存在大量模板方法,如:通过SqlSessionFactory创建SqlSession,调用SqlSession的数据库操作方法。

  (2)、调用sqlSession的数据库操作方法需要指定statement的id,这里存在硬编码。

  (3)、调用sqlsession方法时传入的变量,由于sqlsession方法使用泛型,即使变量类型传入错误,在编译阶段也不报错,不利于程序员开发。

Mapper动态代理方式

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的类型相同。

2、Mapper.xml(映射文件)

映射文件与原始Dao开发的映射文件相似,只需要将namespace定于为mapper接口全路径。

<?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">
<mapper namespace="com.luchao.mybatis.first.mapper.UserMapper">
 <!-- 根据id获取用户信息 -->
 <select id="findUserById" parameterType="int" resultType="user">
  select * from user where id = #{id}
 </select>
 <!-- 根据username模糊查询用户信息 -->
 <select id="findUserByName" parameterType="java.lang.String" resultType="com.luchao.mybatis.first.po.User">
  select * from user where username like '%${value}%'
 </select>
 <!-- 添加用户信息 -->
 <insert id="insertUser" parameterType="com.luchao.mybatis.first.po.User">
  <selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">
   select LAST_INSERT_ID()
  </selectKey>
  insert into user(username,birthday,sex,address) value (#{username},#{birthday},#{sex},#{address});
 </insert>
 <!-- 根据id删除用户信息 -->
 <delete id="deleteUser" parameterType="int">
  delete from user where id=#{id}
 </delete>
 <!-- 修改用户信息 -->
 <update id="updateUser" parameterType="com.luchao.mybatis.first.po.User">
  update user set username=#{username},birthday=#{birthday},sex=#{sex},address=#{address}
  where id=#{id}
 </update>
</mapper>

3、Mapper.java(接口文件)

public interface UserMapper {
 //根据ID查询用户信息
 public User findUserById(int id) throws Exception;
 //添加用户信息
 public void insertUser(User user) throws Exception;
 //删除用户信息
 public void deleteUser(int id) throws Exception;
 //更新用户信息
 public void updateUser(User user) throws Exception;
 //根据用户名模糊查找
 public List<User> findUserByName(String user) throws Exception;
}

接口定义有如下特点:

  (1)、 Mapper接口方法名和Mapper.xml中定义的statement的id相同。

  (2)、 Mapper接口方法的输入参数类型和mapper.xml中定义的statement的parameterType的类型相同。

  (3)、 Mapper接口方法的输出参数类型和mapper.xml中定义的statement的resultType的类型相同。

4、加载UserMapper.xml文件

在SqlMapConfig.xml文件中加载UserMapper.xml,如下:

 <mappers>
  <mapper resource="mapper/UserMapper.xml"/>
 </mappers>

5、测试代码:

public class MyBatis_mapper_test {
 private SqlSessionFactory sqlSessionFactory;
 @Before
 public void init() throws IOException{
  //创建sqlSessionFactory
  //MyBatis配置文件
  String resource = "SqlMapConfig.xml";
  //得到配置文件流
  InputStream inputStream = Resources.getResourceAsStream(resource);
  //创建会话工厂,传入MyBatis的配置信息
  sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
 }
 @Test
 public void testFindUserById() throws Exception{
  //获取sqlSession对象
  SqlSession sqlSession = sqlSessionFactory.openSession();
  //创建UserMapper对象,MyBatis自动生成mapper代理
  UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
  //调用userMapper的方法
  User user = userMapper.findUserById(10);
  //关闭资源
  sqlSession.close();
  //打印客户信息
  System.out.println(user);
 }
}

5、Mapper动态代理总结:

  (1)、动态代理对象调用sqlSession.selectOne()sqlSession.selectList()是根据mapper接口方法的返回值决定,如果返回list则调用selectList方法,如果返回单个对象则调用selectOne方法。

  (2)、使用mapper代理方法时,输入参数可以使用pojo包装对象或map对象,保证dao的通用性。在系统中,dao层的代码是被业务层公用的。即使mapper接口只有一个参数,可以使用包装类型的pojo满足不同的业务方法的需求。

注意:持久层方法的参数可以包装类型、map等,service方法中建议不要使用包装类型(不利于业务层的可扩展)。

mybatis开发dao的方法有两种:原始Dao开发和Mapper动态代理开发,这两种各有优点。原始Dao开发:程序员要写Dao和Dao实现,需要些较多的代码,但是比较好理解。Mapper动态代理:程序员只需要写Mapper接口,然后按照规范进行配置,MyBatis就会自动实现类似Dao实现,减少模板方法。mybatis官方推荐使用mapper代理方法开发mapper接口,程序员不用编写mapper接口实现类,使用mapper代理方法时,输入参数可以使用pojo包装对象或map对象,保证dao的通用性。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对我们的支持。

时间: 2017-07-07

Mybatis中通过generator生成mapper、Dao、mapper.xml的方法

1.将如下东西复制到项目中,或某一个文件夹. 2.更改generator.xml (1)更改数据驱动包的位置,选择你所安装的目录: (2)更改你所要连接的数据库的名称,数据库的user和password (3)更改下图 targetPakage的地方,targetProject的地方,这里targetProject所在的地方一定要存在 要不然会报错 (4)在tableName中填写你所要填写的表名.domainObjectName填写你想要生成的名字. 3.进入命令行窗口运行: 1.进入项目 的

详解MyBatis Generator自动创建代码(dao,mapping,poji)

连接的数据库为SQL server2008,所以需要的文件为sqljdbc4.jar 使用的lib库有: 在lib库目录下新建一个src文件夹用来存放生成的文件,然后新建generatorConfig.xml 里面代码为: <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE generatorConfiguration PUBLIC "-//mybatis.org//DTD MyBatis G

对dbunit进行mybatis DAO层Excel单元测试(必看篇)

DAO层测试难点 可重复性,每次运行单元测试,得到的数据是重复的 独立性,测试数据与实际数据相互独立 数据库中脏数据预处理 不能给数据库中数据带来变化 DAO层测试方法 使用内存数据库,如H2.优点:无需清空无关数据:缺点:单元测试中需要进行数据库初始化过程,如果初始化过程复杂,单元测试工作量增大 使用dbunit.优点:数据库初始化简单,大大减轻单元测试工作量:缺点:目前官方提供jar包只支持xml格式文件,需要自己开发Excel格式文件 基于dbunit进行DAO单元测试 应用环境:Spri

Spring+SpringMVC+MyBatis深入学习及搭建(二)之MyBatis原始Dao开发和mapper代理开发

前面有写到Spring+SpringMVC+MyBatis深入学习及搭建(一)--MyBatis的基础知识.MybatisFirst中存在大量重复的代码.这次简化下代码: 使用MyBatis开发Dao,通常有两种方法,即原始Dao开发方法和Mapper接口开发方法. 1.SqlSession使用范围 1.1 SqlsessionFactoryBuilder 通过SqlSessionFactoryBuilder创建会话工厂SqlSessionFactory,将SqlSessionFactoryBu

MyBatis实践之DAO与Mapper

MyBatis简介 MyBatis前身是iBatis,是一个基于Java的数据持久层/对象关系映射(ORM)框架. MyBatis是对JDBC的封装,使开发人员只需关注SQL本身,而不需花费过多的精力去处理如注册驱动.设置参数.创建Connection/Statement.解析结果集等JDBC过程性代码.MyBatis基于XML/注解的方式配置Statement,执行SQL,并将执行结果映射成Java对象, 大大降低了数据库开发的难度. MyBatis is a first class pers

Java的MyBatis+Spring框架中使用数据访问对象DAO模式的方法

SqlSessionTemplate SqlSessionTemplate是MyBatis-Spring的核心.这个类负责管理MyBatis的SqlSession,调用MyBatis的SQL方法,翻译异常.SqlSessionTemplate是线程安全的,可以被多个DAO所共享使用. 当调用SQL方法时,包含从映射器getMapper()方法返回的方法,SqlSessionTemplate将会保证使用的SqlSession是和当前Spring的事务相关的.此外,它管理session的生命周期,包

Yii学习总结之数据访问对象 (DAO)

Yii提供了强大的数据库编程支持.Yii数据访问对象(DAO)建立在PHP的数据对象(PDO)extension上,使得在一个单一的统一的接口可以访问不同的数据库管理系统(DBMS).使用Yii的DAO开发的应用程序可以很容易地切换使用不同的数据库管理系统,而不需要修改数据访问代码. 数据访问对象(DAO) 对访问存储在不同数据库管理系统(DBMS)中的数据提供了一个通用的API. 因此,在将底层 DBMS 更换为另一个时,无需修改使用了 DAO 访问数据的代码. Yii DAO 基于 PHP

Java的Spring框架中DAO数据访问对象的使用示例

Spring DAO之JDBC   Spring提供的DAO(数据访问对象)支持主要的目的是便于以标准的方式使用不同的数据访问技术, 如JDBC,Hibernate或者JDO等.它不仅可以让你方便地在这些持久化技术间切换, 而且让你在编码的时候不用考虑处理各种技术中特定的异常. 为了便于以一种一致的方式使用各种数据访问技术,如JDBC.JDO和Hibernate, Spring提供了一套抽象DAO类供你扩展.这些抽象类提供了一些方法,通过它们你可以 获得与你当前使用的数据访问技术相关的数据源和其

详解Java的Spring框架中的事务管理方式

数据库事务是被当作单个工作单元的操作序列.这些操作要么全部完成或全部不成功.事务管理是面向企业应用程序,以确保数据的完整性和一致性RDBMS中的重要组成部分.事务的概念可以用下面的描述为ACID四个关键属性来描述: 原子性: 一个事务应该被视为单个操作单元表示的操作的任一整个序列是成功的或不成功的. 一致性: 这代表了数据库的参照完整性,在桌等唯一主键的一致性 隔离性: 可能有很多事务处理相同的数据集的同时,每个事务都应由他人隔离,以防止数据损坏. 持久性: 一旦事务完成,本次事务的结果必须作出

Java的Spring框架中AOP项目的一般配置和部署教程

0.关于AOP 面向切面编程(也叫面向方面编程):Aspect Oriented Programming(AOP),是软件开发中的一个热点,也是Spring框架中的一个重要内容.利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率. AOP是OOP的延续. 主要的功能是:日志记录,性能统计,安全控制,事务处理,异常处理等等. 主要的意图是:将日志记录,性能统计,安全控制,事务处理,异常处理等代码从业务逻辑代码中划分出来,通过

深入理解Java的Spring框架中的IOC容器

Spring IOC的原型 spring框架的基础核心和起点毫无疑问就是IOC,IOC作为spring容器提供的核心技术,成功完成了依赖的反转:从主类的对依赖的主动管理反转为了spring容器对依赖的全局控制. 这样做的好处是什么呢? 当然就是所谓的"解耦"了,可以使得程序的各模块之间的关系更为独立,只需要spring控制这些模块之间的依赖关系并在容器启动和初始化的过程中将依据这些依赖关系创建.管理和维护这些模块就好,如果需要改变模块间的依赖关系的话,甚至都不需要改变程序代码,只需要将

设计模式在Spring框架中的应用汇总

这篇文章主要介绍了设计模式在Spring框架中的应用汇总,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 在开始正文之前,请你先思考几个问题: 你项目中有使用哪些 GOF 设计模式 说一说 GOF 23 种设计模式的设计理念 说说 Spring 框架中如何实现设计模式 假设我是面试官问起了你这些面试题,你该如何回答呢,请先思考一分钟. 好的,我们开始进入正题.设计模式实践里面提供了许多经久不衰的解决方案和最佳方案.这里,GOF 设计模式主要分为三

使用spring框架中的组件发送邮件功能说明

Spring框架是由于软件开发的复杂性而创建的.Spring使用的是基本的JavaBean来完成以前只可能由EJB完成的事情.然而,Spring的用途不仅仅限于服务器端的开发.从简单性.可测试性和松耦合性角度而言,绝大部分Java应用都可以从Spring中受益. 首先进入自己的QQ邮箱,在设置中修改账户信息 然后来至底部 点击开启,再用手机发送对应信息到指定号码,然后点击我已发送 获取授权码 注意提示: 到这里,相信你已经开通了SMTP服务,这样就可以在java code发送邮件了 接下来的是S

Spring框架中 @Autowired 和 @Resource 注解的区别

Spring框架中 @Autowired 和 @Resource 注解的区别 在 spring 框架中,除了使用其特有的注解外,使用基于 JSR-250 的注解,它包括 @PostConstruct, @PreDestroy 和 @Resource 注释. 首先,咱们简单了解 @PostConstruct 和 @PreDestroy 注释: 为了定义一个 bean 的安装和卸载,我们可以使用 init-method 和 destroy-method 参数简单的声明一下 ,其中 init-meth

java获取两个数组中不同数据的方法

本文实例讲述了java获取两个数组中不同数据的方法.分享给大家供大家参考.具体实现方法如下: public static <T> List<T> compare(T[] t1, T[] t2) { List<T> list1 = Arrays.asList(t1); List<T> list2 = new ArrayList<T>(); for (T t : t2) { if (!list1.contains(t)) { list2.add(t)