MyBatis的学习
MyBatis的学习
JinMyBatis特性
- MyBatis 是支持定制化 SQL、存储过程以及高级映射的优秀的持久层框架
- MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集
- MyBatis可以使用简单的XML或注解用于配置和原始映射,将接口和Java的POJO(Plain Old JavaObjects,普通的Java对象)映射成数据库中的记录
- MyBatis 是一个 半自动的ORM(Object Relation Mapping)框架
搭建使用 MyBatis
导入依赖
在 maven 项目里导入 MyBatis 和 mysql
<!-- 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>8.0.13</version>
</dependency>
创建全局配置文件
在项目 src/main/resources
目录下创建 mybatis 配置文件,习惯上命名为 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>
<settings>
<!--设置全局配置,将字段名的下划线自动映射为驼峰 -->
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
<!--
environments表示配置Mybatis的开发环境,
可以配置多个环境,在众多具体环境中,使用default属性指定实际运行时使用的环境。
default属性的取值是environment标签的id属性的值。
-->
<environments default="development">
<!-- environment表示配置Mybatis的一个具体的环境 -->
<environment id="development">
<!-- Mybatis的内置的事务管理器 -->
<transactionManager type="JDBC"/>
<!-- 配置数据源 -->
<dataSource type="POOLED">
<!-- 建立数据库连接的具体信息 -->
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis-example"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<mappers>
<!-- Mapper注册:指定Mybatis映射文件的具体位置 -->
<!-- mapper标签:配置一个具体的Mapper映射文件 -->
<!-- resource属性:指定Mapper映射文件的实际存储位置,
这里需要使用一个以类路径根目录为基准的相对路径 -->
<!-- 对Maven工程的目录结构来说,
resources目录下的内容会直接放入类路径,
所以这里我们可以以resources目录为基准 -->
<mapper resource="mappers/EmployeeMapper.xml"/>
</mappers>
</configuration>
创建映射配置文件
相关概念:ORM(Object Relationship Mapping)对象关系映射
对象:Java的实体类对象
关系:关系型数据库
映射:二者之间的对应关系
java 类 -> 数据库表
java 属性 -> 字段/列
java 对象 -> 记录/行
创建数据库表和 java 类
CREATE DATABASE `mybatis-example`;
USE `mybatis-example`;
CREATE TABLE `t_emp`(
emp_id INT AUTO_INCREMENT,
emp_name CHAR(100),
emp_salary DOUBLE(10,5),
PRIMARY KEY(emp_id)
);
INSERT INTO `t_emp`(emp_name,emp_salary) VALUES("tom",200.33);
INSERT INTO `t_emp`(emp_name,emp_salary) VALUES("jerry",666.66);
INSERT INTO `t_emp`(emp_name,emp_salary) VALUES("andy",777.77);
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Employee {
private Integer empId;
private String empName;
private Double empSalary;
}
创建 mapper 接口
MyBatis中的mapper接口相当于以前的dao。但是区别在于,mapper仅仅是接口,我们不需要 提供实现类
public interface EmployeeMapper {
// 查询用户
Employee selectEmployee(Integer empId);
}
创建对应的映射文件
映射文件的命名规则: 表所对应的实体类的类名+Mapper.xml
例如:表t_user,映射的实体类为User,所对应的映射文件为UserMapper.xml
因此一个映射文件对应一个实体类,对应一张表的操作
MyBatis映射文件用于编写SQL,访问以及操作表中的数据
MyBatis映射文件存放的位置是``src/main/resources/mappers`目录下
MyBatis中可以面向接口操作数据,要保证两个一致:
mapper接口的全类名和映射文件的命名空间(namespace)保持一致
mapper接口中方法的方法名和映射文件中编写SQL的标签的id属性保持一致
加入配置文件 EmployeeMapper.xml
<?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属性:在Mybatis全局范围内找到一个具体的Mapper配置 -->
<!-- 引入接口后,为了方便通过接口全类名来找到Mapper配置文件,
所以通常将namespace属性设置为接口全类名 -->
<mapper namespace="com.example.mybatis.dao.EmployeeMapper">
<!-- 编写具体的SQL语句,使用id属性唯一的标记一条SQL语句 -->
<!-- resultType属性:指定封装查询结果的Java实体类的全类名 -->
<select id="selectEmployee" resultType="com.example.mybatis.entity.Employee">
<!-- Mybatis负责把SQL语句中的#{}部分替换成 “?” 占位符
在#{}内部还是要声明一个见名知意的名称 -->
select * from t_emp where emp_id=#{empId}
</select>
</mapper>
测试功能
使用 junit 测试
@Test
public void test1() throws IOException {
// 获取核心配置文件的输入流
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
// 获取 sql SqlSessionFactoryBuilder 对象
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
// 获取 SqlSessionFactory 对象
SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(is);
// 获取sql的会话对象SqlSession,是mybatis提供操作数据库的对象
SqlSession sqlSession = sqlSessionFactory.openSession();
// 获取UserMapper的代理实现对象
EmployeeMapper mapper = sqlSession.getMapper(EmployeeMapper.class);
// 调用 mapper接口中的方法,实现查询用户功能
Employee employee = mapper.selectEmployee(1);
sqlSession.commit();
System.out.println(employee);
sqlSession.close();
}
优化使用
加入日志功能
在Mybatis工作过程中,通过打印日志的方式,将要执行的SQL语句打印出来
<!-- 日志 -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>
加入配置日志文件 logback.xml,与 mybatis 全局配置文件同路径
<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="true">
<!-- 指定日志输出的位置,ConsoleAppender表示输出到控制台 -->
<appender name="STDOUT"
class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<!-- 日志输出的格式 -->
<!-- 按照顺序分别是:时间、日志级别、线程名称、打印日志的类、日志主体内容、换行 -->
<pattern>[%d{HH:mm:ss.SSS}] [%-5level] [%thread] [%logger] [%msg]%n</pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
<!-- 设置全局日志级别。日志级别按顺序分别是:TRACE、DEBUG、INFO、WARN、ERROR -->
<!-- 指定任何一个日志级别都只打印当前级别和后面级别的日志。 -->
<root level="INFO">
<!-- 指定打印日志的appender,这里通过“STDOUT”引用了前面配置的appender -->
<appender-ref ref="STDOUT" />
</root>
<!-- 根据特殊需求指定局部日志级别 -->
<logger name="com.example.mybatis" level="DEBUG" />
</configuration>
测试代码使用
在类上加上 @Slf4j 注解
使用logger对象打印数据
log.info(result.toString());
外部文件配置数据库连接
新建 jdbc.properties
jdbc.dev.driver=com.mysql.jdbc.Driver
jdbc.dev.url=jdbc:mysql://localhost:3306/mybatis-example
jdbc.dev.username=root
jdbc.dev.password=123456
jdbc.test.driver=com.mysql.jdbc.Driver
jdbc.test.url=jdbc:mysql://localhost:3306/mybatis-example
jdbc.test.username=root
jdbc.test.password=123456
jdbc.product.driver=com.mysql.jdbc.Driver
jdbc.product.url=jdbc:mysql://localhost:3306/mybatis-example
jdbc.product.username=root
jdbc.product.password=123456
在 mybatis 全局配置文件引入 jdbc.properties
<properties resource="jdbc.properties"/>
读取外部文件配置的值
使用${key}格式引用属性文件中的键
<dataSource type="POOLED">
<!-- 建立数据库连接的具体信息(引用了外部属性文件中的数据) -->
<property name="driver" value="${jdbc.dev.driver}"/>
<property name="url" value="${jdbc.dev.url}"/>
<property name="username" value="${jdbc.dev.username}"/>
<property name="password" value="${jdbc.dev.password}"/>
</dataSource>
添加测试 SqlSession
SqlSession:代表Java程序和数据库之间的会话。(HttpSession是Java程序和浏览器之间的 会话)
在测试类添加 SqlSession 方便测试
private SqlSession session;
// junit会在每一个@Test方法前执行@Before方法
@Before
public void init() throws IOException {
session = new SqlSessionFactoryBuilder()
.build(
Resources.getResourceAsStream("mybatis-config.xml"))
.openSession();
}
// junit会在每一个@Test方法后执行@After方法
@After
public void clear() {
session.commit();
session.close();
}
再次测试
@Slf4j
public class myBatisTest {
private SqlSession session;
// junit会在每一个@Test方法前执行@Before方法
@Before
public void init() throws IOException {
session = new SqlSessionFactoryBuilder()
.build(
Resources.getResourceAsStream("mybatis-config.xml"))
.openSession();
}
// junit会在每一个@Test方法后执行@After方法
@After
public void clear() {
session.commit();
session.close();
}
@Test
public void test(){
// 1.根据EmployeeMapper接口的Class对象获取Mapper接口类型的对象
EmployeeMapper employeeMapper = session.getMapper(EmployeeMapper.class);
// 2.调用EmployeeMapper接口的方法完成对数据库的操作
Employee emp = employeeMapper.selectEmployee(1);
// 3.打印查询结果
if (emp != null)
log.info(emp.toString());
}
}
基本用法
sql 参数
MyBatis获取参数值的两种方式:${}
和 #{}
${}
的本质就是字符串拼接,若为字符串类型或日期类型的字段进行赋值时,需要手动加单引号
#{}
的本质就是占位符赋值 ,字符串或日期会自动生成单引号
@Param标识参数
@Param注解标识 mapper 接口中的方法参数
此时,会将这些参数放在map集合中,以 @Param 注解的 value 属性值为键,以参数为值;
以 param1,param2…为键,以参数为值;
只需要通过
${}
和#{}
访问map集合的键就可以获取相对应的值
代码举例
查询一个用户
// mapper接口
User getUserById(@Param("id") int id);
<!--User getUserById(@Param("id") int id);-->
<select id="getUserById" resultType="User">
select * from t_user where id = #{id}
</select>
查询一条数据为map集合
Map<String, Object> getUserToMap(@Param("id") int id);
<select id="getUserToMap" resultType="map">
select * from t_user where id = #{id}
</select>
特殊 sql 执行
模糊查询
List<User> testMohu(@Param("mohu") String mohu);
<!--List<User> testMohu(@Param("mohu") String mohu);-->
<select id="testMohu" resultType="User">
<!--select * from t_user where username like '%${mohu}%'-->
<!--select * from t_user where username like concat('%',#{mohu},'%')-->
select * from t_user where username like "%"#{mohu}"%"
</select>
批量删除
int deleteMore(@Param("ids") String ids);
<!--int deleteMore(@Param("ids") String ids);-->
<delete id="deleteMore">
delete from t_user where id in (${ids})
</delete>
动态设置表名
List<User> getAllUser(@Param("tableName") String tableName);
<!--List<User> getAllUser(@Param("tableName") String tableName);-->
<select id="getAllUser" resultType="User">
select * from ${tableName}
</select>
添加功能获取自增的主键
int insertUser(User user);
<!--int insertUser(User user);-->
<insert id="insertUser" useGeneratedKeys="true" keyProperty="id">
insert into t_user values(null,#{username},#{password},#{age},#{sex})
</insert>
- useGeneratedKeys:设置使用自增的主键
- keyProperty:因为增删改有统一的返回值是受影响的行数,因此将获取的自增的主键放在传输的参数 user 对象的某个属性中
自定义映射
resultMap
若字段名和实体类中的属性名不一致,则可以通过resultMap设置自定义映射
属性:
- id:表示自定义映射的唯一标识
- type:查询的数据要映射的实体类的类型
子标签:
- id:设置主键的映射关系
- result:设置普通字段的映射关系
- association:设置多对一的映射关系
- collection:设置一对多的映射关系
子标签属性:
- property:设置映射关系中实体类中的属性名
- column:设置映射关系中表中的字段名
例如数据库字段名风格为_下划线,java 实体类使用驼峰:user_name -> userName
mapper 映射文件
<resultMap id="UserResMap" type="org.example.pojo.User">
<id property="id" column="id" />
<result property="userName" column="user_name" />
</resultMap>
<select id="getUserById" resultMap="UserResMap" >
select id,user_name from t_user where id = #{id}
</select>
可以在MyBatis的核心配置文件中设置一个全局配置信息mapUnderscoreToCamelCase,可以在查询表中数据时,自动将_类型的字段名转换为驼峰
<setting name="mapUnderscoreToCamelCase" value="true"/>
多对一映射处理
使用场景:例如,有两张表,一张员工表,一张员工部门表,查询员工信息时,也查询该员工所对应的部门
java 实体类
@Data
public class Employee {
private Integer empId;
private String empName;
private Double empSalary;
private Dept dept;
}
// ----
@Data
public class Dept {
private int did;
private String dName;
}
级联方式处理映射关系
<resultMap id="EmpAndEept" type="org.example.pojo.Employee">
<id property="empId" column="emp_id"/>
<result property="empName" column="emp_name"/>
<result property="empSalary" column="emp_salary"/>
<result property="dept.did" column="did" />
<result property="dept.dName" column="d_name"/>
</resultMap>
<!--Employee getEmpAndEept(@Param("id") int id);-->
<select id="getEmpAndEept" resultMap="EmpAndEept">
select emp.*,dept.* from t_emp emp left join t_dept dept on emp.did = dept.did where emp.emp_id = #{id}
</select>
使用association处理映射关系
<resultMap id="EmpAndEept" type="org.example.pojo.Employee">
<id property="empId" column="emp_id"/>
<result property="empName" column="emp_name"/>
<result property="empSalary" column="emp_salary"/>
<association property="dept" javaType="org.example.pojo.Dept">
<id property="did" column="did"/>
<result property="dName" column="d_name"/>
</association>
</resultMap>
<!--Employee getEmpAndEept(@Param("id") int id);-->
<select id="getEmpAndEept" resultMap="EmpAndEept">
select emp.*,dept.* from t_emp emp left join t_dept dept on emp.did = dept.did where emp.emp_id = #{id}
</select>
分步查询
第一步:查询员工信息
Employee getEmpByIdOne(@Param("id") int id);
第二步:查询部门信息
Dept getDeptByIdTwo(@Param("did") int did);
第一步 mapper 映射
<!-- 分步查询 -->
<resultMap id="EmpAndEeptByStep" type="org.example.pojo.Employee">
<id property="empId" column="emp_id"/>
<result property="empName" column="emp_name"/>
<result property="empSalary" column="emp_salary"/>
<association property="dept" select="org.example.mappers.DeptMapper.getDeptByIdTwo" column="did"/>
</resultMap>
<!-- Employee getEmpByIdOne(@Param("id") int id);-->
<select id="getEmpByIdOne" resultMap="EmpAndEeptByStep">
select * from t_emp where emp_id = #{id}
</select>
association 标签属性
- select:设置分步查询,查询某个属性的值的sql的标识(namespace.sqlId)
- column:将sql以及查询结果中的某个字段设置为分步查询的条件
第二步 mapper 映射
<resultMap id="DeptMap" type="org.example.pojo.Dept">
<id property="did" column="did"/>
<result property="dName" column="d_name"/>
</resultMap>
// 上面 resultMap 可开转驼峰配置省略
<!--Dept getDeptByIdTwo(@Param("did") int did);-->
<select id="getDeptByIdTwo" resultMap="DeptMap">
select * from t_dept where did = #{did}
</select>
总结:
- 第一步查询 association 标签来设置分步查询
- select 属性设置下一步的 mapper 接口
- column 属性设置将该步查询的字段作为下一步查询所需的条件
一对多映射处理
使用场景:例如,查询部门信息,及部门中的员工信息
collection 标签
实体类加入员工信息
private List<Employee> emps;
mapper 接口
Dept getDeptEmpByDid(@Param("did") int did);
mapper 映射
<resultMap id="deptMap" type="org.example.pojo.Dept">
<id property="did" column="did"/>
<result property="dName" column="d_name"/>
<collection property="emps" ofType="org.example.pojo.Employee">
<id property="empId" column="emp_id"/>
<result property="empName" column="emp_name"/>
<result property="empSalary" column="emp_salary"/>
</collection>
</resultMap>
<select id="getDeptEmpByDid" resultMap="deptMap">
select dept.*,emp.* from t_dept dept left join t_emp emp on dept.did = emp.did where dept.did = #{did}
</select>
ofType:设置 collection 标签所处理的集合属性中存储数据的类型
分步查询
第一步:查询部门信息
Dept getDeptByStep(@Param("did") int did);
第二步:根据部门id查询部门中的所有员工
List<Emp> getEmpListByDid(@Param("did") int did);
第一步:mapper 映射文件
<resultMap id="deptEmpStep" type="org.example.pojo.Dept">
<id property="did" column="did" />
<result property="dName" column="d_name" />
<collection
property="emp"
fetchType="eager"
select="org.example.mappers.EmployeeMapper.getEmpListByDid"
column="did"
/>
</resultMap>
<!--Dept getDeptByStep(@Param("did") int did);-->
<select id="getDeptByStep" resultMap="deptEmpStep">
select * from t_dept where did = #{did}
</select>
第二步:mapper 映射文件
<!--List<Emp> getEmpListByDid(@Param("did") int did);-->
<!-- 配置文件开启 mapUnderscoreToCamelCase了,使用resultType指定实体类即可 -->
<select id="getEmpListByDid" resultType="org.example.pojo.Employee">
select * from t_emp where did = #{did}
</select>
动态 sql
Mybatis框架的动态SQL技术是一种根据特定条件动态拼装SQL语句的功能,它存在的意义是为了
解决 拼接SQL语句字符串时的痛点问题
if 和 where
if 标签:i通过test属性的表达式判断,若结果为true,则标签中的内容会执行;反之不会执行
where 标签: 会自动去掉 “标签体内前面多余的 and/or ”
<!-- Employee selectByEmp(@Param("employee") Employee employee); -->
<select id="selectByEmp" resultType="org.example.pojo.Employee">
select * from t_emp
<where>
<if test="employee.empName != '' and employee.empName != null" >
emp_name = #{employee.empName}
</if>
<if test="employee.age != '' and employee.age != null">
and age = #{employee.age}
</if>
<if test="employee.empSalary > 0">
and emp_salary = #{employee.empSalary}
</if>
</where>
</select>
执行的 sql :select * from t_emp WHERE emp_name = ? and age = ? and emp_salary = ?
注:
- 在if标签的test属性中,可以访问实体类的属性,不可以访问数据库表的字段
- where 标签不能去掉条件最后多余的and
- 使用 @Param(“employee”) 注解 ,在标签使用属性需要
employee.属性
,不用可直接用属性,empName != ''
trim
trim 常用属性:
- prefix:在trim标签中的内容的前面添加某些内容
- prefixOverrides:在trim标签中的内容的前面去掉某些内容
- suffix:在trim标签中的内容的后面添加某些内容
- suffixOverrides:在trim标签中的内容的后面去掉某些内容
所以上面 where 也可以用 trim 代替
<!-- Employee selectByEmp(@Param("employee") Employee employee); -->
<select id="selectByEmp" resultType="org.example.pojo.Employee">
select * from t_emp
<trim prefix="where" suffixOverrides="and">
<if test="employee.empName != '' and employee.empName != null" >
emp_name = #{employee.empName}
</if>
<if test="employee.age != '' and employee.age != null">
and age = #{employee.age}
</if>
<if test="employee.empSalary > 0">
and emp_salary = #{employee.empSalary}
</if>
</trim>
</select>
set
对 update 语句的set子句进行定制,防止 null 值去更新表
例如根据 id 去更新名字和年龄
<!-- void UpdateEmp(Employee employee); -->
<update id="UpdateEmp">
update t_emp
<set>
<if test="empName != null and empName !=''">
emp_name = #{empName},
</if>
<if test="age != null and age !=''">
age = #{age},
</if>
</set>
where emp_id = #{empId}
</update>
执行的 sql :update t_emp SET emp_name = ?, age = ? where emp_id = ?
使用set标签动态管理set子句,并且动态去掉两端多余的逗号
choose、when、otherwise
choose、when、 otherwise相当于if…else if..else
<!-- List<Employee> selectEmp(Employee employee);-->
<select id="selectEmp" resultType="org.example.pojo.Employee">
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>
<otherwise>
1=1
</otherwise>
</choose>
</where>
执行 sql
名字不为空和 null :
select * from t_emp WHERE emp_name = ?
名字为空 ,年龄不为空:
select * from t_emp WHERE age = ?
名字和年龄为空:
select * from t_emp WHERE 1=1
总结:
- 在多个分支条件中,仅执行一个
- 从上到下依次执行条件判断
- 遇到的第一个满足条件的分支会被采纳
- 被采纳分支后面的分支都将不被考虑
- 如果所有的when分支都不满足,那么就执行otherwise分支
foreach
foreach 标签属性:
- collection:遍历的集合
- item:遍历集合的过程中能得到每一个具体对象
- separator:指定当foreach标签的标签体重复拼接字符串时,各个标签体字符串之间的分隔符
- open:整个循环把字符串拼好后,字符串整体的前面要添加的字符串
- close:整个循环把字符串拼好后,字符串整体的后面要添加的字符串
- index:List集合的索引值 / Map集合的key
<!-- int insertMoreEmp(@Param("employees") List<Employee> employees);-->
<insert id="insertMoreEmp">
insert into t_emp values
<foreach collection="employees" item="emp" separator=",">
(null,#{emp.empName},#{emp.empSalary},#{emp.age},null,null)
</foreach>
</insert>
执行的 sql :insert into t_emp values (null,?,?,?,null,null) ,(null,?,?,?,null,null) , (null,?,?,?,null,null)
SQL片段
sql片段,可以记录一段公共sql片段,在使用的地方通过 include 标签进行引入
<sql id="empColumns">
id,empName,empSalary,age,did
</sql>
<!--使用-->
select <include refid="empColumns"></include> from t_emp
缓存
查询的数据会被缓存,下次查询相同的数据,就会从缓存中直接获取,不会从数据库重新访问
MyBatis的一级缓存
一级缓存是SqlSession级别的,通过同一个SqlSession,查询的数据会被缓存
一级缓存失效的情况:
- 不是同一个SqlSession
- 同一个SqlSession但是查询条件发生了变化
- 同一个SqlSession两次查询期间执行了任何一次增删改操作
- 同一个SqlSession两次查询期间手动清空了缓存
- 同一个SqlSession两次查询期间提交了事务
MyBatis的二级缓存
二级缓存是SqlSessionFactory级别,通过同一个SqlSessionFactory创建的SqlSession查询的结果会被缓存
开启二级缓存:
加入 cache 标签
<mapper namespace="com.example.mybatis.EmployeeMapper">
<!-- 加入cache标签启用二级缓存功能 -->
<cache/>
实体类加入序列化
public class Employee implements Serializable {
MyBatis缓存查询的顺序
- 先查询二级缓存,因为二级缓存中可能会有其他程序已经查出来的数据,可以拿来直接使用
- 如果二级缓存没有命中,再查询一级缓存
- 如果一级缓存也没有命中,则查询数据库
- SqlSession 关闭之后,一级缓存中的数据会写入二级缓存
TDDO:整合EHCache
配置文件常用配置
开启别名
<!-- 配置类型的别名 -->
<typeAliases>
<!-- 声明了实体类所在的包之后,在Mapper配置文件中,只需要指定这个包下的简单类名即可 -->
<package name="com.example.mybatis.pojo"/>
</typeAliases>
例如:resultType=”Employee” 不用写全类名
<!-- Employee selectEmployeeById(Integer empId); -->
<select id="selectEmployeeById" resultType="Employee">
select * from t_emp where emp_id=#{empId}
</select>
mybatis 内置别名
配置 mapper 映射
指定 Mapper 映射文件时,只指定其所在的包,即指定所有的映射文件
<mappers>
<package name="com.example.mybatis.mapper"/>
</mappers>
要求:
- Mapper 接口和 Mapper 配置文件名称一致
- Mapper 配置文件所在目录的结构和 Mapper 接口所在包的目录结构一致
- 例如接口文件在 java/com/example/mybatis/mapper/,映射文件就要在 resources/com/example/mybatis/mapper/
下划线映射驼峰
全局配置文件加入
<settings>
<!--设置全局配置,将字段名的下划线自动映射为驼峰 -->
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>