MyBatis3

一、MyBatis入门

1.1 认识Mybatis

MyBatis 本是Apache的一个开源项目iBatis, 2010年这个项目由Apache Software Foundation 迁移到了Google Code,且改名为MyBatis 。2013年11月迁移到GitHub。iBATIS一词来源于“internet”和“abatis”的组合。

MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Ordinary Java Object,普通的 Java对象)映射成数据库中的记录。

精简解释:MyBatis是一个半自动ORM框架,其本质是对JDBC的封装。使用MyBatis重点需要程序员编写SQL命令,不需要写一行JDBC代码

2.2 第一个MyBatis程序

第一步

创建一个Maven项目并导入对应依赖
在这里插入图片描述在这里插入图片描述
依赖

<dependencies>
        <!--mybatis核心依赖-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.7</version>
        </dependency>
        <!--mysql驱动-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.47</version>
        </dependency>
</dependencies>	

第二步

创建包结构,实体类和准备数据库表
在这里插入图片描述
在这里插入图片描述

第三步

前面两步都是准备工作,现在来编写核心的配置文件

  • 在mapper包中创建DeptMapper接口和对应的DeptMapper.xml文件
//DeptMapper接口
public interface DeptMapper {
    List<Dept> selectAll();
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--namespace:指定DeptMapper接口的位置-->
<mapper namespace="com.lzf.mapper.DeptMapper">

    <!--id:对应DeptMapper接口中的方法名
        resultType:该方法的返回值类型
       -->
    <!--此处编写要执行的sql语句-->
    <select id="selectAll" resultType="com.lzf.pojo.Dept">
        select * from dept
    </select>

</mapper>
  • 在resouces目录下创建mybatis-config.xml文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <!--配置数据源,指定自己数据库的信息-->
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <!--mybatis_db:数据库名称-->
                <property name="url" value="jdbc:mysql://127.0.0.1:3306/mybatis_db?useSSL=false&amp;useUnicode=true&amp;characterEncoding=UTF-8&amp;serverTimezone=Asia/Shanghai"/>
                <!--连接mysql的用户名和密码-->
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
    </environments>
    <!--mapper文件要在这里注册-->
    <mappers>
        <mapper resource="com/lzf/mapper/DeptMapper.xml"/>
    </mappers>
</configuration>

第四步

在test包中编写测试类测试

public static void main(String[] args) throws IOException {
    //1、指定mybatis核心配置文件的输入流
    InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
    //2、创建出sqlSessionFactory
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
    //3、通过sqlSessionFactory创建SqlSession
    SqlSession sqlSession = sqlSessionFactory.openSession();
    //4.通过sqlSession获取到mapper,执行方法拿到结果
    DeptMapper mapper = sqlSession.getMapper(DeptMapper.class);
    List<Dept> depts = mapper.selectAll();
    for (Dept dept : depts) {
        System.out.println(dept);
    }
    //关闭sqlSession
    sqlSession.close();
}
//结果打印
/*
com.lzf.pojo.Dept@27a5f880
com.lzf.pojo.Dept@1d29cf23
com.lzf.pojo.Dept@5f282abb
com.lzf.pojo.Dept@167fdd33
*/

会遇到的问题

在这里插入图片描述

找不到DeptMapper.xml,原因是maven在编译的时候不会把java包中的配置文件编译进去,导致在target目录中找不到文件。
在这里插入图片描述

两种解决办法:

  1. 在pom.xml中添加

    <build>
        <resources>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.xml</include>
                </includes>
                <filtering>true</filtering>
            </resource>
            <resource>
                <directory>src/main/resources</directory>
                <filtering>true</filtering>
            </resource>
        </resources>
    </build>
    
  2. 把DeptMapper.xml文件放到resources目录中,修改了文件的位置,记得mybatis-config注册时的路径也要修改

    <!--mapper文件要在这里注册-->
    <mappers>
        <mapper resource="DeptMapper.xml"/>
    </mappers>
    

二、MyBatis配置详解

2.1 XML配置(核心配置文件)

前置

MyBatis 的配置文件包含了会深深影响 MyBatis 行为的设置和属性信息。 配置文档的顶层结构如下:
在这里插入图片描述

日志

在mybatis.cfg.xml中配置MyBatis所使用的具体日志实现。如果不指定将自动搜索。可能会搜到log4j,但是如果优先搜到了其他的日志实现呢,所以还是设置为好。这一来log4j就跑不了了。

<settings>
    <!--配置日志-->
    <setting name="logImpl" value="LOG4J"/>
</settings>

在resources目录中创建log4j.properties文件

#定义全局日志级别调试阶段推荐debug
log4j.rootLogger=debug,stdout 
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.err
log4j.appender.stdout.layout=org.apache.log4j.SimpleLayout
log4j.appender.logfile=org.apache.log4j.FileAppender
log4j.appender.logfile.File=d:/msb.log
log4j.appender.logfile.layout=org.apache.log4j.PatternLayout
log4j.appender.logfile.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %l %F %p %m%n

也可以使用其他的日志 logj2

<!--log4j2依赖-->
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-core</artifactId>
    <version>2.12.1</version>
</dependency>

在resources目录中创建log4j2.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="DEBUG">
    <Appenders>
        <Console name="Console" target="SYSTEM_ERR">
            <PatternLayout pattern="%d{YYYY-MM-dd HH:mm:ss} [%t] %-5p %c{1}:%L - %msg%n"/>
        </Console>
    </Appenders>
    <Loggers>
        <Root level="DEBUG">
            <AppenderRef ref="Console"/>
        </Root>
    </Loggers>
</Configuration>

事务

在这里插入图片描述

在mybatis核心配置文件中 envirment中 通过transactionManager配置事务的处理策略

JDBC 这个配置直接简单使用了 JDBC 的提交和回滚设置。它依赖于从数据源得到的连接来管理事务范围

MANAGED 这个配置几乎没做什么。它从来不提交或回滚一个连接。而它会让容器来管理事务的整个生命周期(比如 Spring 或 JEE 应用服务器的上下文) 默认情况下它会关闭连接。然而一些容器并不希望这样, 因此如果你需要从连接中停止它,将closeConnection 属性设置为 false。

mybatis本身并不做事务的处理,交给其他框架去处理事务,如spring

映射器(mappers)

mapper映射文件的文件路径导入:resource属性

<mappers>
    <mapper resource="com/lzf/mapper/DeptMapper.xml"/>
</mappers>

接口的全限定名导入:class属性

<mappers>
    <mapper class="com.lzf.mapper.DeptMapper"/>
</mappers>

包扫描形式加载所有的mapper映射文件:package标签

<mappers>
    <package name="com.lzf.mapper"/>
</mappers>

网络资路径:url属性

<!--
本地路径写法:
file:///本地路径
-->
<mappers>
    <mapper url="file:///E:\01_JAVA笔记资料\11_Project\demo\mybatis_study\src\main\java\com\lzf\mapper\DeptMapper.xml"/>
</mappers>

类型别名(typeAliases)

类型别名可为 Java 类型设置一个缩写名字。 它仅用于 XML 配置,意在降低冗余的全限定类名书写。

<!--设置实体类别名-->
<typeAliases>
    <typeAlias type="com.lzf.pojo.Dept" alias="dept"/>
</typeAliases>

在映射文件的resultType 返回值类型 和paramterType 上就可以使用别名了

<!--此处编写要执行的sql语句-->
<select id="selectAll" resultType="dept">
    select * from dept
</select>

当实体类多时一个个为实体类设置别名就比较麻烦,可以通过包扫描为实体类设置别名

<!--包设置实体类别名,默认别名为类的首字母小写
也可以自定义别名,在类上使用注解@Alias("dept")  一般不用
-->
<typeAliases>
    <package name="com.lzf.pojo"/>
</typeAliases>

属性(properties)

在之前的mybatis-config.xml文件中,数据源的配置信息,我们是直接写在配置文件里面的,这样的方式不易于修改,不合理。应该在外部定义一个文件,然后在mybatis-config.xml中引入。

在resources中创建文件jdbc.properties

jdbc_driver=com.mysql.jdbc.Driver
jdbc_url=jdbc:mysql://127.0.0.1:3306/mydb?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
jdbc_username=root
jdbc_password=123456

mybatis-config.xml中引入并使用

<!--引入外部文件-->
<properties resource="jdbc.properties"/>
<dataSource type="POOLED">
    <property name="driver" value="${jdbc_driver}"/>
    <!--mybatis_db:数据库名称-->
    <property name="url" value="${jdbc_url}"/>
    <!--连接mysql的用户名和密码-->
    <property name="username" value="${jdbc_username}"/>
    <property name="password" value="${jdbc_password}"/>
</dataSource>

2.2 XML映射文件(mapper.xml)

参数传递

单个基本数据类型

#{}中可以随便写,遵循见名知意

多个基本数据类型

方式1 arg*     arg0 arg1 arg2 数字是索引,0开始
方式2 param*   param1 param2 param3 数字是编号,1开始
方式3 @Param定义别名  推荐此方法,见名知意。

单个引用数据类型

#{}中写的使用对象的属性名

map集合数据类型

#{}写键的名字

多个引用数据类型

如果用@Param定义了别名,那么就不能使用arg*.属性名,但是可以使用param*.属性名和别名.属性名

CRUD

select

<!--根据id查询
    id:指定接口中的方法名
    resultType:该方法的返回值类型,
    如果返回的是集合,那应该设置为集合包含的类型,
    而不是集合本身的类型。
    parameterType:指定方法的参数类型。这个属性是可选的,
    因为 MyBatis 可以通过类型处理器(TypeHandler)推断出具体传入语句的参数
    -->
<select id="findById" parameterType="int" resultType="dept">
    select * from dept WHERE DEPTNO = #{deptno}
</select>

insert, update 和 delete

数据变更语句 insert,update 和 delete 的实现非常接近,增删改记得提交 事务(sqlSession.commit())

    <!--增加 parameterType可以不写-->
    <insert id="insert" parameterType="dept">
        insert into dept values(#{deptno},#{dname},#{loc})
    </insert>
    <!--根据ID修改 parameterType可以不写-->
    <update id="update" parameterType="dept">
        update dept set  DNAME = #{dname},LOC  = #{loc} where DEPTNO = #{deptno}
    </update>
    <!--根据ID删除 parameterType可以不写-->
    <delete id="delete" parameterType="int">
        delete from dept where DEPTNO = #{deptno}
    </delete>

模糊查询

使用concat()函数来连接参数和通配符。另外注意对于特殊字符,比如<,不能直接书写,应该使用字符实体替换。

public interface DeptMapper {
    /**
     * 根据name模糊查询
     * @param name 模糊查询的文字
     * @return Dept对象List集合
     */
    List<Dept>  findByName(String name);
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.lzf.mapper.DeptMapper">
    <select id="findByName" resultType="dept">
        select * from dept WHERE DNAME like concat('%',#{name},'%')
    </select>
</mapper>

注解自增回填

有时候完成添加后需要立刻获取刚刚自增的主键,由下一个操作来使用。MyBatis提供了支持,可以非常简单的获取。

/**
     * 添加一个Dept
     * @param dept 要添加的dept
     * @return
     */
int addDept(Dept dept);
<!-- 
useGeneratedKeys="true" 返回数据库帮我们生成的主键
keyProperty="deptno" 生成的主键值用我们dept对象那个属性存储
-->
<insert id="addDept" parameterType="dept" useGeneratedKeys="true" keyProperty="deptno">
    insert into dept values(null,#{dname},#{loc})
</insert>

resultMap

前面已经使用MyBatis完成了CRUD操作,但只是完成了对单个数据库表的操作。这肯定是远远不够的。

在实际开发中,经常会将来自多张表的数据在一个位置显示。这个时候就需要使用resultMap手动处理数据库查询字段和封装实体类属性之间的映射关系。

  1. 需求:根据编号查询员工信息及所在的部门信息

    实体类

public class Emp {
    private Integer empno;
    private String ename;
    private String job;
    private Integer mgr;
    private Date hiredate;
    private Double sal;
    private Double comm;
    private Integer deptno;
    // 组合一个Dept对象作为自己的属性
    private Dept dept;
    //提供构造器、get,set
}

​ 接口

/**
     * 根据员工编号查询员工的所有信息并携带所在的部门信息
     * @param empno 要查询的员工编号
     * @return Emp对象,组合了Dept对象作为属性,对部门信息进行存储
     */
Emp findEmpJoinDeptByEmpno(int empno);

​ Empmapper.xml

<resultMap id="empJoinDept" type="emp">
    <!--设置emp本身的八个属性的映射关系-->
    <id property="empno" column="empno"/>
    <result property="ename" column="ename"/>
    <result property="job" column="job"/>
    <result property="mgr" column="mgr"/>
    <result property="hiredate" column="hiredate"/>
    <result property="sal" column="sal"/>
    <result property="comm" column="comm"/>
    <result property="deptno" column="deptno"/>
    <!--
        association 处理一对一
        封装一对一信息关系的标签
        property  emp类的属性名
        javaType  用哪个类的对象给属性赋值
        -->
    <association property="dept" javaType="dept">
        <id property="deptno" column="deptno"/>
        <result property="dname" column="dname"/>
        <result property="loc" column="loc"/>
    </association>
</resultMap>
<select id="findEmpJoinDeptByEmpno" resultMap="empJoinDept">
    select * from emp e
    left join dept d on e.deptno = d.deptno
    where EMPNO = #{empno}
</select>
  1. 需求:根据部门号查询部门信息及该部门的所有员工信息

    实体类

    public class Dept {
        private Integer deptno;
        private String dname;
        private String loc;
        // 组合一个Emp的List集合作为属性
        List<Emp> emps;
        //提供构造器、get,set
    }    
    

    接口

    /**
         * 根据部门编号查询部门信息及该部分的所有员工信息
         * @param deptno 要查询的部门编号
         * @return Dept对象,内部组合了一个Emp的List属性用于封装部门的所有员工信息
         */
    Dept findDeptJoinEmpsByDeptno(int deptno);
    

    DeptMapper.xml

    <resultMap id="deptJoinEmps" type="dept">
        <id property="deptno" column="deptno"/>
        <result property="dname" column="dname"/>
        <result property="loc" column="loc"/>
        <!--处理一对多关系的标签-->
        <collection property="emps" ofType="emp">
            <id property="empno" column="empno"/>
            <result property="ename" column="ename"/>
            <result property="job" column="jbo"/>
            <result property="mgr" column="mgr"/>
            <result property="hiredate" column="hiredate"/>
            <result property="sal" column="sal"/>
            <result property="comm" column="comm"/>
            <result property="deptno" column="deptno"/>
        </collection>
    </resultMap>
    
    <select id="findDeptJoinEmpsByDeptno" resultMap="deptJoinEmps">
        SELECT * FROM
        dept d LEFT JOIN emp e ON d.DEPTNO = e.DEPTNO
        WHERE d.DEPTNO = 30
    </select>
    

三、动态SQL

if

接口

//条件查询
List<Emp> findByCondition(Emp emp);

映射文件

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

where

用于处理where关键字和and

<select id="findEmpByCondition" resultType="emp">
    select * from emp
    <where>
        <if test="empno != null">
            and empno= #{empno}
        </if>
        <if test="ename != null and ename != ''">
            and ename= #{ename}
        </if>
        <if test="job != null and job != ''">
            and job= #{job}
        </if>
        <if test="mgr != null ">
            and mgr= #{mgr}
        </if>
        <if test="hiredate != null ">
            and hiredate= #{hiredate}
        </if>
        <if test="sal != null">
            and sal= #{sal}
        </if>
        <if test="comm != null ">
            and comm =#{comm}
        </if>
        <if test="deptno != null ">
            and deptno= #{deptno}
        </if>
    </where>
</select>

choose

前面的when条件成立 后面的 when就不再判断了

<select id="findEmpByCondition2" resultType="emp">
    select * from emp
    <where>
        <choose>
            <when test="empno != null">
                and empno= #{empno}
            </when>
            <when test="ename != null and ename != ''">
                and ename= #{ename}
            </when>
            <when test="job != null and job != ''">
                and job= #{job}
            </when>
            <when test="mgr != null ">
                and mgr= #{mgr}
            </when>
            <when test="hiredate != null ">
                and hiredate= #{hiredate}
            </when>
            <when test="sal != null">
                and sal= #{sal}
            </when>
            <when test="comm != null ">
                and comm =#{comm}
            </when>
            <when test="deptno != null ">
                and deptno= #{deptno}
            </when>
        </choose>
    </where>
</select>

set

接口

//根据条件更新
int updateEmpByCondtion(Emp emp);

映射文件

<update id="updateEmpByCondtion">
    update emp
    <set>
        <if test="ename != null and ename != '' ">
            , ename =#{ename}
        </if>
        <if test="job != null and ename != '' ">
            , job =#{job}
        </if>
        <if test="mgr != null ">
            , mgr =#{mgr}
        </if>
        <if test="hiredate != null ">
            , hiredate =#{hiredate}
        </if>
        <if test="sal != null ">
            , sal =#{sal}
        </if>
        <if test="comm != null ">
            , comm =#{comm}
        </if>
        <if test="deptno != null ">
            , deptno =#{deptno}
        </if>
    </set>
    where empno =#{empno}
</update>

trim

Trim 标签处理 set

<update id="updateEmpByCondition2" >
    update emp
    <!--prefix 要增加什么前缀
    prefixOverrides 要去除什么前缀
    suffix 要增加什么后缀
    suffixOverrides 要去除什么后缀
    set 是trim的一种特殊情况
    -->
    <trim prefix="set"  suffixOverrides="," >
        <if test="ename != null and ename != ''">
            ename= #{ename},
        </if>
        <if test="job != null and job != ''">
            job= #{job},
        </if>
        <if test="mgr != null ">
            mgr= #{mgr},
        </if>
        <if test="hiredate != null ">
            hiredate= #{hiredate},
        </if>
        <if test="sal != null">
            sal= #{sal},
        </if>
        <if test="comm != null ">
            comm =#{comm},
        </if>
        <if test="deptno != null ">
            deptno= #{deptno},
        </if>
    </trim>
    where  empno = #{empno}
</update>

Trim标签 处理where

<select id="findEmpByCondition" resultType="emp">
    select * from emp
    <trim prefix="where" prefixOverrides="and">
        <if test="empno != null">
            and empno= #{empno}
        </if>
        <if test="ename != null and ename != ''">
            and ename= #{ename}
        </if>
        <if test="job != null and job != ''">
            and job= #{job}
        </if>
        <if test="mgr != null ">
            and mgr= #{mgr}
        </if>
        <if test="hiredate != null ">
            and hiredate= #{hiredate}
        </if>
        <if test="sal != null">
            and sal= #{sal}
        </if>
        <if test="comm != null ">
            and comm =#{comm}
        </if>
        <if test="deptno != null ">
            and deptno= #{deptno}
        </if>
    </trim>
</select>

bind

一般用于处理模糊查询的模板

<select id= "findEmpByEname" resultType = "emp">
    <bind name = "likePatten" value = " '%' + param1 + '%' "
     select * from emp where ename like #{likePatten}
</select>

sql

定义公共的SQL,以便复用

<sql id="empColumn">empno,ename,job,mgr,hiredate,sal,comm,deptno</sql>
<sql id="baseSelect">select <include refid="empColumn"></include> from emp</sql>

foreach

<!--List<Emp> findByEmpnos1(int[] empnos);
 collection=""  遍历的集合或者是数组
                 参数是数组,collection中名字指定为array
                 参数是List集合,collection中名字指定为list
 separator=""   多个元素取出的时候 用什么文字分隔
 open=""        以什么开头
 close=""       以什么结尾
 item=""        中间变量名
 for(Person per:PersonList)
 -->
<select id="findByEmpnos1" resultType="emp">
    select * from emp  where empno in
    <foreach collection="array" separator="," open="(" close=")" item="deptno">
        #{deptno}
    </foreach>
</select>
<!-- List<Emp> findByEmpnos2(List<Integer> empnos);-->
<select id="findByEmpnos2" resultType="emp">
    select * from emp  where empno in
    <foreach collection="list" separator="," open="(" close=")" item="deptno">
        #{deptno}
    </foreach>
</select>

四、缓存【了解】

一般不用MyBatis的缓存,用第三方缓存。

一级缓存

一级存储是SqlSession上的缓存,默认开启,是一种内存型缓存,不要求实体类对象实现Serializable接口。

请添加图片描述

测试代码

@Test
public void testFindDeptByDetpno()   {
    EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);
    Emp emp = mapper.findByEmpno(7521);
    System.out.println(emp);
    // 中间发生了增删改或者是调用了SqlSession调用了commit,会自动清空缓存
    sqlSession.commit();// 增删改的时候调用
    EmpMapper mapper2 = sqlSession.getMapper(EmpMapper.class);
    Emp emp2 = mapper2.findByEmpno(7521);
    System.out.println(emp2);
    System.out.println(emp==emp2);
    System.out.println(mapper==mapper2);
}

二级缓存

级缓存是以namespace为标记的缓存,可以是由一个SqlSessionFactory创建的SqlSession之间共享缓存数据。默认并不开启。下面的代码中创建了两个SqlSession,执行相同的SQL语句,尝试让第二个SqlSession使用第一个SqlSession查询后缓存的数据。要求实体类必须实现序列化接口

请添加图片描述

开启二级缓存

  • 全局开关:在sqlMapConfig.xml文件中的 settings 标签配置开启二级缓存
<settings>
    <!--cacheEnabled的默认值就是true,所以这步的设置可以省略-->
    <setting name="cacheEnabled" value="true"/>

</settings>
  • 分开关:在要开启二级缓存的mapper文件中开启缓存
<mapper namespace="com.msb.mapper.EmployeeMapper">
    <cache/>
</mapper>

五、注解开发【了解】

简单的且稳定不改动的SQL语句可以用注解

使用注解没有实现Java代码和SQL语句的解耦

无法实现SQL语句的动态拼接

进行多表的查询时定制ResultMap比较麻烦

public interface DeptMapper {
    @Select("select * from dept where deptno =#{deptno}")
    Dept findByDeptno(int deptno);
    @Update("update dept set dname =#{dname}, loc =#{loc} where deptno =#{deptno}")
    int updateDept(Dept dept);
    @Insert("insert into dept values(DEFAULT,#{dname},#{loc})")
    int addDept(Dept dept);
    @Delete("delete from dept where deptno =#{deptno}")
    int removeDept(int deptno);
}

qlSession使用第一个SqlSession查询后缓存的数据。要求实体类必须实现序列化接口

[外链图片转存中…(img-n05jKS7E-1631097962432)]

开启二级缓存

  • 全局开关:在sqlMapConfig.xml文件中的 settings 标签配置开启二级缓存
<settings>
    <!--cacheEnabled的默认值就是true,所以这步的设置可以省略-->
    <setting name="cacheEnabled" value="true"/>

</settings>
  • 分开关:在要开启二级缓存的mapper文件中开启缓存
<mapper namespace="com.msb.mapper.EmployeeMapper">
    <cache/>
</mapper>

五、注解开发【了解】

简单的且稳定不改动的SQL语句可以用注解

使用注解没有实现Java代码和SQL语句的解耦

无法实现SQL语句的动态拼接

进行多表的查询时定制ResultMap比较麻烦

public interface DeptMapper {
    @Select("select * from dept where deptno =#{deptno}")
    Dept findByDeptno(int deptno);
    @Update("update dept set dname =#{dname}, loc =#{loc} where deptno =#{deptno}")
    int updateDept(Dept dept);
    @Insert("insert into dept values(DEFAULT,#{dname},#{loc})")
    int addDept(Dept dept);
    @Delete("delete from dept where deptno =#{deptno}")
    int removeDept(int deptno);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值