MyBatis知识点总结-DX的笔记

MyBatis知识点总结

什么是MyBatis?

  • 它是一款半自动的ORM持久层框架,具有较高的SQL灵活性,支持高级映射(一对一,一对多),动态SQL,延迟加载和缓存等特性,但它的数据库无关性较低
  • ORM(Object Relation Mapping)对象关系映射
    • 对象:Java对象
    • 关系:数据库中的关系模型
    • 对象关系映射:Java对象和数据库的关系模型之间建立一种对用关系
    • 比如用一个Java的Student类,去对应数据库中的一张student表,类中的属性和表中的列一一对应
    • Student类就对应student表,一个Student对象就对应student表中的一行数据
  • mybatis的特点
    • mybatis是:半自动的ORM框架,需要手动编写SQL语句
    • 全自动的ORM框架(如:hibernate),不需要编写SQL语句
    • hibernate只需设置好ORM映射关系,就可以实现CRUD操作
    • mybatis需要手写SQL,灵活性更高,但是换数据库时,需要重写SQL,因为mybatis的数据无关性低
    • 相对于JDBC,它提供了输入映射和输出映射,方便sql的参数设置和结果集封装
    • 提供了关联查询动态SQL等功能,极大地提升了开发的效率

项目创建思路整理

项目结构

  • 创建Maven项目

  • 在pom.xml文件中导包

      <dependencies>
        <dependency>
          <groupId>junitgroupId>
          <artifactId>junitartifactId>
          <version>4.11version>
          <scope>testscope>
        dependency>
        <dependency>
          <groupId>org.mybatisgroupId>
          <artifactId>mybatisartifactId>
          <version>3.5.1version>
        dependency>
        <dependency>
          <groupId>mysqlgroupId>
          <artifactId>mysql-connector-javaartifactId>
          <version>8.0.19version>
        dependency>
      dependencies>
    
  • 在Java目录下建包

    • entity 实体类
    • utils 工具类
    • dao 数据操作对象
  • 在resources目录下建mybatis-config.xml文件

项目搭建好,开始干活

  1. 编写实体类

    • Student.java
    • 成员变量与字段名尽量相同
  2. 连接数据库的准备

    • 在mybatis-config.xml中写配置信息

      
      DOCTYPE configuration PUBLIC	"-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
      
      <configuration>
          
          <settings>
              <setting name="logImpl" value="STDOUT_LOGGING"/>
          settings>
      
          
          <environments default="mysql">
              <environment id="mysql">
                  <transactionManager type="JDBC">transactionManager>
                  <dataSource type="POOLED">
                      <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                      <property name="url" value="jdbc:mysql:///stusys?serverTimezone=UTC"/>
                      <property name="username" value="root"/>
                      <property name="password" value="111111"/>
                  dataSource>
              environment>
          environments>
      
          
          <mappers>
              <mapper resource="mapper/StudentMapper.xml">mapper>
      
          mappers>
      configuration>
      
  3. 写数据库连接的工具类

    public class MyBatisUtil {
        static SqlSessionFactory factory=null;
        static {
            try {
                InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
                factory = new SqlSessionFactoryBuilder().build(in);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        public static SqlSession getSqlSession(){
            return factory.openSession();
        }
    }
    
  4. 开始写DAO层(数据连接对象)

    • 写StudentDao接口文件

      public interface StudentDao {
      
          List<Student> select();
      
          Student selectById(int id);
      
          int insert(Student student);
      
          int updata(Student student);
      
          int deleteById(int id);
      }
      
    • 写映射文件StudentMapper.xml

      
      DOCTYPE mapper PUBLIC	"-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
      
      <mapper namespace="StudentMapper">
      
          <select id="select" resultType="com.dx.entity.Student">
              select * from student
          select>
          <select id="selectById" parameterType="int" resultType="com.dx.entity.Student">
              select * from student where id=#{id}
          select>
      
          <insert id="insert" parameterType="com.dx.entity.Student">
              insert into student(sname,age,gender,address,phone,remark) values(#{sname},#{age},#{gender},#{address},#{phone},#{remark})
          insert>
      
          <update id="updata" parameterType="com.dx.entity.Student">
              update student set sname=#{sname},age=#{age},gender=#{gender},address=#{address},phone=#{phone},remark=#{remark} where id=#{id}
          update>
      
          <delete id="deleteById">
              delete from student where id = #{id}
          delete>
      
      mapper>
      
  5. 写实现类

    public class StudentDaoImpl implements StudentDao {
        @Override
        public List<Student> select() {
            SqlSession sqlSession = MyBatisUtil.getSqlSession();
            //传入的第一个参数为:mapper文件中的命名空间名称.sql语句id
            List<Student> students = sqlSession.selectList("StudentMapper.select");
            sqlSession.close();
            return students;
        }
    
        @Override
        public Student selectById(int id) {
            SqlSession sqlSession = MyBatisUtil.getSqlSession();
            //传入的第二个参数为:查询条件,如果有多个查询条件应该封装成对象(对象的成员变量名要与sql的字段名保持一致)或使用map
            Student student = sqlSession.selectOne("StudentMapper.selectById",id);
            sqlSession.close();
            return student;
        }
    
        @Override
        public int insert(Student student) {
            SqlSession sqlSession = MyBatisUtil.getSqlSession();
            int result = sqlSession.insert("StudentMapper.insert", student);
            //增、删、改 都需要提交事务
            //jdbc默认自动提交,MyBatis默认手动提交
            sqlSession.commit();
            sqlSession.close();
            return result;
        }
    
        @Override
        public int updata(Student student) {
            SqlSession sqlSession = MyBatisUtil.getSqlSession();
            int result = sqlSession.insert("StudentMapper.updata", student);
            //增、删、改 都需要提交事务
            //jdbc默认自动提交,MyBatis默认手动提交
            sqlSession.commit();
            sqlSession.close();
            return result;
        }
    
        @Override
        public int deleteById(int id) {
            SqlSession sqlSession = MyBatisUtil.getSqlSession();
            int result = sqlSession.insert("StudentMapper.deleteById", id);
            //增、删、改 都需要提交事务
            //jdbc默认自动提交,MyBatis默认手动提交
            sqlSession.commit();
            sqlSession.close();
            return result;
        }
    }
    
  6. 写测试类

    public class MyTest {
    
        @Test
        public void crudTest(){
    
            StudentDaoImpl studentDao = new StudentDaoImpl();
    
            //查
    //        List student = new StudentDaoImpl().select();
    //        Student student = studentDao.selectById(2);
    //        System.out.println(student);
    
            //增
    //        Student student = new Student("莎莎", 22, "1", "zhegnzhou", "1242330", "iafg");
    //        int res = studentDao.insert(student);
            //改
    //        Student student = new Student(17, "shasha", 22, "1", "zhegnzhou", "1242330", "iafg");
    //        int res = studentDao.updata(student);
            //删
            int res = studentDao.deleteById(17);
    
            if (res == 1) {
                System.out.println("成功");
            } else {
                System.out.println("失败");
            }
        }
    }
    

代理模式

dao接口+mapper文件

要求

  1. mapper文件中的命名空间必须与dao接口的全限定名保持一致
  2. mapper文件中的sql语句ID必须与dao接口中的方法名称保持一致
  3. mapper文件中parameterType传入参数类型必须与dao接口中的方法形参类型保持一致
  4. mapper文件中resultType传出结果类型必须与dao接口中的方法返回值“保持一致”

使用方法

  • 不使用代理模式

    SqlSession sqlSession = MybatisUtil.getSqlSession();
    //两个参数(Mapper的命名空间名.sql标签的id , [传入的参数] )
    Emp emp = sqlSession.selectOne("empNamespace.selectById", 7566);
    System.out.println(emp);
    sqlSession.close();
    
  • 使用代理

    SqlSession sqlSession = MybatisUtil.getSqlSession();
    //获取Mapper代理对象 			getMapper(接口.class)		返回值为当前指定接口的实现对象
    DeptDao deptDao = sqlSession.getMapper(DeptDao.class);
    Dept dept = deptDao.selectById(10);
    System.out.println(dept);
    sqlSession.close();
    

mybatis配置文件

全局设置(日志和下划线转驼峰)

<settings>
    
    <setting name="mapUnderscoreToCamelCase" value="true"/>
    
    
    <setting name="logImpl" value="LOG4J"/>
settings>

设置别名

  1. 自带的
    • int -> java.lang.Integer
    • _int -> int
    • double
    • string->java.lang.String
    • map -> java.util.Map,
    • hashmap -> java.util.HashMap
    • list -> java.util.List
  2. 自定义别名

<typeAliases>
    
    <typeAlias type="com.dx.entity.Emp" alias="emp"/>
    
    <package name="com.dx.entity"/>
typeAliases>

配置数据操作环境

<environments default="mysql">
    <environment id="mysql">
        
        <transactionManager type="JDBC">transactionManager>
        
        <dataSource type="POOLED">
            <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
            <property name="url" value="jdbc:mysql:///student?serverTimezone=UTC"/>
            <property name="username" value="root"/>
            <property name="password" value="111111"/>
        dataSource>
    environment>

    <environment id="oracle">
        <transactionManager type="JDBC">transactionManager>
        <dataSource type="POOLED">
            <property name="driver" value="oracle.jdbc.driver.OracleDriver"/>
            <property name="url" value="jdbc:oracle:thin:localhost:1521:orcl"/>
            <property name="username" value="root"/>
            <property name="password" value="111111"/>
        dataSource>
    environment>
environments>

加载mapper映射文件

<mappers>
    
    <mapper resource="mapper/EmpMapper.xml"/>
    
    <mapper class="com.bjpowernode.dao.EmpDao"/>
    
    <package name="com.bjpowernode.dao"/>
mappers>

log4j日志管理

日志配置文件

# 全局日志配置
log4j.rootLogger=DEBUG, stdout
# MyBatis 日志配置
#局部日志记录配置
log4j.logger.org.mybatis.example.BlogMapper=TRACE
# 控制台输出
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p %c.%M() --%m%n

### 输出DEBUG 级别以上的日志到=E://logs/error.log ###
log4j.appender.file = org.apache.log4j.DailyRollingFileAppender
log4j.appender.file.File = D:/logs/test.log
#log4j.appender.file.Append = true
#log4j.appender.file.Threshold = DEBUG
log4j.appender.file.layout = org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n

### 输出DEBUG 级别以上的日志到=E://logs/error.log ###
log4j.appender.E = org.apache.log4j.DailyRollingFileAppender
log4j.appender.E.File =E://logs/error.log 
log4j.appender.E.Append = true
log4j.appender.E.Threshold = ERROR 
log4j.appender.E.layout = org.apache.log4j.PatternLayout
log4j.appender.E.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n

log4j的使用

/**
 * java.util.logging.Logger(JUL)
 */
private Logger logger = Logger.getLogger(Log4jTest.class);

@Test
public void run(){
    //错误信息
    logger.error("error日志");
    //警告信息
    logger.warn("warn日志");
    //普通信息
    logger.info("info日志");
    //调试信息
    logger.debug("debug日志");
    //底层信息
    logger.trace("trace日志");
}

映射配置文件

结果映射

  • 自动映射

    <select id="selectAll" resultType="com.dx.entity.Emp">
    	select empno,ename,job,mgr,hiredate,sal,comm,deptno from emp order by empno desc
    select>
    
  • 手动映射

    <resultMap id="ResultMap" type="emp">
        
        <id column="empno" property="empno"/>
        
        <result column="ename" property="ename"/>
        <result column="job" property="job"/>
        <result column="mgr" property="mgr"/>
        <result column="hiredate" property="hiredate"/>
        <result column="sal" property="sal"/>
        <result column="comm" property="comm"/>
        <result column="deptno" property="deptno"/>
    resultMap>
    
    <select id="selectAll2" resultMap="ResultMap">
        select empno,ename,job,mgr,hiredate,sal,comm,deptno from emp order by empno desc
    select>
    

占位符#与$

  • ${}的sql是静态sql

  • #{}的sql是动态sql

  • 
    <select id="selectById" parameterType="int" resultType="Emp">
        select empno,ename,job,mgr,hiredate,sal,comm,deptno from emp where empno=#{empno}
    select>
    <select id="selectById2" parameterType="int" resultType="Emp">
        select empno,ename,job,mgr,hiredate,sal,comm,deptno from emp where empno=${value}
    select>
    

模糊查询



<select id="selectByEname" parameterType="String" resultType="emp">
    select empno,ename,job,mgr,hiredate,sal,comm,deptno from emp where ename like concat('%',#{name},'%')
select>

<select id="selectByEname2" parameterType="String" resultType="emp">
    select empno,ename,job,mgr,hiredate,sal,comm,deptno from emp where ename like '%${value}%'
select>

<select id="selectByEname3" parameterType="String" resultType="Emp">
    <bind name="keyname" value="'%'+_parameter+'%'"/>
    select empno,ename,job,mgr,hiredate,sal,comm,deptno from emp where ename like #{keyname}
select>

传入多参数

建议:参数为2-4个使用@Param,参数过多使用实体类或Map集合

传入参数为Map

  • mapper.xml

    
    <select id="selectByParam" parameterType="map" resultType="emp">
        select empno,ename,job,mgr,hiredate,sal,comm,deptno from emp
        where deptno=#{aaa}
        and sal>=#{bbb}
    select>
    
  • test.java

    @Test
    public void selectByMap(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        EmpDao empDao = sqlSession.getMapper(EmpDao.class);
        HashMap<String, Object> map = new HashMap<>();
        map.put("aaa",10);
        map.put("bbb",2000);
        List<Emp> emps = empDao.selectByParam(map);
        for (Emp emp : emps) {
        	System.out.println(emp);
        }
        sqlSession.close();
    }
    

使用@Param注解

  • mapper.xml

    <select id="selectByParam2" parameterType="map" resultType="emp">
        select empno,ename,job,mgr,hiredate,sal,comm,deptno from emp
        where deptno=#{deptno}
        and sal>=#{sal}
    select>
    
  • dao.java接口

    public List<Emp> selectByParam2(@Param(value="deptno") Integer deptno,@Param("sal") Double sal);
    
  • test.java

    @Test
    public void selectByMap2(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        EmpDao empDao = sqlSession.getMapper(EmpDao.class);
        List<Emp> emps = empDao.selectByParam2(10,3000.0);
        for (Emp emp : emps) {
        	System.out.println(emp);
        }
        sqlSession.close();
    }
    

分页查询

  • 使用sql语句

    <select id="selectPage" parameterType="map" resultType="emp">
        select empno,ename,job,mgr,hiredate,sal,comm,deptno from emp 
        order by empno limit #{page},#{num}
    select>
    
  • 使用 RowBounds()

    <select id="selectPage2" resultType="emp">
        select empno,ename,job,mgr,hiredate,sal,comm,deptno from emp order by empno
    select>
    
    public List<Emp> selectPage2(RowBounds rowBounds);
    
    //使用RowBounds(起始坐标,展示条数)实现
    RowBounds rowBounds = new RowBounds(10, 5);
    List<Emp> emps = empDao.selectPage2(rowBounds);
    
  • 使用PageHelper插件

    <dependency>
        <groupId>com.github.pagehelpergroupId>
        <artifactId>pagehelperartifactId>
        <version>5.2.0version>
    dependency>
    
    <plugins>
        <plugin interceptor="com.github.pagehelper.PageInterceptor">plugin>
    plugins>
    
    <select id="selectPage3" resultType="emp">
        select empno,ename,job,mgr,hiredate,sal,comm,deptno from emp order by empno
    select>
    
    //使用分页插件 PageHelper.startPage(当前页码,每页条数);
    PageHelper.startPage(1,5);
    List<Emp> emps = empDao.selectPage3();
    
    //在PageHelper提供一个PageInfo的分页工具类
    PageInfo<Emp> pageInfo = new PageInfo<>(list);
    pageInfo.getList();
    System.out.println("当前页码:" + pageInfo.getPageNum());
    System.out.println("每页条数:" + pageInfo.getPageSize());
    System.out.println("总记录数:" + pageInfo.getTotal());
    System.out.println("总页数:" + pageInfo.getPages());
    System.out.println("上一页:" + pageInfo.getPrePage());
    System.out.println("下一页:" + pageInfo.getNextPage());
    System.out.println("是否有上一页:" + pageInfo.isHasPreviousPage());
    System.out.println("是否有下一页:" + pageInfo.isHasNextPage());
    System.out.println("是否为首页:" + pageInfo.isIsFirstPage());
    System.out.println("是否为末页:" + pageInfo.isIsLastPage());
    System.out.println("页码数组:" + Arrays.toString(pageInfo.getNavigatepageNums()));
    

插入数时返回主键值

  • 
    <insert id="insert" parameterType="emp" useGeneratedKeys="true" keyColumn="empno" keyProperty="empno">
        insert into emp(ename,job,mgr,hiredate,sal,comm,deptno)
        values (#{ename},#{job},#{mgr},#{hiredate},#{sal},#{comm},#{deptno})
    insert>
    
  • @Test
    public void insertTest() {
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        EmpDao empDao = sqlSession.getMapper(EmpDao.class);
        Emp emp = new Emp("小小", "经理", 100, new Date(), 5600.0, 1000.0, 20);
        System.out.println("数据插入前empno="+emp.getEmpno());
        empDao.insert(emp);
        System.out.println("数据插入后empno="+emp.getEmpno());
        sqlSession.commit();
        sqlSession.close();
    }
    

动态sql

  • if

    
    <select id="selectUseIf" resultType="emp">
        select empno,ename,job,mgr,hiredate,sal,comm,deptno from emp
        where
        <if test="ename!=null and ename !='' ">
            ename like concat('%',#{ename},'%')
        if>
        <if test="sal!=null">
            and sal >= #{sal}
        if>
    select>
    
    <select id="selectUseIf2" parameterType="String" resultType="emp">
        select empno,ename,job,mgr,hiredate,sal,comm,deptno from emp
        where
        <if test="_parameter!=null and _parameter !='' ">
            ename = #{ename}
        if>
    select>
    
  • where和choose

    <select id="selectUseWhere" resultType="emp">
        select empno,ename,job,mgr,hiredate,sal,comm,deptno from emp
        <where>
            <if test="ename!=null and ename !='' ">
                ename like concat('%',#{ename},'%')
            if>
            <if test="sal!=null">
                and sal >= #{sal}
            if>
    
    
    
    
    
    
        where>
    select>
    
  • set

    <update id="updateUseSet" parameterType="emp">
        update emp
        <set>
            <if test="ename!=null">
                ename=#{ename},
            if>
            <if test="job!=null">
                job=#{job},
            if>
        set>
        where empno=#{empno}
    update>
    
  • foreach

    
    <delete id="deleteUseForeach" parameterType="int">
        delete from emp where empno in
        <foreach collection="array" open="(" close=")" separator="," item="id">
            #{id}
        foreach>
    delete>
    
    <delete id="deleteUseForeach2" parameterType="int">
        delete from emp where empno in
        <foreach collection="list" open="(" close=")" separator="," item="id">
            #{id}
        foreach>
    delete>
    
  • Trim

    
    <insert id="insertUseTrim" parameterType="com.dx.entity.Emp">
        insert into emp
        <trim prefix="(" suffix=")" suffixOverrides=",">
            <if test="ename!=null"> ename, if>
            <if test="job!=null"> job, if>
            <if test="mgr!=null"> mgr, if>
            <if test="hiredate!=null"> hiredate, if>
            <if test="sal!=null"> sal, if>
            <if test="comm!=null"> comm, if>
            <if test="deptno!=null"> deptno, if>
        trim>
        <trim prefix=" values (" suffix=")" suffixOverrides=",">
            <if test="ename!=null"> #{ename}, if>
            <if test="job!=null"> #{job}, if>
            <if test="mgr!=null"> #{mgr}, if>
            <if test="hiredate!=null"> #{hiredate}, if>
            <if test="sal!=null"> #{sal}, if>
            <if test="comm!=null"> #{comm}, if>
            <if test="deptno!=null"> #{deptno} if>
        trim>
    insert>
    
  • 测试类

    @Test
    public void if_where_choose_Test(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        EmpDao empDao = sqlSession.getMapper(EmpDao.class);
        Emp param = new Emp();
        param.setEname("S");
        param.setSal(1000.0);
    	List<Emp> empList = empDao.selectUseIf(param);
        List<Emp> empList = empDao.selectUseWhere(param);
        for (Emp emp : empList) {
            System.out.println(emp);
        }
        sqlSession.close();
    }
    
    @Test
    public void set_Test(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        EmpDao empDao = sqlSession.getMapper(EmpDao.class);
        Emp param = new Emp();
        param.setEmpno(666);
        param.setEname("shasha");
        param.setJob("医生");
        empDao.updateUseSet(param);
        System.out.println("插入成功!");
        sqlSession.commit();
        sqlSession.close();
    }
    
    @Test
    public void foreachTest(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        EmpDao empDao = sqlSession.getMapper(EmpDao.class);
        //批量删除-数组
    	empDao.deleteUseForeach(new Integer[]{1,2,3,4});
        //批量删除-集合
        empDao.deleteUseForeach2(Arrays.asList(1,2,3,4,5,6));
        sqlSession.commit();
        System.out.println("删除成功");
        sqlSession.close();
    }
    

使用注解

使用lombok

  • 导包

    <dependency>
        <groupId>org.projectlombokgroupId>
        <artifactId>lombokartifactId>
        <version>1.18.24version>
    dependency>
    
  • 常用注解

    • @Setter 注解在类或字段,注解在类时为所有字段生成setter方法,注解在字段上时只为该字段生成setter方法。
    • @Getter 使用方法同上,区别在于生成的是getter方法。
    • @ToString 注解在类,添加toString方法。
    • @EqualsAndHashCode 注解在类,生成hashCode和equals方法。
    • @NoArgsConstructor 注解在类,生成无参的构造方法。
    • @RequiredArgsConstructor 注解在类,为类中需要特殊处理的字段生成构造方法,比如final和被@NonNull注解的字段。
    • @AllArgsConstructor 注解在类,生成包含类中所有字段的构造方法。
    • @Data 注解在类,生成setter/getter、equals、canEqual、hashCode、toString方法,如为final属性,则不会为该属性生成setter方法。
    • @Slf4j 注解在类,生成log变量,严格意义来说是常量。private static final Logger log = LoggerFactory.getLogger(UserController.class);

Mybatis注解

  • @Select

  • @Insert

  • @Delete

  • @Update

  • 简单的sql可以用,复杂的不推荐使用

  • 用法

    public interface UserMapper {
        @Insert("insert  into user (name,pwd) value (#{name},#{pwd})")
        Integer insert(User user);
        @Delete("delete  from user where id = #{id}")
        Integer delete(Integer id);
        @Select("select  id,name,pwd from user ")
        List<User> selectAll();
        /* 动态sql 写法 */
        @Select("")
        List<User> selectList(@Param("age") Integer age);
    }
    

缓存

一级缓存

  • 一级缓存:在同一个sqlSession中

  • 一级缓存是内存式缓存,必须使用,不能关闭

  • 查询时,先查询一级缓存,如果没有找到数据再发送sql语句查询数据,并将结果放到sqlSession中

  • @Test
    public void firstCacheTest(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
    
        System.out.println("——————————————————————————第一次查询——————————————————————————");
        UserDao userDao = sqlSession.getMapper(UserDao.class);
        User user = userDao.selectUserById(2);
        System.out.println(user);
    
        //清空一级缓存
        //sqlSession.commit();
    
        System.out.println("——————————————————————————第二次查询——————————————————————————");
        UserDao userDao2 = sqlSession.getMapper(UserDao.class);
        User user2 = userDao2.selectUserById(2);
        System.out.println(user2);
    
        System.out.println("——————————————————————————两次结果对比——————————————————————————");
        System.out.println(user==user2);
    
        sqlSession.close();
    }
    

二级缓存

  • 二级缓存:在同一个SqlSessionFactory中

  • 二级缓存有三个开关

    • 第一个在mybatis-config.xml中设置cacheEnabled为true(默认开启)
    • 第二个在mapper.xml中加上 (不加上就相当于关闭)
    • 第三个在select标签中配置 useCache=“true” (默认开启)
  • 被缓存的数据需要支持序列化,所以存储的对象必须实现可序列化接口

  •  @Test
    public void secondCacheTest(){
        System.out.println("——————————————————————————第一次查询——————————————————————————");
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        UserDao userDao = sqlSession.getMapper(UserDao.class);
        User user = userDao.selectUserById(2);
        System.out.println(user);
        sqlSession.close();
    
        System.out.println("——————————————————————————第二次查询——————————————————————————");
        SqlSession sqlSession2 = MybatisUtils.getSqlSession();
        UserDao userDao2 = sqlSession2.getMapper(UserDao.class);
        User user2 = userDao2.selectUserById(2);
        System.out.println(user2);
        sqlSession2.close();
    
        System.out.println("——————————————————————————两次结果对比——————————————————————————");
        System.out.println(user==user2);
    }
    

联表查询⭐

使用的数据库

  • student表
id sname cid
1 小李 1
2 小陈 2
3 小郭 2
4 小夏 1
  • classes表
id cname
1 一班
2 二班
3 三班

一对一

  • 查询学生和其所在的班级

  • //Dao接口
    List<Student> selectStudentAndClasses();
    
  • 
    <resultMap id="selectResultMap" type="com.dx.entity.Student">
        
        <id column="id" property="id"/>
        
        <result column="sname" property="sname"/>
        <result column="cid" property="cid"/>
        
        <association property="classes" javaType="com.dx.entity.Classes">
            <id column="id" property="id"/>
            <result column="cname" property="cname"/>
        association>
    resultMap>
    
    <select id="selectStudentAndClasses" resultMap="selectResultMap">
        select s.id,s.sname,s.cid,c.cname from student s join classes c on s.cid=c.id
    select>
    
  • 扩展:使用 代码块 和 继承

    
    
    <resultMap id="BaseResultMap" type="com.dx.entity.Student">
        <id column="id" property="id"/>
        <result column="sname" property="sname"/>
        <result column="cid" property="cid"/>
    resultMap>
    <resultMap id="selectResultMap2" type="com.dx.entity.Student" extends="BaseResultMap">
        <association property="classes" javaType="com.dx.entity.Classes">
            <id column="id" property="id"/>
            <result column="cname" property="cname"/>
        association>
    resultMap>
    
    
    <sql id="FeildList">
        s.id,s.sname,s.cid,c.cname
    sql>
    <select id="selectStudentAndClasses2" resultMap="selectResultMap">
        select <include refid="FeildList">include>
        from student s join classes c on s.cid=c.id
    select>
    

一对多

  • 查询某个班级里的学生

  • Classes selectById(Integer id);
    
  • <resultMap id="BaseResultMap" type="com.dx.entity.Classes">
        <id column="id" property="id"/>
        <result column="cname" property="cname"/>
    resultMap>
    <resultMap id="selectByIdResultMap" type="com.dx.entity.Classes" extends="BaseResultMap">
        <collection property="studentList" ofType="com.dx.entity.Student">
            <id column="sid" property="id"/>
            <result column="sname" property="sname"/>
        collection>
    resultMap>
    
    <select id="selectById" resultMap="selectByIdResultMap">
        select c.id,c.cname,s.id sid,s.sname from classes c left join student s on c.id=s.cid where c.id=#{id}
    select>
    

关联查询

  • Dao接口

    Classes selectOne(Integer id);
    
  • StudentMapper.xml

    
    <select id="selectByCid" resultType="com.dx.entity.Student">
        select id,sname
        from student where cid=#{cid}
    select>
    
  • ClassesMapper.xml

    
    <resultMap id="SelectOneResultMap" type="com.dx.entity.Classes" extends="BaseResultMap">
        
        <collection property="studentList" ofType="com.dx.entity.Student"
                    column="id" select="com.dx.dao.StudentDao.selectByCid">
        collection>
    resultMap>
    
    <select id="selectOne" parameterType="int" resultMap="SelectOneResultMap">
        select id,cname
        from classes
        where id=#{id}
    select>
    

你可能感兴趣的:(Java,mybatis,java)