• 5.Mybatis 基础知识


    Mybatis 基础知识

    知识点一 : 映射文件 属性释义

    属性说明
    id对应namespace中的方法名
    resultTypeSql语句执行的返回值
    parameterType参数类型

    注意点1 : 映射文件下的 namespace 的包名要和 mapper接口 中的包名一致.

    在这里插入图片描述
    图片/Mybatis基础知识1.png

      
      

    知识点二 : 映射文件 CRUD的使用

    1.查询语句 select


    • ① 编写 mapper 接口

      // 根据ID查询用户
      User getUserById(int id);
      
      • 1
      • 2
    • ② 编写 映射文件 SQL语句

      <select id="getUserById" parameterType="int" resultType="com.whiteCat.pojo.User">
      	select * from mybatis.user where id = #{id}
      select>
      
      • 1
      • 2
      • 3
    • ③ 编写 测试文件

      @Test
      public void getUserById(){
          SqlSession sqlSession = MybatisUtils.getSqlSession();
          UserMapper mapper = sqlSession.getMapper(UserMapper.class);
      
          User user = mapper.getUserById(1);
          System.out.println(user);
      	
      	sqlSession.commit();
          sqlSession.close();
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11

      
      

    2.插入语句 insert


    • ① 编写 mapper 接口

      // 插入一个用户
      int addUser(User user);
      
      • 1
      • 2
    • ② 编写 映射文件 SQL语句

      <insert id="addUser" parameterType="com.whiteCat.pojo.User">
          insert into mybatis.user (id,name,pwd) values (#{id},#{name},#{pwd});
      insert>
      
      • 1
      • 2
      • 3
    • ③ 编写 测试文件

      @Test
      public void addUser(){
          SqlSession sqlSession = MybatisUtils.getSqlSession();
          UserMapper mapper = sqlSession.getMapper(UserMapper.class);
      
      
          int res = mapper.addUser(new User(4,"赵六","123333"));
          if (res >0){
              System.out.println("插入成功");
          }
          // 提交事务
          sqlSession.commit();
          sqlSession.close();
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14

      
      

    3.插入语句 update


    • ① 编写 mapper 接口

      // 修改用户
      int updateUser(User user);
      
      • 1
      • 2
    • ② 编写 映射文件 SQL语句

      <update id="updateUser" parameterType="com.whiteCat.pojo.User">
      	update mybatis.user set name=#{name},pwd=#{pwd} where id = #{id};
      update>
      
      • 1
      • 2
      • 3
    • ③ 编写 测试文件

      @Test
      public void updateUser(){
          SqlSession sqlSession = MybatisUtils.getSqlSession();
          UserMapper mapper = sqlSession.getMapper(UserMapper.class);
      
      
          int res = mapper.updateUser(new User(4,"白猫","000000"));
          if (res >0){
              System.out.println("修改成功");
          }
          // 提交事务
          sqlSession.commit();
          sqlSession.close();
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14

      
      

    4.删除语句 delete


    • ① 编写 mapper 接口

      // 删除一个用户
      int deleteUser(int id);
      
      • 1
      • 2
    • ② 编写 映射文件 SQL语句

      <delete id="deleteUser" parameterType="int">
          delete from mybatis.user where id = #{id};
      delete>
      
      • 1
      • 2
      • 3
    • ③ 编写 测试文件

      @Test
      public void deleteUser(){
          SqlSession sqlSession = MybatisUtils.getSqlSession();
          UserMapper mapper = sqlSession.getMapper(UserMapper.class);
      
      
          int res = mapper.deleteUser(4);
          if (res >0){
              System.out.println("删除成功");
          }
          // 提交事务(必须提交,不然表中不变)
          sqlSession.commit();
          sqlSession.close();
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14

      
      

    知识点三 : 映射文件 Map的使用


    • ① 编写 mapper 接口

      """
      假设实体类或数据库表中字段或参数过多,就应当考虑使用Map.
      """
          
      // 万能Map
      int addUser2(Map<String,Object> map);
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
    • ② 编写 映射文件 SQL语句

      <insert id="addUser2" parameterType="map">
          insert into mybatis.user (id,name,pwd) values (#{userid},#{userName},#{passWord});
      insert>
      
      • 1
      • 2
      • 3
    • ③ 编写 测试文件

      @Test
      public void addUser2(){
          SqlSession sqlSession = MybatisUtils.getSqlSession();
          UserMapper mapper = sqlSession.getMapper(UserMapper.class);
      
          Map<String,Object> map =new HashMap<String, Object>();
          map.put("userid",5);
          map.put("userName","白猫");
          map.put("passWord","000111");
      
          sqlSession.commit();
          sqlSession.close();
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13

      注意点1 : java代码写模糊查询的时候,传递通配符%%.

      List<User> userList = mapper.getUserLike("%李%")
      
      • 1

      注意点2 : 在sql拼接中使用通配符.

      select * from mybatis.user where name like "%#{value}%"
      
      • 1

      
      

    知识点四 : 资源 核心配置文件

    1. mybatis-config.xml 文件


    • MyBatis的配置文件包含了深刻影响MyBatis行为的设置和属性信息

      configuration(配置)
      properties(属性)
      settings(设置)
      typeAliases(类型别名)
      typeHandlers(类型处理器)
      objectFactory(对象工厂)
      plugins(插件)
      environments(环境配置)
      environment(环境变量)
      transactionManager(事务管理器)
      dataSource(数据源)
      databaseIdProvider(数据库厂商标识)
      mappers(映射器)
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
    • 环境配置(environments) :

      • Mybatis可以配置成适应多种环境
      • Mybatis默认的事务管理器是JDBC,连接池:POOLED

      注意点1 : 尽管可以在mybatis-config.xml 文件中配置多种环境,但每个 SqlSessionFactory实例只能选择一种环境.

      图片/Mybatis基础知识2.png


      
      

    2. jdbc.properties 文件


    • ① 通过properties属性来实现引用配置文件: 在 src\main\resources 路径下新建一个 jdbc.properties 文件,并插入以下内容

      jdbc.driver=com.mysql.jdbc.Driver
      jdbc.url=jdbc:mysql://127.0.0.1:3306/mybatis_sql
      jdbc.username=root
      jdbc.password=123456
      
      • 1
      • 2
      • 3
      • 4
    • ② 在核心配置文件 mybatis-config.xml 文件中映入以下内容

      <properties resource="jdbc.properties">
          <property name="username" value="root"/>
          <property name="password" value="123456"/>
      properties>
      
      • 1
      • 2
      • 3
      • 4

      注意点1 : 这些属性都是可外部配置且可动态替换的,既可以在典型的 Java 属性文件中配置,也可以在 properties 元素的子元素中设置.

      注意点2 : 在xml中所有的标签都可以规定其顺序,properties需在environments前,否则报错.

      注意点3 : 在mybatis-config.xml文件中可以直接引入外部文件且可以在其中增加一些属性配置.

      注意点4 : 当db.properties文件和mybatis-config.xml文件中增加的属性配置有同一字段时,优先使用外部配置文件的.


      
      

    知识点五 : 资源 类型别名


    • 类型别名 : 类型别名是为Java类型设置一个短的名字,其存在的意义仅在于用来减少类完全限定名的冗余.

      • 方式一 : 在核心配置文件 mybatis-config.xml 文件中插入以下内容

        
        <typeAliases>
            <typeAlias type="com.whiteCat.pojo.User" alias="User"/>
        typeAliases>
        
        • 1
        • 2
        • 3
        • 4
      • 方式二 : 在核心配置文件 mybatis-config.xml 文件中插入以下内容

        
        <typeAliases>
            <package name="com.whiteCat.pojo"/>
        typeAliases>
        
        
        • 1
        • 2
        • 3
        • 4
        • 5

      注意点1 : typeAliases 位置在 environments 之前, properties 之后

      注意点2 : 方法二是扫盲实体类的包,它的默认别名就为这个类的类名,注意首字母要小写

      注意点3 : 法一在实体类较少时使用,法二在实体类多时使用.


      
      

    知识点六 : 资源 映射器


    • MapperRegistry : 注册绑定我们的Mapper文件.

      • 方式一 : 使用相对于类路径的资源引用(推荐)

         
            <mappers>
                <mapper resource="com/whiteCat/dao/UserMapper.xml"/>
            mappers>
        
        • 1
        • 2
        • 3
        • 4
      • 方式二 : 使用class文件绑定注册

         
            <mappers>
                <mapper class="com.whiteCat.dao.UserMapper"/>
            mappers>
        
        • 1
        • 2
        • 3
        • 4

        注意点1 : 接口和它的Mapper配置文件必须同名

        注意点2 : 接口和它的Mapper配置文件必须在同一个包下

      • 方式三 : 使用扫描包进行注入绑定

         
            <mappers>
                <package name = "com.whiteCat.dao"/>
            mappers>
        
        • 1
        • 2
        • 3
        • 4

      
      

    知识点七 : Mybatis 生命周期和作用域


    • 生命周期和作用域图解 :

      图片/Mybatis基础知识3.png

      图片/Mybatis基础知识4.png

      名称解释
      SqlSessionFactoryBuilder1.创建SqlSessionFactory后丢弃
      2.局部变量
      SqlSessionFactory (核心)1.相当于数据库连接池,一旦创建就一直存在,没有任何理由丢弃或重建一个实例
      2.最佳作用域为应用作用域
      3.最简单的就是使用单例模式或静态单例模式
      SqlSession1.连接到连接池的一个请求
      2.用完之后需关闭,否则资源会被占用

      注意点1 : 生命周期和作用域是至关重要的,错误的使用会导致严重的并发问题.

      注意点2 : 每一个mapper就代表一个具体的业务.


      
      

    知识点八 : Mybatis ResultMap结果集映射


    • 问题 : 数据库中的字段名为pwd,但是User.java文件中的属性名我们写的是password,属性名与字段名不一致导致UserDaoTest.java文件执行后的password结果值为null.

      图片/Mybatis基础知识5.png

    • 解决办法 :

      • 方案1 : 给UserMapper.xml文件中查询的SQL语句中的pwd起别名.

        图片/Mybatis基础知识6.png

      • 方案2 : 用ResultMap将数据库字段和实体类属性映射.

        图片/Mybatis基础知识7.png

        注意点1 : ResultMap元素是MyBatis中最重要最强大的元素.

        注意点2 : ResultMap的设计思想是,对于简单的语句根本不需要配置显式的结果映射,对于复杂的语句只需描述它们间的关系即可.

        注意点3 : ResultMap最优秀的地方在于,如果对其足够了解,便无需显式地用到他们.


      
      

    知识点九 : Mybatis 日志


    • 日志 : 如果一个数据库操作出现异常,则需要我们手动排错.而日志就是我们最好的助手.mybatis设置中的logImpl(日志工厂),其可以指定 MyBatis 所用日志的具体实现,未指定时将自动查找.

    • loglmpl 有效值 :

      有效值要求说明
      SLF4J了解
      LOG4J掌握1.可通过其控制日志信息输送的目的地(控制台,文件,GUI组件等);
      2.可控制每一条日志的输出格式;
      3.通过定义每一条日志信息的级别,我们能够更加细致地控制日志的生成过程;
      4.通过一个配置文件来灵活地进行配置而无需修改应用的代码
      LOG4J2了解
      JDK_LOGGING了解
      COMMONS_LOGGING了解
      STDOUT_LOGGING掌握标准日志输出
      NO_LOGGING了解

      注意点1 : 在Mybatis中具体使用哪个日志实现,在设置中设定.

    • loglmpl-log4j 的使用

      • ① 配置资源文件在 mybatis-config.xml 文件下导包

        <dependencies>
            
            <dependency>
                <groupId>log4jgroupId>
                <artifactId>log4jartifactId>
                <version>1.2.17version>
            dependency>
        dependencies>
        
        • 1
        • 2
        • 3
        • 4
        • 5
        • 6
        • 7
        • 8
      • ② 配置资源文件在resouces文件下新建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/whiteCat.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.sql.PreparedStatement = DEBUG
        
        • 1
        • 2
        • 3
        • 4
        • 5
        • 6
        • 7
        • 8
        • 9
        • 10
        • 11
        • 12
        • 13
        • 14
        • 15
        • 16
        • 17
        • 18
        • 19
        • 20
        • 21
        • 22
        • 23
        • 24
      • ③ 配置资源文件在mybatis-config.xml文件中配置log4j为日志的实现

        <settings>
            <setting name="logImpl" value="LOG4J"/>
        settings>
        
        • 1
        • 2
        • 3
      • ④ 配置测试文件实现 Log4j 的简单使用

        @Test
        public void testLog4j(){
            logger.info("info:进入testLog4j");
            logger.debug("debug:进入了testLog4j");
            logger.error("error:进入了testLog4j");
        }
        
        • 1
        • 2
        • 3
        • 4
        • 5
        • 6

      
      

    知识点十 : Mybatis 分页


    • 使用SQL实现limit分页

      • ① 配置 mapper 接口文件

        // 分页
        List<User> getUserByLimit(Map<String,Integer> map);
        
        • 1
        • 2
      • ② 配置 映射文件

        
        <select id="getUserByLimit" parameterType="map" resultMap="UserMap">
            select * from mybatis.user limit #{startIndex},#{pageSize}
        select>
        
        • 1
        • 2
        • 3
        • 4
      • ③ 配置 测试文件

        @Test
        public void getUserByLimit(){
            SqlSession sqlSession = MybatisUtils.getSqlSession();
            UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        
            HashMap<String,Integer> map = new HashMap<String, Integer>();
            map.put("startIndex", 1);
            map.put("pageSize", 2);
            List<User> userList = mapper.getUserByLimit(map);
            for (User user : userList){
                System.out.println(user);
            }
            sqlSession.close();
        }
        
        • 1
        • 2
        • 3
        • 4
        • 5
        • 6
        • 7
        • 8
        • 9
        • 10
        • 11
        • 12
        • 13
        • 14
    • 不使用SQL实现RowBounds分页(了解)

      • ① 配置 mapper 接口文件

        //分页2
        List<User> getUserByRowBounds();
        
        • 1
        • 2
      • ② 配置 映射文件

        
        <select id="getUserByRowBounds" resultMap="UserMap">
            select * from mybatis.user
        select>
        
        • 1
        • 2
        • 3
        • 4
      • ③ 配置 测试文件

        @Test
        public void getUserByRowBounds(){
            SqlSession sqlSession = MybatisUtils.getSqlSession();
        
            // RowBounds实现
            RowBounds rowBounds = new RowBounds(1,2);
        
            // 通过Java代码层面实现分页
            List<User> userList = sqlSession.selectList("com.whiteCat.dao.UserMapper.getUserByRowBounds");
        
            for (User user : userList){
                System.out.println(user);
            }
            sqlSession.close();
        }
        
        • 1
        • 2
        • 3
        • 4
        • 5
        • 6
        • 7
        • 8
        • 9
        • 10
        • 11
        • 12
        • 13
        • 14
        • 15

      
      

    知识点十一 : Mybatis 注解开发


    • ① 配置 mapper 接口文件

      @Select("select * from user")
      List<User> getUsers();
      
      • 1
      • 2
    • ② 在核心配置文件中绑定接口

      
      <mappers>
          <mapper class="com.whiteCat.dao.UserMapper"/>
      mappers>
      
      • 1
      • 2
      • 3
      • 4
    • 配置 测试文件

      @Test
      public void test() {
          SqlSession sqlSession = MybatisUtils.getSqlSession();
          UserMapper mapper = sqlSession.getMapper(UserMapper.class);
          List<User> users = mapper.getUsers();
          for (User user : users) {
              System.out.println(user);
          }
          sqlSession.close();
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9

      
      

    知识点十二 : Mybatis 开发过程

    图片/Mybatis基础知识8.png

      
      

    知识点十三 : Mybatis 注解CRUD


    • ① 编写接口,增加注解

      public interface UserMapper {
      
      
          @Select("select * from user")
          List<User> getUsers();
      
          
          // 方法存在多个参数,所有的参数前面必须加上@Param("id")注解
          @Select("select * from user where id = #{id}")
          User getUserByID(@Param("id") int id);
      
      
          @Insert("insert into user(id,name,pwd) values (#{id},#{name},#{password})")
          int addUser(User user);
      
      
          @Update("update user set name=#{name},pwd=#{password} where id = #{id}")
          int updateUser(User user);
      
      
          @Delete("delete from user where id = #{uid}")
          int deleteUser(@Param("uid") int id);
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
    • ② 编写 测试文件

      // 我们必须要将接口注册绑定到我们的核心配置文件中
      
      @Test
      public void test() {
          SqlSession sqlSession = MybatisUtils.getSqlSession();
          UserMapper mapper = sqlSession.getMapper(UserMapper.class);
          List<User> users = mapper.getUsers();
          for (User user : users) {
              System.out.println(user);
          }
          User userByID = mapper.getUserByID(1);
          System.out.println(userByID);
      
      
          mapper.addUser(new User(5,"Hello","123123"));
      
      
          mapper.updateUser(new User(5,"to","213213"));
          mapper.deleteUser(5);
          sqlSession.commit();
          sqlSession.close();
      	}
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23

      注意点1 : 关于@Param()注解

      ​ 1.基本类型的参数或者String类型,需要加@上Param()

      ​ 2.引用类型不需要加@Param()

      ​ 3.如果之一个基本类型,可忽略,但是还是建议加上

      ​ 4.我们在SQL中引用的就是我们这里的@Param()中设定的属性名


      
      

    知识点十四 : Mybatis Lombok的使用


    • ① 在IDEA中安装Lombok插件: 在Setting中的Plugins中下载即可

    • ② 在项目中导入lombok的jar包

      <dependencies>
          <dependency>
              <groupId>org.projectlombokgroupId>
              <artifactId>lombokartifactId>
              <version>1.18.10version>
          dependency>
      dependencies>
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
    • ③ 使用

      @Data:无参构造,get,set,tostring,hashcode,equals
      @AllArgsConstructor
      @NoArgsConstructor
      @EqualsAndHashCode
      @ToString
      
      • 1
      • 2
      • 3
      • 4
      • 5

      
      

    知识点十五 : Mybatis 多对一处理


    • 多对一释义 : 如多个学生对应一个老师,对于学生而言,多个学生关联了一个老师(即多对一,也叫关联).而对于老师而言,一个老师有很多学生(即一对多,也叫集合)

    • 多对一处理 :

      • ① 创建SQL表

        CREATE TABLE `teacher` (
          `id` INT(10) NOT NULL,
          `name` VARCHAR(30) DEFAULT NULL,
          PRIMARY KEY (`id`)
        ) ENGINE=INNODB DEFAULT CHARSET=utf8
        
        
        INSERT INTO teacher(`id`, `name`) VALUES (1, '秦老师'); 
        
        
        CREATE TABLE `student` (
          `id` INT(10) NOT NULL,
          `name` VARCHAR(30) DEFAULT NULL,
          `tid` INT(10) DEFAULT NULL,
          PRIMARY KEY (`id`),
          KEY `fktid` (`tid`),
          CONSTRAINT `fktid` FOREIGN KEY (`tid`) REFERENCES `teacher` (`id`)
        ) ENGINE=INNODB DEFAULT CHARSET=utf8
        
        
        INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('1', '小明', '1'); 
        INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('2', '小红', '1'); 
        INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('3', '小张', '1'); 
        INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('4', '小李', '1'); 
        INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('5', '小王', '1');
        
        • 1
        • 2
        • 3
        • 4
        • 5
        • 6
        • 7
        • 8
        • 9
        • 10
        • 11
        • 12
        • 13
        • 14
        • 15
        • 16
        • 17
        • 18
        • 19
        • 20
        • 21
        • 22
        • 23
        • 24
        • 25
      • ② 测试环境搭建

        • 导入lombok
        • 新建实体类Teacher,Student
        • 建立Mapper接口
        • 建立Mapper.xml文件
        • 在核心配置文件中绑定注册我们的Mapper接口或者文件
        • 测试查询是否能够成功
      • ③ 按照查询嵌套处理

        
            <select id="getStudent" resultMap="StudentTeacher">
                select * from student
            select>
            <resultMap id="StudentTeacher" type="Student">
                <result property="id" column="id"/>
                <result property="name" column="name"/>
                
                <association property="teacher" column="tid" javaType="Teacher" select="getTeacher"/>
            resultMap>
            <select id="getTeacher" resultType="Teacher">
                select * from teacher where id = #{id}
            select>
        
        • 1
        • 2
        • 3
        • 4
        • 5
        • 6
        • 7
        • 8
        • 9
        • 10
        • 11
        • 12
        • 13
      • ④ 按照结果嵌套处理

        
            <select id="getStudent2" resultMap="StudentTeacher2">
                select s.id as sid,s.name as sname,t.name as tname
                from student s,teacher t
                where s.tid=t.id;
            select>
            <resultMap id="StudentTeacher2" type="Student">
                <result property="id" column="sid"/>
                <result property="name" column="sname"/>
                <association property="teacher" javaType="Teacher">
                    <result property="name" column="tname"/>
                association>
            resultMap>
        
        • 1
        • 2
        • 3
        • 4
        • 5
        • 6
        • 7
        • 8
        • 9
        • 10
        • 11
        • 12
        • 13

      

    知识点十六 : Mybatis 一对多处理


    • ① 实体类

      @Data
      public class Student {
          private int id;
          private String name;
          private Teacher tid;
      }
      
      
      @Data
      public class Teacher {
          private int id;
          private String name;
      
      
          // 一个老师拥有多个学生
          private List<Student> students;
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
    • ② 按照结果嵌套查询

      <select id="getTeacher" resultMap="TeacherStudent">
          select s.id sid ,s.name sname, t.name tname, t.id as tid
          from student s,teacher t
          where s.tid =t.id and t.id = #{tid}
      select>
      
      
      <resultMap id="TeacherStudent" type="Teacher">
          <result property="id" column="tid"/>
          <result property="name" column="tname"/>
          
          <collection property="students" ofType="Student">
              <result property="id" column="sid"/>
              <result property="name" column="sname"/>
              <result property="tid" column="tid"/>
          collection>
      resultMap>
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
    • ③ 按照查询嵌套处理

      <select id="getTeacher2" resultMap="">
          select * from mybatis.teacher where id = #{tid}
      select>
      <resultMap id="TeacherStudent2" type="Teacher">
          <collection property="students" javaType="ArrayList" ofType="Student" select="getStudentByTeacherId" column="id"/>
      
      
      resultMap>
      
      
      <select id="getStudentByTeacherId" resultType="Student">
          select * from mybatis.student where tid = #{tid}
      select>
      
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
    • 小结

      • 关联-association 多对一
      • 集合-collection 一对多
      • javatype & ofType
        • javaType 用来指定实体类中属性的类型
        • ofType 用来指定映射到List或者集合中的pojo类型

      

    知识点十七 : Mybatis 动态SQL


    • 动态SQL定义 : 动态SQL就是根据不同的条件生成不同的SQL语句.

    • 搭建环境 :

      -- 搭建环境用到的SQL语句
      
      CREATE TABLE `blog`(
      `id` VARCHAR(50) NOT NULL COMMENT '博客id',
      `title` VARCHAR(100) NOT NULL COMMENT '博客标题',
      `author` VARCHAR(30) NOT NULL COMMENT '博客作者',
      `create_time` DATETIME NOT NULL COMMENT '创建时间',
      `views` INT(30) NOT NULL COMMENT '浏览量'
      )ENGINE=INNODB DEFAULT CHARSET=utf8
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
    • 创建基础工程

      • ① 导包

      • ② 编写配置文件

      • ③ 编写实体类

        @Data
        public class Blog {
            private int id;
            private String title;
            private String author;
            private Date createTime;
            private int views;
        }
        
        • 1
        • 2
        • 3
        • 4
        • 5
        • 6
        • 7
        • 8
      • ④ 编写实体类对应Mapper接口和Mapper.XML文件

    • if 语句

      <select id="queryBlogIF" parameterType="map" resultType="blog">
          select * from mybatis.blog where 1=1
          <if test="title != null">
              and title = #{title}
          if>
      
      
          <if test="author != null">
              and author = #{author}
          if>
      select>
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
    • choose(when,otherwise) 语句

      <select id="queryBlogChoose" parameterType="map" resultType="blog">
          select * from mybatis.blog
          <where>
              <choose>
                  <when test="title != null">
                      title = #{title}
                  when>
                  <when test="author != null">
                       and author = #{author}
                  when>
                  <otherwise>
                      and views =#{views}
                  otherwise>
              choose>
          where>
      select>
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
    • trim(where,set) 语句

      <update id="updateBlog" parameterType="map">
          update mybatis.blog
          <set>
              <if test="title != null">
                  title = #{title},
              if>
              <if test="author != null">
                  author = #{author}
              if>
          set>
          where id = #{id}
      update>
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12

      注意点1 : 所谓的动态SQL其本质还是SQL语句,只是我们可以在SQL层面去执行一个逻辑代码(if,where,set,choose,when)

    • SQL片段 : 有时候我们可能会将一些功能的部分抽取出来方便复用

      • ① 使用SQL标签抽取公共部分

        <sql id="if-title-author">
            <if test="title != null">
                and title = #{title}
            if>
        
            <if test="author != null">
                and author = #{author}
            if>
        sql>
        
        • 1
        • 2
        • 3
        • 4
        • 5
        • 6
        • 7
        • 8
        • 9
      • ② 在需要使用的地方使用Include标签引用即可

        <select id="queryBlogIF" parameterType="map" resultType="blog">
            select * from mybatis.blog
            <where>
                <include refid="if-title-author">include>
            where>
        select>
        
        • 1
        • 2
        • 3
        • 4
        • 5
        • 6

      注意点1 : SQL片段最好基于单表来定义SQL片段

      注意点2 : SQL片段不要存在where标签

    • Foreach 语句

      
      <select id="queryBlogForeach" parameterType="map" resultType="blog">
      
      
          select * from mybatis.blog
          <where>
              <foreach collection="ids" item="id" open="and (" close=")" separator="or">
                  id = #{id}
              foreach>
          where>
      select>
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14

      注意点1 : 先在MySQL中写出完整的SQL,再对应的去修改成动态SQL实现通用即可.


      

    知识点十八 : Mybatis 缓存


    • 缓存定义 : 存储在内存中的临时数据,将用户经常查询的数据放在缓存(内存)中,即再次查询相同数据的时候直接走缓存而不用走数据库

    • Mybatis一级缓存

      • 一级缓存也叫本地缓存:SqlSession.

        • 与数据库同一次会话期间查询到的数据会放在本地缓存中.
        • 以后如果需要获取相同的数据,直接从缓存中拿,没必要再去查询数据库;
      • 测试步骤:

        • ① 开启日志

              <settings>
                  
                  <setting name="logImpl" value="STDOUT_LOGGING"/>
              settings>
          
          • 1
          • 2
          • 3
          • 4
        • ② 测试一个Session中查询两次相同的记录

              @Test
              public void test(){
                 SqlSession sqlSession = MybatisUtils.getSqlSession();
                  UserMapper mapper = sqlSession.getMapper(UserMapper.class);
          
          
                  User user = mapper.queryUserById(1);
                  System.out.println(user);
          
          
                  System.out.println("========================");
          
          
                  User user2 = mapper.queryUserById(1);
                  System.out.println(user2);
          
          
                  sqlSession.close();
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          • 16
          • 17
          • 18
        • ③ 查看日志输出

          图片/Mybatis基础知识9.png

        • ④ 缓存失效的情况:

          • 查询不同的东西
          • 增删改操作,可能会改变原来的数据,所以必定会刷新缓存
          • 查询不同的Mapper.xml
          • 手动清理缓存:sqlSession.clearCache();
    • Mybatis二级缓存

      • 二级缓存也叫全局缓存,一个作用域太低故而诞生了二级缓存.

      • 基于namespace级别的缓存,一个命名空间对应一个二级缓存;

      • 二级缓存的工作机制是:

        • 一个会话查询一条数据,这个数据就会被放在当前会话的一级缓存中;
        • 如果当前会话关闭了,这个会话对应的一级缓存就没了,但是我们想要的是,会话关闭,一级缓存会被保存到二级缓存中;
        • 新的会话查询信息就可以从二级缓存中获取内容;
        • 不同的mapper查出的数据会放在自己对应的缓存(map)中;

        注意点1 : 只要开启了二级缓存,在同一个Mapper下就有效

        注意点2 : 所有的数据都会先放在一级缓存中,只有当会话提交,或者关闭的时候,才会提交到二级缓存中.

      • 测试步骤:

        • ① 开启全局缓存

                  
                  <setting name="cacheEnabled" value="true"/>
          
          • 1
          • 2
        • ② 在要使用二级缓存的Mapper中开启

              
              <cache/>
          
          • 1
          • 2

          也可以自定义参数

              
              <cache 
                      eviction="FIFO" 
                      flushInterval="60000" 
                      size="512" 
                      readOnly="true"
              />
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
        • ③ 将实体类序列化 (否则报错)

          @Data
          @AllArgsConstructor
          @NoArgsConstructor
          public class User implements Serializable {
              private int id;
              private String name;
              private String pwd;
          }
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8

          注意点1 : 报错内容为Caused by: java.io.NotSerializableException: com.whiteCat.pojo.User

    • Mybatis 缓存原理

      图片/Mybatis基础知识10.png

    • Mybatis 自定义缓存Ehcache (了解)

      • Ehcache是一种广泛使用的开源Java分布式缓存,主要面向通用缓存

      • 使用步骤:

        • ① 导包

                  <dependency>
                      <groupId>org.mybatis.cachesgroupId>
                      <artifactId>mybatis-ehcacheartifactId>
                      <version>1.1.0version>
                  dependency>
          
          • 1
          • 2
          • 3
          • 4
          • 5
        • ② 在mapper中指定使用我们的ehcache缓存实现

              
              <cache type="org.mybatis.caches.ehcache.EhcacheCache"/>
          
          • 1
          • 2
        • ③ ehcache.xml

          
          <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                   xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"
                   updateCheck="false">
              
              <diskStore path="./tmpdir/Tmp_EhCache"/>
          
          
              
              <defaultCache
                  eternal="false"
                  maxElementsInMemory="10000"
                  overflowToDisk="false"
                  diskPersistent="false"
                  timeToIdleSeconds="1800"
                  timeToLiveSeconds="259200"
                  memoryStoreEvictionPolicy="LRU"/>
          
          
              <cache
                      name="cloud_user"
                      eternal="false"
                      maxElementsInMemory="5000"
                      overflowToDisk="false"
                      diskPersistent="false"
                      timeToIdleSeconds="1800"
                      timeToLiveSeconds="1800"
                      memoryStoreEvictionPolicy="LRU"/>
          
          
              
          ehcache>
          
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          • 16
          • 17
          • 18
          • 19
          • 20
          • 21
          • 22
          • 23
          • 24
          • 25
          • 26
          • 27
          • 28
          • 29
          • 30
          • 31
          • 32
          • 33
          • 34
          • 35
          • 36
          • 37
          • 38
          • 39
          • 40
          • 41
          • 42
          • 43
          • 44
          • 45
          • 46
          • 47
          • 48
          • 49

      
      

    知识点十九 : Mybatis 笔记


    • 笔记1 : 什么是Create from archetype?
      • Create from archetype勾选之后,相当于创建了一个模板maven项目,但一般不用,因为我们直接创建出来的maven工程默认是一个Java工程

      

    • 笔记2 : maven项目的三种打包方式: pom jar war

      • pom:用在父级工程或聚合工程中,用来做jar包的版本控制,必须指明这个聚合工程的打包方式为pom.

      • jar:工程的默认打包方式,打包成jar用作jar包使用。存放一些其他工程都会使用的类,工具类。我们可以在其他工程的pom文件中去引用它.

      • war:将会打包成war,发布在服务器上,如网站或服务。用户可以通过浏览器直接访问,或者是通过发布服务被别的工程调用.

        总结1 : pom用于父工程中,jar和war用于子项目(module)

      

    • 笔记3 : Import changes 和 enable auto-import

      • Import Changes Enable Auto-Import:导入我们新添加的依赖

      • Enable Auto-Import:以后更改 .pom 文件后自动下载依赖包

        总结1 : 如果没有勾选自动导入依赖,打开setting→maven→importing:取消选择Import Maven projects automatically

        总结2 : 导入的依赖需要再手打一遍,不然会一直爆红

      

    • 笔记4 : maven工程中生成的标准目录

      名称解释
      src即source,该文件夹下存放的是项目的源文件(.java后缀与配置文件)。
      src\main主程序文件夹
      src\main\java放置java代码的文件夹
      src\main\resources放置配置文件

      

    • 笔记5 : MyBatis核心配置文件中,标签的顺序

      
      
      
      
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

  

  • 笔记6 : mapper接口
    • mybatis中的mapper接口相当于以前的dao,但是区别在于,mapper仅仅是接口,我们不需要提交实现类.

  

  • 笔记7 : 实体类与其mapper接口
    • 先创建实体类User,再创建其mapper接口UserMapper.
    • mybatis为什么要创建mapper接口? 因为mybatis中有面向接口编程的功能,然后每当我们去调用接口中的方法,它就会自动去匹配一个SQL语句并且去执行

  

  • 笔记8 : 映射文件

    • Java概念: 类 属性 对象

    • 数据库概念: 表 字段/列 记录/行

      pom.xml(maven仓库导入各种需要的工具) <----------> mybatis-config.xml(配置核心文件连接到mysql数据库),log4j.xml(配置日志) <----------> 实体类User(用的哪张表就创建一个对应的实体类) <----------> *mapper接口UserMapper(写入想要通过SQL语句实现的功能) <---------->  *映射文件UserMapper.xml(写实现功能的SQL语句) <----------> 测试文件MybatisTest(测试能否实现功能),SqlSessionUtils文件(封装要用的SQLSession对象避免代码冗余)
      
      • 1
      • 一个映射文件对应一个实体类,对应一张表的操作
      • Mybatis映射文件用于编写SQL,访问及其操作表中的数据
      • Mybatis映射文件存放的位置是src/main/resources/mappers目录下
      • 映射文件的命名规则:表所对应的实体类的类名+Mapper.xml
      • MyBatis中可以面向接口操作数据,要保证两个一致:
        • 1.mapper接口的全类名和映射文件的命名空间(namespace)保持一致
        • 2.mapper接口中方法的方法名和映射文件中编写SQL的标签的id属性保持一致

  

  • 笔记9 : insert语句需要插入全部属性时,如果有自增量,那一列用null

  

  • 笔记10 : @Test注解
    • 一个方法用了@Test注解,就省略了psvm也可以运行代码,并且使得咱们可以在一个java文件中分别执行不同的方法而不用一次性执行完所有的方法

  

  • 笔记11: sqlsession对象

    • mybaits为我们提供的一个操作数据库的会话对象.

    • 想要用sqlsession对象,就需要加载sqlsession的核心配置文件,这个核心配置文件从import org.apache.ibatis.io中的Resources类中去加载

    • 然后Resources类中有一个静态方法叫做getResourceAsStream(),咱们用这个静态方法来读取当前咱们的配置文件,来获取它所对应的字节输入流

    • 最后因为咱们获取的核心配置文件是以一个字节输入流的方式来获取的,所以返回值也一定是一个字节输入流,故而咱们用InputStream对象来接收.

      InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
      
      • 1
    • 但是因为其与流相关,所以我们一定要来处理异常,这里将其异常声明出去即可.

    @Test
    public void testMyBatis throws IOException{
        /** 加载核心配置文件 **/
        InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 完整流程:

      @Test
      public void testMyBatis throws IOException{
          // 1.读取MyBatis的核心配置文件
          InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
      
          // 2.创建SqlSessionFactoryBuilder对象
          SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
      
          // 3.通过核心配置文件所对应的字节输入流创建工厂类SqlSessionFactory,生产SqlSession对象
          SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(is);
      
          //创建SqlSession对象,此时通过SqlSession对象所操作的sql都必须手动提交或回滚事务
          //SqlSession sqlSession = sqlSessionFactory.openSession();
      
          // 4.创建SqlSession对象,此时通过SqlSession对象所操作的sql都会自动提交
          SqlSession sqlSession = sqlSessionFactory.openSession(true);
      
          // 5.通过代理模式创建UserMapper接口的代理实现类对象
          UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
      
          // 6.调用UserMapper接口中的方法,就可以根据UserMapper的全类名匹配元素文件,通过调用的方法名匹配 映射文件中的SQL标签,并执行标签中的SQL语句
          int result = userMapper.insertUser();
      
          //sqlSession.commit();
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25

      注意点1 : SqlSession:代表Java程序和数据库之间的会话。(HttpSession是Java程序和浏览器之间的会话)

      注意点2 : SqlSessionFactory:是“生产”SqlSession的“工厂”

      注意点3 : 工厂模式:如果创建某一个对象,使用的过程基本固定,那么我们就可以把创建这个对象的相关代码封装到一个“工厂类”中,以后都使用这个工厂类来“生产”我们需要的对象。

      注意点4 : 当然,每次用SqlSession对象要用的步骤是一样的,每次都写那么长一串代码会显得冗余,所以创建一个utils文件夹,将上诉代码封装进SqlSessionUtils文件后再调用即可.

  

  • 笔记12 : 日志的级别

    • FATAL(致命)>ERROR(错误)>WARN(警告)>INFO(信息)>DEBUG(调试)

    注意点1 : 从左到右打印的内容越来越详细

  

  • 笔记13 : 查与增删改的不同
    • select语句需要设置resultType(结果类型)或resultMap(结果映射),否则会报错(因为mybatis在处理结果集的时候我们必须给它指定我们当前查询出来的数据所对应的实体类对象是谁,报错的原因就是因为我们没有设置它的一个结果类型,当前的mybatis执行完SQL语句之后,并不知道要将它转换成什么样的一个实体类对象,当我们设置完结果类型之后,mybatis就可以将我们查询出来的结果转换成我们所设置的结果类型,然后再把我们最终的结果作为返回值返回给我们刚才调用的方法)
    • 还需要注意的是,查询功能的标签必须是resultType或resultMap
      • resultType: 设置的是默认的映射关系(sql字段名和java属性名一致的时候用)
      • resultMap: 设置自定义的映射关系(sql字段名和java属性名不一致,处理多对一关系,处理一对多关系的时候用)

  

  • 笔记14 : 核心配置文件
    • 了解即可,在SSM整合的环境中我们的核心配置文件中所配置的所有的内容都可以交给Spring来管理.

  

  • 笔记15 : Resource Bundle文件
    • 创建一个xxx.properties文件进行资源绑定,其文件格式为键 = 值, 键名需要做到见名知义.
    • 键名有可能会重复,所以我们在设置键名时为其加上一个前缀,如jdbc.driver=com.mysql.jdbc.Driver,jdbc就是键名前缀,我们常以当前文件为单位,设置一个表示功能的前缀.

  

  • 笔记16 : #{}和${}的区别

    • #相当于对数据 加上 双引号,$相当于直接显示数据

      • 1.# 对传入的参数视为字符串,也就是它会预编译
      select * from user where name = #{name},
      
      • 1

      比如传一个csdn,那么传过来就是

      select * from user where name = 'csdn';
      
      • 1
      • 2.$ 将不会将传入的值进行预编译

        select * from user where name=${name},
        
        • 1

        比如传一个csdn,那么传过来就是

        select * from user where name=csdn;
        
        • 1

  

  • 笔记17 : 类型别名typeAliases标签
    • mybatis提供的解决resultType属性对应的全类名值过长的问题
    • 需要注意的是typeAliases标签也好,properties标签也罢,最终都是为environment标签,即连接数据库做服务的.

  

  • 笔记18 : 映射文件中获取参数值

    • 单参: username = ‘${username}’
    • 多参: username = ‘${param1}’ and password = ‘${param2}’
    • 多参(参数为Map,这种情况测试类中的参数名要自己写): username = #{username} and password = #{password}

    注意点1 : 参数值最好就分为两种情况,实参类和使用@Param注解命名参数

  

  • 笔记19 : mapper接口方法的参数是实体类类型的参数

    • 映射文件中的insert语句不写实参,实参到测试类中写.
    1.void insertUser();
    2.<insert id="insertUser">
    insert into t_user values(null,"admin","123456",23,"男","12345@qq.com")
    </insert>
    3.mapper.insertUser();
    
    变成:
    
    1.int insertUser(User user);
    2.<insert id="insertUser">
    insert into t_user values(null,#{username},#{password},#{age},#{sex},#{email})
    </insert>
    3.int result = mapper.insertUser(new User(null, "李四", "123", 23, "男", "123@qq.com"));
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

  

  • 笔记20 : 在批量删除操作中不能使用 #{}. --> delete from t_user where id in (${ids})

  

  • 笔记21 : 动态获取表名,映射文件中的表名不固定,在测试类中写我们要获取的表名 --> select * from ${tableName}

    注意点1 : 注意表名不能加单引号,故而用${}.

  

  • 笔记22 : resultMap只在查询功能中有用,增删改不需要设置映射关系

  

  • 笔记23 : 多对一关系(员工 对 部门) 对一对应对象
    • 分布查询 (因为可用延时加载)

  

  • 笔记24 : 一对多关系(部门 对 员工) 对多对应集合
    • 分布查询(因为可用延时加载)

  

  • 笔记25 : 延迟加载

    • 在核心配置文件mybatis-config.xml中配置
    <setting name="lazyLoadingEnabled" value="true"/>
    
    • 1
    • 查员工表的信息的同时不会去查询部门表,提高查询的效率

  

  • 笔记26 : 动态SQL

    • if标签 : 根据标签中test属性所对应的表达式决定标签中的内容是否需要拼接到SQL中

      
      <select id="getEmpByCondition" resultType="Emp">
      	select * from t_emp
      	<where>
              <if test="empName != null and empName != ''">
                  emp_name = #{empName}
              if>
              <if test="age != null and age != ''">
                  and age = #{age}
              if>
              <if test="sex != null and sex != ''">
                  or sex = #{sex}
              if>
              <if test="email != null and email != ''">
                  and email = #{email}
              if>
      	where>
      select>
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
    • where标签:

      • 当where标签中有内容时,会自动生成where关键字,并且将内容前多余的and或or去掉

        (*注意:where标签不能将其中内容后面多余的and或or去掉)

      • 当where标签中没有内容时,此时where标签没有任何效果.

      
      <select id="getEmpByCondition" resultType="Emp">
      	select * from t_emp
      	<where>
              <if test="empName != null and empName != ''">
                  emp_name = #{empName}
              if>
              <if test="age != null and age != ''">
                  and age = #{age}
              if>
              <if test="sex != null and sex != ''">
                  or sex = #{sex}
              if>
              <if test="email != null and email != ''">
                  and email = #{email}
              if>
      	where>
      select>
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
    • trim标签:

      • 若标签中有内容时:

        prefix|suffix:将trim标签中内容前面或后面添加指定内容

        suffixOverrides|prefixOverrides:将trim标签中内容前面或后面去掉指定内容

        
        <select id="getEmpByCondition" resultType="Emp">
        	select * from t_emp
        	<trim prefix="where" suffixOverrides="and|or">
        	
        		<if test="empName != null and empName != ''">
        			emp_name = #{empName} and
        		if>
        		<if test="age != null and age != ''">
        			age = #{age} or
        		if>
        		<if test="sex != null and sex != ''">
        			sex = #{sex} and
        		if>
        		<if test="email != null and email != ''">
        			email = #{email}
        		if>
        	trim>
        select>
        
        • 1
        • 2
        • 3
        • 4
        • 5
        • 6
        • 7
        • 8
        • 9
        • 10
        • 11
        • 12
        • 13
        • 14
        • 15
        • 16
        • 17
        • 18
        • 19
    • choose标签,when标签,otherwise标签(三个为一套): 相当于if…else if…else

      (注意:when至少要有一个,otherwise最多只能有一个)

      foreach(循环)标签:
      <select id="getEmpByChoose" resultType="Emp">
      	select * from t_emp
      	<where>
      		<choose>
      			<when test="empName != null and empName != ''">
      				emp_name = #{empName}
      			when>
                  <when test="age != null and age != ''">
                  	age = #{age}
                  when>
                  <when test="sex != null and sex != ''">
                      sex = #{sex}
                  when>
                  <when test="email != null and email != ''">
                      email = #{email}
                  when>
                  <otherwise>
                  	did = 1
                  otherwise>
      		choose>
      	where>
      select>
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
    • foreach(循环)标签 :

      • collection: 设置需要循环的数组或集合
      • item: 表示数组或集合中的每一个数据
      • separator: 循环体之间的分割符
      • open: foreach标签所循环的所有内容的开始符
      • close: freach标签所循环的所有内容的结束符
      .sql标签<delete id="deleteMoreByArray">
      	delete from t_emp where eid in
      	<foreach collection="eids" item="eid" separator="," open="(" close=")">
      		#{eid}
      	foreach>
      delete>
      
      ----------------上述方法了解即可,下面是常用的
      
      <delete id="deleteMoreByArray">
      	delete from t_emp where
          <foreach collection="eids" item="eid" separator="or">
          	eid = #{eid}
          foreach>
      delete>
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
    • sql标签 :

      • 设置SQL片段:eid,emp_name,age,sex,email
      • 引用SQL片段:
      <sql id="empColumns">eid,emp_name,age,sex,emailsql>
      
      <select id="getEmpByCondition" resultType="Emp">
      	select <include refid="empColumns">include> from t_emp
      	<trim prefix="where" suffixOverrides="and|or">
      		<if test="empName != null and empName != ''">
      			emp_name = #{empName} and
      		if>
              <if test="age != null and age != ''">
              	age = #{age} or
              if>
              <if test="sex != null and sex != ''">
              	sex = #{sex} and
              if>
              <if test="email != null and email != ''">
              	email = #{email}
              if>
      	trim>
      select>
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19

  

  • 笔记27 : 命名参数@Param(“”)

    • @Param(“”)让我们不再强制遵循mybaits默认的参数名,而是可以自己设置.

      int insertMoreByList(@Param("emps") List<Emp> emps);
      
      List<Emp> emps = Arrays.asList(emp1, emp2, emp3);
      
      • 1
      • 2
      • 3

      注意点1 : 如果不使用@Param,这里我们传参emp1,emp2,emp3就必须使用默认规定的arg,collection和list

  

  • 笔记28 : 缓存

    • 一级缓存: 默认开启,级别为SQLSession.

      • 使一级缓存失效的四种情况:
        • 1.不同的SqlSession对应不同的一级缓存
        • 2.同一个SqlSession但是查询条件不同
        • 3.同一个SqlSession两次查询期间执行了任何一次增删改操作
        • 4.同一个SqlSession两次查询期间手动清空了缓存
    • 二级缓存: 级别为SqlSessionFactory

      • 二级缓存开启的条件:

        • 1.在核心配置文件中,设置全局配置属性cacheEnabled=“true”,默认为true,不需要设置
        • 2.在映射文件中设置标签
        • 3.二级缓存必须在SqlSession关闭或提交之后有效
        • 4.查询的数据所转换的实体类类型必须实现序列化的接口
      • 使二级缓存失效的情况:两次查询之间执行了任意的增删改,会使一级和二级缓存同时失效

    • 一级缓存和二级缓存的查询顺序为:先二后一,都没有查数据库

    注意点1 : 一级缓存默认开,二级缓存最好不开


  • 相关阅读:
    书评《自动驾驶汽车环境感知》
    flink技术总结待续
    ElasticSearch8 8.3.0 安装 + kibana8.3.0 linux系统安装详细流程
    【计算机操作系统慕课版】第一章知识点总结
    MyBatis原理分析手写持久层框架
    2023年高校大数据实验室建设方案
    VFP用上git来管理源代码,备份回滚,开发模式不影响正式版本,猫猫带你来入门
    2022最新版-李宏毅机器学习深度学习课程-P50 BERT的预训练和微调
    .net餐厅管理系统用户,餐厅、结果Model部分
    【从零学习python 】85.Python进程池的并行计算技术应用
  • 原文地址:https://blog.csdn.net/m0_56126722/article/details/126339286