栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

【狂神说】mybatis学习笔记(全)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【狂神说】mybatis学习笔记(全)

zip格式源码下载
PDF格式
https://wwm.lanzouw.com/it2lqydg5ra
密码:1hb3

文章目录
  • MyBatis
  • 1、简介
    • 1.1、什么是Mybatis
      • 如何获得Mybatis?
    • 1.2、持久化
      • 为什么需要持久化?
    • 1.3、持久层
    • 1.4、为什么需要mybatis?
  • 2、第一个Mybatis程序
    • 2.1、搭建环境
      • 1.搭建数据库
      • 2.新建项目
    • 2.2、创建一个模块
      • 编写mybatis的核心配置文件
      • 编写mybatis工具类
    • 2.3、编写代码
      • 实体类
      • Dao接口
      • 接口实现类
    • 2.4、测试
      • 注意点:
      • junit测试
    • 遇到的问题
      • 配置文件没有注册
      • 方法名不对,返回类型不对
      • 字符错误
      • maven导出资源问题
    • 思路
      • 准备工作
      • 代码实现
    • mybatis三个核心接口
      • SqlSessionFactoryBuilder
      • SqlSessionFactory
      • SqlSession
  • 3、CRUD
    • 1、namespace
    • 2、select
    • 3、insert
    • 4、updata
    • 5、delete
    • 注意
    • 6、分析错误
    • 读错方式
    • 7、万能的Map
      • 添加用户
      • 查看用户
    • 8、模糊查询
      • Java代码执行的时候,传递通配符% %
      • 在sql拼接中使用通配符
  • 4、配置解析
    • 1、核心配置文件
    • 2、环境配置(environments)重要
    • 3、属性(properties)
    • 4、类型别名(typeAliases)
    • 5、 设置 (Settings)
    • 6、其他配置
    • 7、映射器 (mapper)
    • 练习
    • 8. 作用域和生命周期
  • 5、解决属性名和字段名不一致的问题
    • 1. 问题
    • 2. ==resultMap==(重点、难点)
  • 6、日志
    • 6.1 日志工厂
    • 错误
    • 6.2 Log4j
      • 配置
      • Log4j简单使用
  • 7、分页
    • 7.1 使用Limit分页
    • 7.2 RowBounds分页
    • 7.3 分页插件
  • 8、使用注解开发(重点)
    • 8.1 面向接口开发
    • 8.2 使用注解开发
      • 动态代理
    • MyBatis详细执行流程(重要)
    • 8.3 注解CURD
      • 自动提交事务
      • CURD
      • 注意
      • 关于@Param( )注解
      • #{} 和 ${} 区别
  • 9、Lombok
    • 使用步骤:
    • 说明:
  • 10、多对一处理(难点)
    • 1.数据库设计
    • 测试环境搭建
    • 2. 按照查询嵌套处理
    • 3.按照结果嵌套处理
    • 回顾Mysql多对一查询方式
  • 11、一对多处理(难点)
    • 1.环境搭建
    • 2. 按照结果嵌套嵌套处理
    • 小结
  • 12、动态SQL(重点)
    • 搭建环境
    • IF(重点)
    • choose (when, otherwise)
    • trim、where、set
      • where(重点)
      • set(重点)
    • SQL片段
      • 注意事项:
    • Foreach
      • 案例
    • 总结
  • 13、缓存(了解)
    • 13.1 简介
    • 13.2 MyBatis缓存
    • 13.3 一级缓存
      • 测试
      • 缓存失效的情况:
      • 小结
    • 13.4 二级缓存
      • 步骤:
      • 代码实现
      • 小结:
    • 13.5 缓存原理
      • 流程图
      • 代码实现
      • 代码讲解
      • 总结
    • 13.6 自定义缓存-ehcache

MyBatis


作用:简化了JDBC的操作

环境:

  • JDK:1.8
  • Mysql:8.0
  • maven:3.8.1
  • IDE:开发工具

回顾:(贯串整个Mybatis的学习)

  • JDBC
  • Mysql
  • java基础
    • 封装继承的思想,
    • 掌握:看到了一个东西能不能把他封装能一个工具类
  • Maven
    • 会架构maven
    • 知道父子模块
  • Junit
    • 单元测试

SSM框架:有配置文件的。

最好的学习方式:看官网文档。

mybatis官方文档:https://mybatis.org/mybatis-3/index.html

1、简介 1.1、什么是Mybatis
  • MyBatis 是一款优秀的**持久层框架**

  • 它支持自定义 SQL、存储过程以及高级映射。(方便写sql)

  • MyBatis 免除了几乎所有的 JDBC 代码以及设置参数获取结果集的工作。(核心)

  • MyBatis 可以通过简单的XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。(配置相关的)

  • MyBatis 本是apache的一个开源项目iBatis,2010年这个项目由apache software foundation 迁移到了[google code](https://baike.baidu.com/item/google code/2346604),并且改名为MyBatis 。

  • 2013年11月迁移到Github。

  • iBATIS提供的持久层框架包括SQL Maps和Data Access Objects(DAOs)

    • DAO:数据 持久层 对象
如何获得Mybatis?
  • maven仓库:https://mvnrepository.com/search?q=mybatis

    org.mybatis
    mybatis
    3.5.6

Github:https://github.com/mybatis/mybatis-3/tags



  • 中文文档:https://mybatis.org/mybatis-3/zh/index.html

作用

概念

为什么需要mybatis

1.2、持久化

持久化是一个,动作。

数据持久化

  • 持久化就是将程序的数据在持久状态瞬时状态转化的过程
    • 持久状态:放在数据库中(只有数据库不删库,一直都在)
    • 瞬时状态:内存里的东西,持久化到数据里边
  • 内存的特性:断电即失
    • 正常的运行数据都在内存中,不如不持久化,内存出意外数据就丢了
  • 持久化方式:数据库(jdbc)、io文件持久化。
    • io特别浪费资源,所有数据库诞生了
  • 生活中持久化方式:冷藏、罐头。
为什么需要持久化?
  • 内存的特性:断电即失

  • 有一些对象,不能让他对掉。如:支付宝余额

  • 内存贵

1.3、持久层

持久层是一个概念。

Dao层、service层(业务)、Controller层……(每个层有具体的业务)

  • Dao层:完成持久化工作的代码块
  • service层:业务操作,调Dao层,等待Controller层的调用
  • Controller层:接收用户请求,转发给业务层去做
  • 层:界限十分明显
1.4、为什么需要mybatis?
  • 核心作用:帮助程序员将数据存入到数据库中
  • 方便
  • 传统的JDBC代码太复杂了。‘
  • 简化。
  • 框架
  • 自动化操作了
  • 不用mybatis也可以,它只是一个框架。
  • 用mybatis更容易上手。技术没有高低之分,只有使用技术的人有高低之分

什么是框架?

  • 约定好了,只需要在里边填写相应的东西
  • 比如:填写表格

优点

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

最重要的一点:使用的人多!

Spring SpringMVC 同样是:使用的人多

SpringBoot:更简单了

2、第一个Mybatis程序

思路:

  1. 搭建环境
  2. 导入mybatis
  3. 编写代码
  4. 测试
2.1、搭建环境 1.搭建数据库

sql要求很高

-- 创建数据库
create database `mybatis`

use `mybatis`

-- 创建表

create table `user`(
	`id` varchar(20) not null primary key, -- 主键
	`name` varchar(30) default null,
	`pwd` varchar(30) default null
	
)engine = innodb default CHARSET = utf8;  -- 引擎

-- engine = innodb 底层 面试题

-- 插入数据
insert into `user`(`id`,`name`,`pwd`) values
(1,'张三','123'),
(2,'李四','123123'),
(3,'王五','456')

2.新建项目
  1. 普通的maven项目

  2. 删除src目录,可以当做父工程来用

  3. 导入maven依赖

    1.     
              
              
                  mysql
                  mysql-connector-java
                  8.0.24
              
              
              
              
                  org.mybatis
                  mybatis
                  3.5.6
              
              
              
                  junit
                  junit
                  4.12
                  test
              
          
      
2.2、创建一个模块 编写mybatis的核心配置文件
  • resources文件下mybatis-config.xml

  • 功能:连接数据库

  • 
    
    
    
        
        
            
                
                
                
                    
                    
                    
                    
                    
                
            
        
        
        
            
        
    
    
编写mybatis工具类
  • // SqlSessionFactory (工厂模式,生成产品的) ---> 生成的产品:sqlSession
    public class MybatisUtils {
    
        private static SqlSessionFactory sqlSessionFactory;
    
        static {//初始就加载
            try {
                
                String resource = "mybatis-config.xml";
                InputStream inputStream = Resources.getResourceAsStream(resource);
                //通过 Builder 把流加载进来
                sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
        
        public static SqlSession getSqlSession(){
            return sqlSessionFactory.openSession();
        }
    
    }
    
2.3、编写代码 实体类
//实体类
public class User {
    private int id;
    private String name;
    private String pwd;

    public User() {
    }

    public User(int id, String name, String pwd) {
        this.id = id;
        this.name = name;
        this.pwd = pwd;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPwd() {
        return pwd;
    }

    public void setPwd(String pwd) {
        this.pwd = pwd;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + ''' +
                ", pwd='" + pwd + ''' +
                '}';
    }
}
Dao接口

操作数据库对象的实体类

Dao 等价于:mapper

  //Dao 等价于:mapper(制图员)
  public interface UserDao {
      List getUserList();
  
  }
接口实现类

操作数据库的实现类

由原来的UserDaoImpl转变为一个Mapper配置文件

  
  
  
  
  
      
      
  select * from user where id = #{id}

  • 测试(增删改需要提交事务)

    1. @Test
      public void getUserById(){
        //获取执行sql的对象
        SqlSession sqlSession = MybatisUtils.getSqlSession();
      
        //获得接口
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        User user = mapper.getUserById(1);
        System.out.println(user);
        sqlSession.close();
      }
      
  • 3、insert
    //插入一个用户
    int addUser(User user);
    
    
      insert into user (id,name ,pwd)
      values (#{id},#{name},#{pwd});
    
    
    @Test
    //增删改需要提交事务
    public void addUser(){
      //获取执行sql的对象
      SqlSession sqlSession = MybatisUtils.getSqlSession();
      //获得接口
      UserMapper mapper = sqlSession.getMapper(UserMapper.class);
      //增加用户
      int user = mapper.addUser(new User(4, "赵六", "123"));
      if (user > 0){
        System.out.println("插入成功!");
      }
      //提交事务
      sqlSession.commit();
    
      sqlSession.close();
    }
    
    4、updata
    //修改一个用户
    int upDataUser(User user);
    
    
      update user
      set id = #{id}, name = #{name}, pwd = #{pwd}
      where id = #{id};
    
    
    //修改一个用户
    @Test
    public void upDataUser(){
      //获得执行sql的对象
      SqlSession sqlSession = MybatisUtils.getSqlSession();
      //得到接口
      UserMapper mapper = sqlSession.getMapper(UserMapper.class);
      mapper.upDataUser(new User(3,"小明","123"));
      sqlSession.commit();
      sqlSession.close();
    }
    
    5、delete
    //删除一个用户
    int deleteUser(int id);
    
    
      delete
      from user
      where id = #{id};
    
    
    //删除一个用户
    @Test
    public void deleteUser(){
      SqlSession sqlSession = MybatisUtils.getSqlSession();
      UserMapper mapper = sqlSession.getMapper(UserMapper.class);
      mapper.deleteUser(4);
      sqlSession.commit();
      sqlSession.close();
    }
    
    注意
    • 增删改,需要提交事务
    6、分析错误
    • 标签不要匹配错误
    • resource 绑定Mapper需要使用路径:/分开
    • 程序配置文件必须符合规范
    • 空指针异常:NullPointerException,没有注册到资源
      • 不能这样定义
    • 输出xml文件存在中文乱码问题!
    • maven资源没有导出问题
    读错方式

    从下往上读,如:

    7、万能的Map

    假设,我们的实体类,或者数据库中的表,字段或者参数过多,我们应当考虑使用Map!

    • Map传递参数,直接在sql中取出key即可!

      • parameterType="map"
        
    • 对象传递参数,直接在sql中取对象的属性即可!

      • parameterType="com.yin.pojo.User" //(对象)
        
    • 只有一个基本类型参数的情况下,可以直接在sql中取到!

      • 可以不写,基本参数类型
    • 多个参数用Map,或者注解!

    添加用户
    //万能的map 好处:不需要知道数据库中有什么,只需要查对应的字段
    int addUser2(Map map);
    
    
      insert into user (id, name, pwd)
      values (#{userid}, #{userName}, #{userWord});
    
    
    //map
    @Test
    public void addUser2(){
      SqlSession sqlSession = MybatisUtils.getSqlSession();
      UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    
      Map map = new HashMap<>();
      map.put("userid",6);
      map.put("userName","小花");
      map.put("userWord",123);
    
      mapper.addUser2(map);
      //提交事务
      sqlSession.commit();
      sqlSession.close();
    }
    
    查看用户
    User getUserById2(Map map);
    
    
      select * from mybatis.user where name like #{value}
    
    
    @Test
    public void getUserLike(){
      SqlSession sqlSession = MybatisUtils.getSqlSession();
      UserMapper mapper = sqlSession.getMapper(UserMapper.class);
      List userLike = mapper.getUserLike("%小%");
      for (User user : userLike) {
        System.out.println(user);
      }
      sqlSession.close();
    }
    
    //输出
    User{id=3, name='小明', pwd='123'}
    User{id=6, name='小花', pwd='123'}
    
    
    在sql拼接中使用通配符

    不安全,会出现sql注入

    
      select * from mybatis.user where name like  "%"#{value}"%"
    
    
    List userLike = mapper.getUserLike("小");
    

    防止sql注入问题的方法

    • 在这里写死,让用户能传递的只有一个稳定的值

    • 
        select * from user where id = #{id}
      
      
      • resultMap 元素是 MyBatis 中最重要最强大的元素。

      • ResultMap 的设计思想是,对简单的语句做到零配置,对于复杂一点的语句,只需要描述语句之间的关系就行了。

      • ResultMap 的优秀之处——你完全可以不用显式地配置它们。

      • 如果这个世界总是这么简单就好了。

      一对多,多对一

      6、日志 6.1 日志工厂

      如果一个数据库操作,出现了异常,我们需要排错,日志就是最好的助手!

      • 曾经:sout、debug

      • 现在:日志工厂

      • SLF4J

      • LOG4J 【掌握】

      • LOG4J2

      • JDK_LOGGING

      • COMMONS_LOGGING

      • STDOUT_LOGGING 【掌握】

      • NO_LOGGING

      在MyBatis中具体使用哪一个日志实现,在设置中设定

      STDOUT_LOGGING标准日志输出

      在mybatis核心配置文件中,配置我们的日志!

      手动配置日志

      顺序不能出错


      name和value不能有错误

      
        
      
      

      输出结果

      Opening JDBC Connection  // 打开jdbc连接
      Created connection 422330142. // 创建connection连接对象,本质还是jdbc
      Setting autocommit to false on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@192c3f1e] // 设置自动提交的事务为 false
      ==>  Preparing: select * from user where id = ? // 预编译的sql
      ==> Parameters: 1(Integer) // sql传递的参数
      <==    Columns: id, name, pwd // 查询的列
      <==        Row: 1, 张三, 123 // 查询的记录
      <==      Total: 1 // 总共多少记录
      User{id=1, name='张三', password='123'} // 结果
      Resetting autocommit to true on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@192c3f1e] // 设置自动提交事务为 true
      Closing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@192c3f1e] // 关闭JDBC连接
      Returned connection 422330142 to pool. // 把connection返回池子
      
      错误

      ClassNotFoundException

      • 包名/类名,写错了

      • 没有导包

      6.2 Log4j

      什么是Log4j?

      Log4j是Apache的一个开源项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台、文件、GUI组件;

      我们也可以控制每一条日志的输出格式;

      通过定义每一条日志信息的级别,我们能够更加细致地控制日志的生成过程;

      通过一个配置文件来灵活地进行配置,而不需要修改应用的代码。

      配置
      1. 先导入log4j的包

        
          log4j
          log4j
          1.2.17
        
        
      2. 通过一个配置文件来灵活地进行配置

        log4j.properties

        #将等级为DEBUG的日志信息输出到console和file这两个目的地,console和file的定义在下面的代码
        # 输出日志级别
        log4j.rootLogger=DEBUG,console,file
        ​
        #控制台输出的相关设置
        log4j.appender.console = org.apache.log4j.ConsoleAppender
        log4j.appender.console.Target = System.out
        log4j.appender.console.Threshold=DEBUG
        log4j.appender.console.layout = org.apache.log4j.PatternLayout
        log4j.appender.console.layout.ConversionPattern=[%c]-%m%n
        #文件输出的相关设置
        log4j.appender.file = org.apache.log4j.RollingFileAppender
        log4j.appender.file.File=./log/rzp.log
        log4j.appender.file.MaxFileSize=10mb
        log4j.appender.file.Threshold=DEBUG
        log4j.appender.file.layout=org.apache.log4j.PatternLayout
        log4j.appender.file.layout.ConversionPattern=[%p][%d{yy-MM-dd}][%c]%m%n
        #日志输出级别
        log4j.logger.org.mybatis=DEBUG
        log4j.logger.java.sql=DEBUG
        log4j.logger.java.sql.Statement=DEBUG
        log4j.logger.java.sql.ResultSet=DEBUG
        log4j.logger.java.sq1.PreparedStatement=DEBUG
        
      3. 配置settings为log4j实现

        
          
        
        
      4. 测试运行

        [org.apache.ibatis.logging.LogFactory]-Logging initialized using 'class org.apache.ibatis.logging.log4j.Log4jImpl' adapter.
        [org.apache.ibatis.logging.LogFactory]-Logging initialized using 'class org.apache.ibatis.logging.log4j.Log4jImpl' adapter.
        [org.apache.ibatis.io.VFS]-Class not found: org.jboss.vfs.VFS
        [org.apache.ibatis.io.JBoss6VFS]-JBoss 6 VFS API is not available in this environment.
        [org.apache.ibatis.io.VFS]-Class not found: org.jboss.vfs.VirtualFile
        [org.apache.ibatis.io.VFS]-VFS implementation org.apache.ibatis.io.JBoss6VFS is not valid in this environment.
        [org.apache.ibatis.io.VFS]-Using VFS adapter org.apache.ibatis.io.DefaultVFS
        [org.apache.ibatis.io.DefaultVFS]-Find JAR URL: file:/D:/IDEA%e6%95%b0%e6%8d%ae/mybatis-study/mybatis-04/target/classes/com/yin/pojo
        [org.apache.ibatis.io.DefaultVFS]-Not a JAR: file:/D:/IDEA%e6%95%b0%e6%8d%ae/mybatis-study/mybatis-04/target/classes/com/yin/pojo
        [org.apache.ibatis.io.DefaultVFS]-Reader entry: User.class
        [org.apache.ibatis.io.DefaultVFS]-Listing file:/D:/IDEA%e6%95%b0%e6%8d%ae/mybatis-study/mybatis-04/target/classes/com/yin/pojo
        [org.apache.ibatis.io.DefaultVFS]-Find JAR URL: file:/D:/IDEA%e6%95%b0%e6%8d%ae/mybatis-study/mybatis-04/target/classes/com/yin/pojo/User.class
        [org.apache.ibatis.io.DefaultVFS]-Not a JAR: file:/D:/IDEA%e6%95%b0%e6%8d%ae/mybatis-study/mybatis-04/target/classes/com/yin/pojo/User.class
        [org.apache.ibatis.io.DefaultVFS]-Reader entry: 漱壕   4 <
        [org.apache.ibatis.io.ResolverUtil]-Checking to see if class com.yin.pojo.User matches criteria [is assignable to Object]
        [org.apache.ibatis.datasource.pooled.PooledDataSource]-PooledDataSource forcefully closed/removed all connections.
        [org.apache.ibatis.datasource.pooled.PooledDataSource]-PooledDataSource forcefully closed/removed all connections.
        [org.apache.ibatis.datasource.pooled.PooledDataSource]-PooledDataSource forcefully closed/removed all connections.
        [org.apache.ibatis.datasource.pooled.PooledDataSource]-PooledDataSource forcefully closed/removed all connections.
        [org.apache.ibatis.transaction.jdbc.JdbcTransaction]-Opening JDBC Connection
        [org.apache.ibatis.datasource.pooled.PooledDataSource]-Created connection 255334292.
        [org.apache.ibatis.transaction.jdbc.JdbcTransaction]-Setting autocommit to false on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@f381794]
        [com.yin.dao.UserMapper.getUserById]-==>  Preparing: select * from user where id = ?
        [com.yin.dao.UserMapper.getUserById]-==> Parameters: 1(Integer)
        [com.yin.dao.UserMapper.getUserById]-<==      Total: 1
        User{id=1, name='张三', password='123'}
        [org.apache.ibatis.transaction.jdbc.JdbcTransaction]-Resetting autocommit to true on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@f381794]
        [org.apache.ibatis.transaction.jdbc.JdbcTransaction]-Closing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@f381794]
        [org.apache.ibatis.datasource.pooled.PooledDataSource]-Returned connection 255334292 to pool.
        
        Process finished with exit code 0
        
      Log4j简单使用
      1. 在要使用Log4j的类中,导入包

         import org.apache.log4j.Logger
        
      2. 日志对象,参数为当前类的class对象

        static Logger logger = Logger.getLogger(UserDaoTest.class);
        
      3. 日志级别

         @Test
         public void testLog4j(){
           logger.info("info:进入了testLog4j"); //info:信息
           logger.debug("debug:进入了testLog4j");
           logger.error("error:进入了testLog4j");
         }
         =================================================
         [com.yin.dao.UserDaoTest]-info:进入了testLog4j
         [com.yin.dao.UserDaoTest]-debug:进入了testLog4j
         [com.yin.dao.UserDaoTest]-error:进入了testLog4j
      

      7、分页

      思考:为什么分页?

      • 减少数据的处理量
      7.1 使用Limit分页

      语法

      SELECt * from user limit startIndex,pageSize 
      SELECt * from user limit 3  #[0,3]
      -- startIndex 当前页码
      -- pageSize 页面大小
      

      使用MyBatis实现分页,核心SQL (推荐使用sql层面做分页)

      1. 接口
         //分页
         List getUserByLimit(Map map);
      
      1. Mapper.xml
         
           
           
           
           
         
         
         
         
           select * from user limit #{startIndex}, #{pageSize}
         
      
      1. 测试
         //分页
         @Test
         public void getUserByLimit(){
           SqlSession sqlSession = MybatisUtils.getSqlSession();
           UserMapper mapper = sqlSession.getMapper(UserMapper.class);
           Map map = new HashMap();
           map.put("startIndex",1);
           map.put("pageSize",2);
           List list = mapper.getUserByLimit(map);
           for (User user : list) {
             System.out.println(user);
           }
           sqlSession.close();
         }
         
         =================
         User{id=2, name='李四', password='123123'}
         User{id=3, name='小明', password='123'}
      
      7.2 RowBounds分页

      不再使用SQL实现分页

      1. 接口
         //分页2:RowBounds
         List getUserByRowBounds();
      
      1. Mapper.xml
         
         
        select *
        from student
      
      
      
        
        
        
        
        
        
      
      
          
      
        select s.id sid, s.name sname, t.name tname
        from student s,teacher t
        where s.tid = t.id;
      
      
        
        
        
        
        
          
        
      
      
      @Test
      public void testStudent2(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
        List studentList = mapper.getStudent2();
        for (Student student1 : studentList) {
          System.out.println(student1);
        }
        sqlSession.close();
      }
      
      回顾Mysql多对一查询方式
      • 子查询 (按照查询嵌套)

      • 联表查询 (按照结果嵌套)

        • select s.id, s.name, t.name
          from student s,teacher t
          where s.tid = t.id;
          
      11、一对多处理(难点)

      一个老师多个学生;

      对于老师而言,就是一对多的关系;

      1.环境搭建
      1. 导入lombok依赖
      2. 导入配置文件
      3. 导入java下的包

      实体类

      @Data
      public class Student {
          private int id;
          private String name;
          private int tid;
      }
      
      @Data
      public class Teacher {
          private int id;
          private String name;
      
          //一个老师拥有多个学生 ,老师下面放学生
          private List student;
      }
      
      2. 按照结果嵌套嵌套处理
      //获取指定老师下的所有学生及老师的信息
      Teacher getTeacher( @Param("tid") int id);
      
      
        select s.id sid, s.name sname, t.name tname, t.id tid
        from student s,teacher t
        where s.tid = t.id and t.id = #{tid}
      
      
        
        
        
        
          
          
          
        
      
      
      @Test
      public void getTeacher(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        TeacherMapper mapper = sqlSession.getMapper(TeacherMapper.class);
        Teacher teacher = mapper.getTeacher(1);
        System.out.println(teacher);
        
        sqlSession.close();
      }
      
      小结
      1. 关联 - association 【多对一】

      2. 集合 - collection 【一对多】

      3. javaType & ofType

        1. JavaType用来:指定实体类中属性的类型

        2. ofType用来:指定集合映射到List或者集合中的pojo类型,泛型中的约束类型

      注意点:

      • 保证SQL的可读性,尽量保证通俗易懂

      • 注意一对多和多对一,属性名和字段的问题

      • 如果问题不好排查错误,可以使用日志,建议使用Log4j

      • 慢SQL 1s 1000s

      面试高频

      • Mysql引擎

        • 这两个引擎的区别
      • InnoDB底层原理

        • 为什么使用InnoDB
      • 索引(解决慢sql问题 1s 1000s)

        • 索引的结构
        • 索引有哪些
        • 索引的分类
        • 如何去操作
      • 索引优化

        • 什么优化索引
      12、动态SQL(重点)

      什么是动态SQL:动态SQL就是根据不同的条件生成不同的SQL语句

      所谓的动态SQL,本质上还是SQL语句,只是我们可以在SQL层面,去执行一个逻辑代码

      动态 SQL 是 MyBatis 的强大特性之一。如果你使用过 JDBC 或其它类似的框架,你应该能理解根据不同条件拼接 SQL 语句有多痛苦,例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号。利用动态 SQL,可以彻底摆脱这种痛苦。

      如果你之前用过 JSTL 或任何基于类 XML 语言的文本处理器,你对动态 SQL 元素可能会感觉似曾相识。在 MyBatis 之前的版本中,需要花时间了解大量的元素。借助功能强大的基于 OGNL 的表达式,MyBatis 3 替换了之前的大部分元素,大大精简了元素种类,现在要学习的元素种类比原来的一半还要少。

      • if(重点)
      • choose (when, otherwise)
      • trim (where, set)
      • foreach
      搭建环境

      数据库

      CREATE TABLE `mybatis`.`blog`  (
        `id` int(10) NOT NULL AUTO_INCREMENT COMMENT '博客id',
        `title` varchar(30) NOT NULL COMMENT '博客标题',
        `author` varchar(30) NOT NULL COMMENT '博客作者',
        `create_time` datetime(0) NOT NULL COMMENT '创建时间',
        `views` int(30) NOT NULL COMMENT '浏览量',
        PRIMARY KEY (`id`)
      )
      

      创建一个基础工程

      1. 导包

      2. 编写配置文件

      3. 编写实体类

        @Data
        public class Blog {
            private int id;
            private String title;
            private String author;
        
            private Date createTime;// 属性名和字段名不一致
            private int views;
        }
        
      4. 编写实体类对应Mapper接口和Mapper.xml文件

      IF(重点)

      需求:根据作者名字和博客名字来查询博客!如果作者名字为空,那么只根据博客名字查询,反之,则根据作者名来查询

      编写接口类

      //查询博客
      List queryBlogIF(Map map);
      

      编写SQL语句

      
        insert into blog (id, title, author, create_time, views)
        values (#{id}, #{title}, #{author}, #{createTime}, #{views});
      
      
      
        select *
        from blog
        
          
            and title = #{title}
          
          
            and author = #{author}
          
        
      
      
      
      @Test
      public void queryBlog(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
        HashMap map = new HashMap();
        map.put("title","java");
        map.put("author","狂神说");
      
        List blogs = mapper.queryBlogIF(map);
        for (Blog blog : blogs) {
          System.out.println(blog);
        }
      
        sqlSession.close();
      }
      

      这个“where”标签会知道如果它包含的标签中有返回值的话,它就插入一个‘where’。

      此外,如果标签返回的内容是以AND 或OR 开头的,则它会剔除掉。【这是我们使用的最多的案例】

      set(重点)

      同理,上面的对于查询 SQL 语句包含 where 关键字,如果在进行更新操作的时候,含有 set 关键词,我们怎么处理呢?

      set 元素会动态地在行首插入 SET 关键字,并会删掉额外的逗号(这些逗号是在使用条件语句给列赋值时引入的)。

      编写接口方法

      //更新博客
      int updateBlog(Map map);
      

      xml

      
        update blog
        
          
            title = #{title},
          
      
          
            author = #{author},
          
        
        where id = #{id}
      
      

      测试

      @Test
      public void updateBlog(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
        HashMap map = new HashMap();
        //        map.put("title","java2");
        map.put("author","狂神说4");
        map.put("id",1);
        //        map.put("views",9999);
        mapper.updateBlog(map);
        sqlSession.close();
      }
      ===================
        ==>  Preparing: update blog SET author = ? where id = ?
          ==> Parameters: 狂神说4(String), 1(Integer)
            <==    Updates: 1
      

      逻辑:

      • if:判断
      • where:保证sql尽量不出问题
      • set:保证sql尽量不出问题
      • choose
      • when
      SQL片段

      有的时候,我们可能会将一些功能的部分抽取出来,方便服用!

      1. 使用SQL标签抽取公共部分可

        
          
            and title = #{title}
          
          
            and author = #{author}
          
        
        
      2. 在需要使用的地方使用Include标签引用即可