一、mybatis简介

1.1 什么是mybatis?

(1)mybatis的概念

①mybatis是一款持久层框架;
②它支持定制化SQL、存储过程以及高级映射;
③mybatis避免了几乎所有的jdbc代码和手动设置以及获取结果集;
④mybatis可以使用简单的xml或注解来配置和映射原生类型、接口和Java的 POJO(Plain Old Java Objects,普通老式的Java对象)为数据库中的记录;
⑤mybatis本事apache的一个开源项目Batis,在2010年这个项目由apache software foundation迁移到了Google code下,并且改名为mybatis;
2013年11月迁移至GitHub下

(2)mybatis的作用

①帮助程序开发者将数据持久化(存入到数据库中);
②方便;
③不用mybatis也可以,不过用了mybatis更容易上手,技术没有高低之分;
④优点:

  • 简单易学;
  • 灵活;
  • SQL和代码分离,提高了可维护性;
  • 提供了映射标签,支持对象与数据库的ORM字段关系映射;
  • 提供对象关系映射标签,支持对象关系组件维护;
  • 提供xml标签,支持编写动态SQL;

(3)第一个mybatis程序

  • SqlSession常见的方法 | 返回值 | 方法名 | 说明 | | —- | —- | —- | | List | selectList(String statement,Object parameter) | 执行查询语句,返回list集合 | | T | selectOne(String statement,Object parameter) | 执行查询语句,返回一个结果对象 | | int | insert(String statement,Object parameter) | 执行新增语句,返回影响行数 | | int | update(String statement,Object parameter) | 执行修改语句,返回影响行数 | | int | delete(String statement,Object parameter) | 执行删除语句,返回影响行数 | | void | commit() | 提交事务 | | void | rollback() | 回滚事务 | | T | getMapper(Class cls) | 获取指定接口的代理实现类对象 | | void | close() | 释放资源 |

  • 新建项目

    • 新建一个普通的maven项目;
    • 删除src目录;
    • 导入maven的mybatis依赖;
      1. <!--mybatis_-->
      2. <dependency>
      3. <groupId>org.mybatis</groupId>
      4. <artifactId>mybatis</artifactId>
      5. <version>3.5.3</version>
      6. </dependency>
      7. <!--mysql-->
      8. <dependency>
      9. <groupId>mysql</groupId>
      10. <artifactId>mysql-connector-java</artifactId>
      11. <version>5.1.46</version>
      12. </dependency>
      13. <!--junit-->
      14. <dependency>
      15. <groupId>junit</groupId>
      16. <artifactId>junit</artifactId>
      17. <version>4.12</version>
      18. <scope>test</scope>
      19. </dependency>
  • 创建一个模块

    • 编写mybatis的核心配置文件

      1. <?xml version="1.0" encoding="UTF-8"?>
      2. <!DOCTYPE configuration
      3. PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
      4. "http://mybatis.org/dtd/mybatis-3-config.dtd">
      5. <configuration>
      6. <!--配置默认环境-->
      7. <environments default="mysql">
      8. <!--配置mysql的环境-->
      9. <environment id="mysql">
      10. <!--配置事务的类型-->
      11. <transactionManager type="JDBC"/>
      12. <!--配置数据源信息-->
      13. <dataSource type="POOLED" >
      14. <!--配置连接数据库的四个基本信息-->
      15. <property name="driver" value="com.mysql.jdbc.Driver"></property>
      16. <property name="url" value="jdbc:mysql://localhost:3306/test?useSSL=true&amp;useUnicode=true&amp;characterEncoding=UTF-8"></property>
      17. <property name="username" value="root"></property>
      18. <property name="password" value="960317"></property>
      19. </dataSource>
      20. </environment>
      21. </environments>
      22. <!--配置映射配置文件的位置-->
      23. <mappers>
      24. <!--指定实体映射配置文件所在的包,指定的是dao接口所在的包-->
      25. <package name="com.xiao.ha.dao"></package>
      26. </mappers>
      27. </configuration>
    • 编写mybatis工具类 ```java package com.xiao.ha.factory;

import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.InputStream;

/**

  • 用于生成dao接口代理实现类的工厂
  • @author HarsonLee
  • @date 2021/03/15 */ public class MapperFactory {

    private static SqlSessionFactory factory; private static ThreadLocal tl = new ThreadLocal();

    static {

    1. InputStream in = null;
    2. try {
    3. //1.读取mybatis主配置文件
    4. in = Resources.getResourceAsStream("SqlMapConfig.xml");
    5. //2.创建构建者对象
    6. SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
    7. //3.使用构建者创建SqlSessionFactory工厂
    8. factory = builder.build(in);
    9. }catch (Exception e){
    10. //打印异常信息到控制台
    11. e.printStackTrace();
    12. //抛出错误提示程序终止执行
    13. throw new ExceptionInInitializerError("初始化SqlSessionFactory失败");
    14. }finally {
    15. //释放流对象
    16. if(in != null){
    17. try{
    18. in.close();
    19. }catch (Exception e){
    20. e.printStackTrace();
    21. }
    22. }
    23. }

    }

    /**

    • 获取SqlSession对象
    • @return
    • 保留此方法是为了后面对业务层方法增强,利用AOP添加事务 */ public static SqlSession getSqlSession(){ return factory.openSession(false); }

      /**

    • 获取Dao接口的代理实现类
    • @param daoClass dao接口字节码
    • @return */ public static T getMapper(SqlSession sqlSession,Class daoClass){ //1.判断传入的SqlSession是否为null if(sqlSession == null){
      1. return null;
      } //2.不为null,创建代理实现类 return sqlSession.getMapper(daoClass); } } ```
    • 编写JavaPOJO类
    • 编写dao接口
    • 编写mybatis映射文件

      1. <?xml version="1.0" encoding="UTF-8"?>
      2. <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
      3. <!--名称空间:指定的是接口的全类名-->
      4. <mapper namespace="com.xiao.ha.dao.store.CatalogDao">
      5. <!--配置实体类属性和数据库表中列的对应关系-->
      6. <resultMap id="BaseResultMap" type="com.xiao.ha.bean.store.Catalog">
      7. <id column="id" jdbcType="VARCHAR" property="id"/>
      8. <result column="name" jdbcType="VARCHAR" property="name"/>
      9. <result column="remark" jdbcType="VARCHAR" property="remark"/>
      10. <result column="state" jdbcType="VARCHAR" property="state"/>
      11. <result column="course_id" jdbcType="VARCHAR" property="courseId"/>
      12. <result column="create_time" jdbcType="TIMESTAMP" property="createTime"/>
      13. <association property="course" column="course_id" javaType="com.xiao.ha.bean.store.Catalog"
      14. select="com.xiao.ha.dao.store.CourseDao.findById"></association>
      15. </resultMap>
      16. <!--配置查询的列名公共SQL语句-->
      17. <sql id="Base_Column_List">
      18. id, name, remark , state , create_time , course_id
      19. </sql>
      20. <!--配置查询所有-->
      21. <select id="findAll" resultMap="BaseResultMap">
      22. select
      23. <include refid="Base_Column_List"/>
      24. from st_catalog
      25. </select>
      26. <!--配置根据ID查询-->
      27. <select id="findById" parameterType="java.lang.String" resultMap="BaseResultMap">
      28. select
      29. <include refid="Base_Column_List"/>
      30. from st_catalog
      31. where id = #{id,jdbcType=VARCHAR}
      32. </select>
      33. <!--配置根据id删除-->
      34. <delete id="delete" parameterType="java.lang.String">
      35. delete from st_catalog where id = #{id,jdbcType=VARCHAR}
      36. </delete>
      37. <!--配置全字段插入,当某个字段没有值时,插入null-->
      38. <insert id="save" parameterType="com.xiao.ha.bean.store.Catalog">
      39. insert into st_catalog (id, name, remark , state , create_time , course_id)
      40. values (#{id,jdbcType=VARCHAR}, #{name,jdbcType=VARCHAR}, #{remark,jdbcType=VARCHAR},
      41. #{state,jdbcType=VARCHAR} , #{createTime,jdbcType=TIMESTAMP}, #{courseId,jdbcType=VARCHAR})
      42. </insert>
      43. <!--配置全字段更新,当提供的数据为null时,数据库数据会被更新为null-->
      44. <update id="update" parameterType="com.xiao.ha.bean.store.Catalog">
      45. update st_catalog
      46. set name = #{name,jdbcType=VARCHAR},
      47. remark = #{remark,jdbcType=VARCHAR},
      48. state = #{state,jdbcType=VARCHAR},
      49. course_id = #{courseId,jdbcType=VARCHAR}
      50. where id = #{id,jdbcType=VARCHAR}
      51. </update>
      52. </mapper>
    • 编写测试类 ```java package com.xiao.ha.serevice.store.impl;

import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageInfo; import com.xiao.ha.bean.store.Catalog; import com.xiao.ha.dao.store.CatalogDao; import com.xiao.ha.factory.MapperFactory; import com.xiao.ha.serevice.store.CatalogService; import com.xiao.ha.util.TransactionUtil; import org.apache.ibatis.session.SqlSession;

import java.util.Date; import java.util.List; import java.util.UUID;

public class CatalogServiceImpl implements CatalogService { /**

  1. * 添加数据的方法
  2. * @param catalog
  3. */
  4. @Override
  5. public void save(Catalog catalog) {
  6. SqlSession sqlSession = null;
  7. try {
  8. //1.获取SqlSession
  9. sqlSession = MapperFactory.getSqlSession();
  10. //2.获取Dao
  11. CatalogDao catalogDao = MapperFactory.getMapper(sqlSession, CatalogDao.class);
  12. //id使用UUID的生成策略来获取
  13. String id = UUID.randomUUID().toString();
  14. catalog.setId(id);
  15. catalog.setCreateTime(new Date());
  16. //3.调用Dao层操作
  17. catalogDao.save(catalog);
  18. //4.提交事务
  19. TransactionUtil.commit(sqlSession);
  20. } catch (Exception e) {
  21. TransactionUtil.rollback(sqlSession);
  22. throw new RuntimeException(e);
  23. //记录日志
  24. } finally {
  25. try {
  26. TransactionUtil.close(sqlSession);
  27. } catch (Exception e) {
  28. e.printStackTrace();
  29. }
  30. }
  31. }
  32. @Override
  33. public void delete(Catalog catalog) {
  34. SqlSession sqlSession = null;
  35. try {
  36. //1.获取SqlSession
  37. sqlSession = MapperFactory.getSqlSession();
  38. //2.获取Dao
  39. CatalogDao catalogDao = MapperFactory.getMapper(sqlSession, CatalogDao.class);
  40. //3.调用Dao层操作
  41. catalogDao.delete(catalog);
  42. //4.提交事务
  43. TransactionUtil.commit(sqlSession);
  44. } catch (Exception e) {
  45. TransactionUtil.rollback(sqlSession);
  46. throw new RuntimeException(e);
  47. //记录日志
  48. } finally {
  49. try {
  50. TransactionUtil.close(sqlSession);
  51. } catch (Exception e) {
  52. e.printStackTrace();
  53. }
  54. }
  55. }
  56. @Override
  57. public void update(Catalog catalog) {
  58. SqlSession sqlSession = null;
  59. try {
  60. //1.获取SqlSession
  61. sqlSession = MapperFactory.getSqlSession();
  62. //2.获取Dao
  63. CatalogDao catalogDao = MapperFactory.getMapper(sqlSession, CatalogDao.class);
  64. //3.调用Dao层操作
  65. catalogDao.update(catalog);
  66. //4.提交事务
  67. TransactionUtil.commit(sqlSession);
  68. } catch (Exception e) {
  69. TransactionUtil.rollback(sqlSession);
  70. throw new RuntimeException(e);
  71. //记录日志
  72. } finally {
  73. try {
  74. TransactionUtil.close(sqlSession);
  75. } catch (Exception e) {
  76. e.printStackTrace();
  77. }
  78. }
  79. }
  80. @Override
  81. public Catalog findById(String id) {
  82. SqlSession sqlSession = null;
  83. try {
  84. //1.获取SqlSession
  85. sqlSession = MapperFactory.getSqlSession();
  86. //2.获取Dao
  87. CatalogDao catalogDao = MapperFactory.getMapper(sqlSession, CatalogDao.class);
  88. //3.调用Dao层操作
  89. return catalogDao.findById(id);
  90. } catch (Exception e) {
  91. throw new RuntimeException(e);
  92. //记录日志
  93. } finally {
  94. try {
  95. TransactionUtil.close(sqlSession);
  96. } catch (Exception e) {
  97. e.printStackTrace();
  98. }
  99. }
  100. }
  101. @Override
  102. public List<Catalog> findAll() {
  103. SqlSession sqlSession = null;
  104. try {
  105. //1.获取SqlSession
  106. sqlSession = MapperFactory.getSqlSession();
  107. //2.获取Dao
  108. CatalogDao catalogDao = MapperFactory.getMapper(sqlSession, CatalogDao.class);
  109. //3.调用Dao层操作
  110. return catalogDao.findAll();
  111. } catch (Exception e) {
  112. throw new RuntimeException(e);
  113. //记录日志
  114. } finally {
  115. try {
  116. TransactionUtil.close(sqlSession);
  117. } catch (Exception e) {
  118. e.printStackTrace();
  119. }
  120. }
  121. }
  122. @Override
  123. public PageInfo findAll(int page, int size) {
  124. SqlSession sqlSession = null;
  125. try {
  126. //1.获取SqlSession
  127. sqlSession = MapperFactory.getSqlSession();
  128. //2.获取Dao
  129. CatalogDao catalogDao = MapperFactory.getMapper(sqlSession, CatalogDao.class);
  130. //3.调用Dao层操作
  131. PageHelper.startPage(page, size);
  132. List<Catalog> all = catalogDao.findAll();
  133. PageInfo pageInfo = new PageInfo(all);
  134. return pageInfo;
  135. } catch (Exception e) {
  136. throw new RuntimeException(e);
  137. //记录日志
  138. } finally {
  139. try {
  140. TransactionUtil.close(sqlSession);
  141. } catch (Exception e) {
  142. e.printStackTrace();
  143. }
  144. }
  145. }

}

  1. <a name="j4aoU"></a>
  2. ### (4)万能的Map
  3. 假设我们的实体类或者数据库中的表的字段或参数比较多时,我们应该考虑使用map
  4. ```java
  5. //万能的Map
  6. int addUser(Map<String,Object>map);
  1. <!--对象中的属性可以直接取出来,传递Map的Key-->
  2. <insert id="save" parameterType="map">
  3. insert into st_catalog (id, name, remark , state , create_time , course_id)
  4. values (#{id,jdbcType=VARCHAR}, #{name,jdbcType=VARCHAR}, #{remark,jdbcType=VARCHAR},
  5. #{state,jdbcType=VARCHAR} , #{createTime,jdbcType=TIMESTAMP}, #{courseId,jdbcType=VARCHAR})
  6. </insert>