java学习笔记 -MyBatis
java学习笔记 -MyBatis
执笔MyBatis搭建
引入依赖
1 | <dependencies> |
MyBatis的核心配置文件
- 存放路径:
src/main/resources
1 |
|
创建Mapper接口
1 | public interface UserMapper { |
创建映射文件
Java概念 | 数据库概念 |
---|---|
类 | 表 |
属性 | 字段/列 |
对象 | 记录/行 |
- 表所对应的实体类的类名+Mapper.xml
- 存放的位置是
src/main/resources/mappers
目录下
1 |
|
通过junit测试功能
1 | public class UserMapperTest { |
- 此时需要手动提交事务,如果要自动提交事务,则在获取sqlSession对象时,使用
SqlSession sqlSession = sqlSessionFactory.openSession(true);
,传入一个Boolean类型的参数,值为true,这样就可以自动提交
加入log4j功能
引入依赖
1
2
3
4
5
6<!-- log4j日志 -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>加入配置文件
- log4j的配置文件名为log4j.xml,存放的位置是src/main/resources目录下
- 日志的级别:FATAL(致命)>ERROR(错误)>WARN(警告)>INFO(信息)>DEBUG(调试) 从左到右打印的内容越来越详细
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<appender name="STDOUT" class="org.apache.log4j.ConsoleAppender">
<param name="Encoding" value="UTF-8" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%-5p %d{MM-dd HH:mm:ss,SSS} %m (%F:%L) \n" />
</layout>
</appender>
<logger name="java.sql">
<level value="debug" />
</logger>
<logger name="org.apache.ibatis">
<level value="info" />
</logger>
<root>
<level value="debug" />
<appender-ref ref="STDOUT" />
</root>
</log4j:configuration>
默认的类型别名
增删改查
添加
1 | <!--int insertUser();--> |
删除
1 | <!--int deleteUser();--> |
修改
1 | <!--int updateUser();--> |
查询一个实体类对象
1 | <!--User getUserById();--> |
查询集合
1 | <!--List<User> getUserList();--> |
- 注:
1 | 查询的标签select必须设置属性resultType或resultMap,用于设置实体类和数据库表的映射关系 |
获取参数值方式
- MyBatis获取参数值的两种方式:${}和#{}
- ${}的本质就是字符串拼接,#{}的本质就是占位符赋值
- ${}使用字符串拼接的方式拼接sql,若为字符串类型或日期类型的字段进行赋值时,需要手动加单引号;但是#{}使用占位符赋值的方式拼接sql,此时为字符串类型或日期类型的字段进行赋值时,可以自动添加单引号
单个字面量类型的参数
- ${} 使用需要手动加单引号
1 | <!--User getUserByUsername(String username);--> |
1 | <!--User getUserByUsername(String username);--> |
多个字面量类型的参数
- 以arg0,arg1…为键,以参数为值;
- 以param1,param2…为键,以参数为值;
1 | <!--User login(String username, String password);--> |
map集合类型的参数
1 | <!-- User checkLogin(Map<String,Object> map);--> |
1 | public void testCheckLogin(){ |
实体类类型的参数
1 | <!--void insertUser(User user);--> |
使用@Param标识参数(主要使用)
1 | <!--User loginByParam(@Param("username") String username,@Param("password") String password);--> |
查询功能
查询一个实体类
1 | /** |
1 | <!--User getUserById(@Param("id") int id);--> |
查询一个List集合
1 | /** * 查询所有用户信息 * @return */ |
1 | <!--List<User> getUserList();--> |
查询单个数据
1 | /** |
1 | <!--int getCount();--> |
查询一条数据为map集合
1 | /** |
1 | <!--Map<String, Object> getUserToMap(@Param("id") int id);--> |
查询多条数据为map集合
方法一
1 | /** |
1 | <!--Map<String, Object> getAllUserToMap();--> |
方法二
1 | /** |
1 | <!--Map<String, Object> getAllUserToMap();--> |
特殊SQL的执行
模糊查询
1 | <!--List<User> getUserByLike(@Param("username") String username);--> |
批量删除
- 只能使用${},如果使用#{},则解析后的sql语句为
delete from t_user where id in ('1,2,3')
,这样是将1,2,3
看做是一个整体,只有id为1,2,3
的数据会被删除。正确的语句应该是delete from t_user where id in (1,2,3)
,或者delete from t_user where id in ('1','2','3')
1 | <!--int deleteMore(@Param("ids") String ids);--> |
动态设置表名
- 只能使用${},因为表名不能加单引号
1 | <!--List<User> getUserByTable(@Param("tableName") String tableName);--> |
添加功能获取自增的主键
1 | <!--void insertUser(User user);--> |
1 |
|
自定义映射
- 若字段名和实体类中的属性名不一致,则可以通过resultMap设置自定义映射,即使字段名和属性名一致的属性也要映射,也就是全部属性都要列出来
1 | <!--List<Emp> getAllEmp();--> |
- 若字段名和实体类中的属性名不一致,但是字段名符合数据库的规则(使用_),实体类中的属性名符合Java的规则(使用驼峰)。此时也可通过以下两种方式处理字段名和实体类中的属性的映射关系
1 | 1. 可以通过为字段起别名的方式,保证和实体类中的属性名保持一致 |
- 可以在MyBatis的核心配置文件中的
setting
标签中,设置一个全局配置信息mapUnderscoreToCamelCase,可以在查询表中数据时,自动将_类型的字段名转换为驼峰,例如:字段名user_name,设置了mapUnderscoreToCamelCase,此时字段名就会转换为userName。核心配置文件详解1
2
3<settings>
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
## 多对一映射
### 级联属性赋值
```xml
<!--处理多对一映射关系方式一:级联属性赋值-->
<resultMap id="empAndDeptResultMaoOne" type="Emp">
<id property="eid" column="eid"></id>
<result property="empName" column="emp_name"></result>
<result property="age" column="age"></result>
<result property="sex" column="sex"></result>
<result property="email" column="email"></result>
<result property="dept.did" column="did"></result>
<result property="dept.deptName" column="dept_name"></result>
</resultMap>
assication标签
1 | <!--处理多对一映射关系方式二:采用association标签--> |
分步查询
- 查询员工信息
1 | /** |
1 | <!--EmpMapper.xml文件 --> |
- 查询部门信息
1 | /** |
1 | <!-- DeptMapper.xml 文件 --> |
一对多映射
connection标签
1 | <resultMap id="DeptAndEmpResultMap" type="Dept"> |
分步查询
- 查询部门信息
1 | /** DpetMapper |
1 | <resultMap id="DeptAndEmpByStepResultMap" type="Dept"> |
- 查询员工信息
1 | /** EmpMapper |
1 | <!--List<Emp> getDeptAndEmpBySeptTwo(@Param("did") Integer did);--> |
延迟加载
1 | <!--设置MyBatis的全局配置--> |
- 开启后,需要用到查询dept的时候才会调用相应的SQL语句
1 |
|
- 关闭延迟加载,两条SQL语句都运行了
- 开启延迟加载,只运行获取emp的SQL语句
- 控制加载效果
1 | <resultMap id="empAndDeptBySeptResultMap" type="Emp"> |
动态SQL
if
- 根据标签中test属性所对应的表达式决定是否需要将内容拼接到SQL中
1 | <!--List<Emp> getEmpByCondition(Emp emp);--> |
where
- 当where标签中有内容时,会自动生成where关键字,并且将内容前的and或者or去除
- 当where标签中没有内容时,where标签不生效
- 注意:where标签不能将内容后的and或者or去除
trim
1 | <!-- |
choose、when、otherwise
- 类似于switch … case .. default
1 | <!--List<Emp> getEmpByChoose(Emp emp);--> |
foreach
1 | <!-- |
SQL片段
- sql片段,可以记录一段公共sql片段,在使用的地方通过include标签进行引入
- 声明sql片段:
<sql>
标签
1 | <sql id="empColumns">eid,emp_name,age,sex,email</sql> |
- 引用sql片段:
<include>
标签
1 | <!--List<Emp> getEmpByCondition(Emp emp);--> |
MyBatis缓存查询的顺序
- 先查询二级缓存,因为二级缓存中可能会有其他程序已经查出来的数据,可以拿来直接使用
- 如果二级缓存没有命中,再查询一级缓存
- 如果一级缓存也没有命中,则查询数据库
- SqlSession关闭之后,一级缓存中的数据会写入二级缓存
评论
匿名评论隐私政策
✅ 你无需删除空行,直接评论以获取最佳展示效果