Mybatis总结

  1. 基本概念:

    1. Mybatis是一个半ORM框架,内部封装JDBC,开发时只需要关注SQL本身;
    2. 使用XML或者注解来配置和映射原生信息,将POJO映射成数据库中的记录;
    3. 具体执行过程:
      1. 通过XML文件或者注解的方式将要执行的各种statement配置起来,
      2. 通过java对象和statement中的SQL的动态参数进行映射生成最终执行的SQL语句,
      3. 最后由Mybatis框架执行SQL并将结果映射为java对象并返回
  2. mybatis**的入门案例

    1. 注意事项:
      1. 持久层接口必须和.xml文件名保持一致如:testDao 和 testDao.xml
    2. 执行流程:
    • 1、先读取xml配置文件,
    • 2、配置文件先读取数据库信息并链接,再读取对应的持久层的xml文件
    • 3、持久层xml文件读取1.持久层地址和实体类信息
    • 4、执行SQL语句
    • 5、通过代理实体类对象开始执行SQL方法,并返回对应的结果集
    • */
    1. mybatis----在 MyBatis 中,反射是用于操作 JavaBean 的实体类对象的,而不是用于操作数据库表中的列名。这是因为 MyBatis 需要将数据库中的数据以及 SQL 查询的结果映射到 JavaBean 的实体对象上,而这个过程就需要使用到反射。
      1. 实际的原理过程:

        1.invoke方法中通过key获取到mapper

        2.通过执行selectList()方法获取到数据对象

        3.数据对象通过映射数据库的列名和值到实体类中;

        4.最后将赋值的实体类添加到列表内并返回值;

        Mybatis总结_第1张图片

    public class MybatisTest {
    
        /**
         * 入门案例 核心代码
         * @param args
         */
        public static void main(String[] args)throws Exception {
            //1.读取配置文件
            InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");
            //2.创建SqlSessionFactory工厂
            SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
            SqlSessionFactory factory = builder.build(in);
            //3.使用工厂生产SqlSession对象
            SqlSession session = factory.openSession();
            //4.使用SqlSession创建Dao接口的代理对象
            UserDao userDao = session.getMapper(UserDao.class);
            //5.使用代理对象执行方法,
            List<User> users = userDao.findAll();
            for(User user : users){
                System.out.println(user);
            }
            //6.释放资源
            session.close();
            in.close();
        }
    }
    
    
  3. 自定义mybatis

Mybatis总结_第2张图片

  1. xml配置文件
    1. resultType属性:指定结果集的类型
    2. paramType属性:指定传入参数的类型
    3. #{}字符: 占位符,自动进行java类型和jdbc类型转换,防止sql注入
    4. ${}:拼接sql串,可以将paramtype传入的内容拼接在sql中且不进行jdbc类型转换
    5. session.commit();来实现事务提交
  2. mybatis好处:
    1. mybatis自动将java对象映射至sql对象;
    2. 通过statement中的resultType定义输出结果类型;
  3. Mybatis 的输出结果封装
    1. resultType 属性可以指定结果集的类型,它支持基本类型和实体类类型

    2. 实体类必须是全限定类名

    3. 实体类中的属性名称必须和查询语句中的列名保持一致,否则无法实现封装

    4. resultMap标签

      1. 建立查询的列明和实体类属性名称不一致建立对应关系
      2. 映射对象中包括 pojo 和 list 实现一对一查询和一对多查询
      <--
          type 属性:指定实体类的全限定类名
          id 属性:给定一个唯一标识,是给查询 select 标签引用用的。
      -->
          
              
              
              
              
              
          
      id 标签:用于指定主键字段
      result 标签:用于指定非主键字段
      column 属性:用于指定数据库列名
      property 属性:用于指定实体类属性名
      
    5. mapper映射器

      
      //使用相对于类路径的资源,实现读取xml文件的方式
      如:
      
      使用 mapper 接口类路径 实现注解方式
      如:
      注意:此种方法要求 mapper 接口名称和 mapper 映射文件名称相同,且放在同一个目录中
      
    6. Mybatis 连接池与事务深入

      1. 数据源分为三类

        我们的数据源配置就是在 SqlMapConfig.xml 文件中,具体配置如下:
        
            
                
                
                
                
            
        MyBatis 在初始化时,根据的 type 属性来创建相应类型的的数据源 DataSource,即:
        type=”POOLED”:MyBatis 会创建 PooledDataSource 实例
        type=”UNPOOLED” : MyBatis 会创建 UnpooledDataSource 实例
        type=”JNDI”:MyBatis 会从 JNDI 服务上查找 DataSource 实例,然后返回使
        
      2. Mybatis 的事务控制

        1. setAutoCommit()进行事务控制

          为什么 CUD 过程中必须使用 sqlSession.commit()提交事务?
              主要原因就是在连接池中取出的连接,都会将调用 connection.setAutoCommit(false)方法;
              就必须使用 sqlSession.commit()方法,相当于使用了 JDBC 中的 connection.commit()方法实现事务提交;
          
          private InputStream in;
              private SqlSession sqlSession;
              private IUserDao userDao;
          
              @Before//用于在测试方法执行之前执行
              public void init()throws Exception{
                  //1.读取配置文件,生成字节输入流
                  in = Resources.getResourceAsStream("SqlMapConfig.xml");
                  //2.获取SqlSessionFactory
                  SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
                  //3.获取SqlSession对象
                  sqlSession = factory.openSession(true);
                  //4.获取dao的代理对象
                  userDao = sqlSession.getMapper(IUserDao.class);
              }
          
              @After//用于在测试方法执行之后执行
              public void destroy()throws Exception{
                  //提交事务
                 // sqlSession.commit();
                  //6.释放资源
                  sqlSession.close();
                  in.close();
              }
          
          
      3. 动态sql语句

        1. 动态 SQL 之标签
    7. 多表查询

      1. 一对一
        1. 方法一
          1. 定义账户实体类
          2. 定义AccountUser继承账户实体类并设置要查询的字段
          3. 定义账户持久层,返回类型为AccountUser
        2. 方法二
          1. Account 类中加入 User 类的对象作为 Account 类的一个属性
          2. 返回值类型是Account
          3. association建立xml关系association下指定从表User的实体属性值
      2. 一对多
        1. 方法一
          1. User 类中加入 Account 类的对象作为 User 类的一个属性
          2. 返回值类型是User
          3. collection:是用于建立一对多中集合属性的对应关系
            1. ofType 用于指定集合元素的数据类型
            2. property 关联查询的结果集存储在 User 对象的上哪个属性
            3. select 属性:用于指定查询 account 列表的 sql 语句,所以填写的是该 sql 映射的 id
            4. column 属性:用于指定 select 属性的 sql 语句的参数来源
    8. Mybatis 延迟加载策略

      1. 就是在需要用到数据时才进行加载,不需要用到数据时就不加载数据。延迟加载也称懒加载

      2. association and collection具备延迟加载的功能

        我们需要在 Mybatis 的配置文件 SqlMapConfig.xml 文件中添加延迟加载的配置。
        
        
        
        
        
        
    9. mybatis缓存:缓存策略减少数据库查询次数,从而提高性能

      1. 一级缓存:SqlSession缓存,只要SqlSession没有close 或者flush 就一直存在

        1. 一级缓存在dao.xml中的配置信息

        Mybatis总结_第3张图片

        1. 具体测试的结果:两次查询出来的结果对象相等则代表使用了缓存策略

        2. 缓存清空:sqlsession.clearCache,清空缓存后两次结果对象不相等

              
              
          
              @Test
              public void testFirstCache(){
                  User user1 = userDao.findById(41);
                  System.out.println("第一次查询用户"+ user1);
          
                  User user2 = userDao.findById(41);
                  System.out.println("第二次查询用户"+user2);
          
                  System.out.println("两次查询结果对比,如果为true则代表没有创建新的对象使用缓存数据");
                  System.out.println(user1 == user2);
              }
          
          

        Mybatis总结_第4张图片

      2. 二级缓存:二级缓存是 mapper 映射级别的缓存,多个 SqlSession 去操作同一个 Mapper 映射的 sql 语句,多个SqlSession 可以共用二级缓存,二级缓存是跨 SqlSession 的。

        1. 开启二级缓存

          
          
          
          
          因为 cacheEnabled 的取值默认就为 true,所以这一步可以省略不配置。为 true 代表开启二级缓存;为
          false 代表不开启二级缓存
          
        2. 配置相关的 Mapper 映射文件

          标签表示当前这个 mapper 映射将使用二级缓存,区分的标准就看 mapper 的 namespace 值。
          
          
          
              
              
          
          
          将 UserDao.xml 映射文件中的