MyBatis 学习笔记
MyBatis 学习笔记
Mybatis官方参考网址:https://mybatis.org/mybatis-3/zh/
MyBatis 是一款持久层框架,用于简化 JDBC 开发。
将硬编码写道配置文件,繁琐操作自动完成。
免除了几乎所有的 JDBC 代码,以及设置参数和获取结果集的工作。
快速入门
已有数据库
1 | use mybatis |
maven配置依赖
先在maven添加依赖,根据情况添加
1 | <!-- mybatis 的依赖--> |
配置mybatis参数文件
在resources下创建mybatis-config.xml
文件,填好连接信息和映射文件路径
此文件写法可直接在mybatis官网寻找
1 | <?xml version="1.0" encoding="UTF-8" ?> |
配置mapper映射文件
在resources下创建UserMapper.xml
的映射文件,namespace需要自己设置,<select>
下 id 代表指令id, resultType指向对应的class
此文件写法可直接在mybatis官网寻找
1 | <?xml version="1.0" encoding="UTF-8" ?> |
执行
对应class类如下
1 | package com.pojo; |
主程序如下
1 | public static void main(String[] args) throws Exception { |
Mapper 代理开发
在resources下创建和接口同名、同路径的对应xml文件。
xml的namespace为接口类的位置,select id 为 接口中定义的函数。
修改mybatis-config.xml内sql映射文件路径。
调用如下
1 | public static void main(String[] args) throws Exception { |
编写流程
idea 有一个插件 MyBatisX ,方便开发
- 编写接口方法:Mapper 接口
- 编写SQL语句:SQL映射文件
- 执行方法,测试
在查询过程中,class类的名称和sql的字段名不一致,会导致封装没有值。
解决方法:
- 起别名:可以在sql语句中起别名,别名和class类中对应字段相同即可。
- 缺点:每次查询都要定义一次别名。
- 定义sql片段。 缺点:不灵活。
- resultMap(最常用)
起别名 如:
1 | <mapper namespace="com.mapper.BrandMapper"> |
定义sql 如:
1 | <sql id="brand_column"> |
resultMap 如:
1 | <resultMap id="brandResultMap" type="com.pojo.Brand"> |
参数占位符:
#{}:会将其替换成 ? ,防止SQL注入 。
${}:拼接sql,会存在SQL注入问题。
参数传递的时候使用 : #{}
表名或列名不固定时:¥{}
参数类型设置: parameterType = " " (可以省略)。如下:
1 | <select id="selectById" parameterType="int" resultMap="brandResultMap"> |
特殊字符的处理:
- 转义字符
- CDATA区:如下: idea 输入CD就会提示
1 | <!-- 小于号 --> |
多参数查询
在 BrandMapper
接口中定义多条件查询的方法。
而该功能有三个参数,我们就需要考虑定义接口时,参数应该如何定义。Mybatis针对多参数有多种实现
使用
@Param("参数名称")
标记每一个参数,在映射配置文件中就需要使用#{参数名称}
进行占位1
List<Brand> selectByCondition(int status, String companyName, String brandName);
将多个参数封装成一个 实体对象 ,将该实体对象作为接口的方法参数。该方式要求在映射配置文件的SQL中使用
#{内容}
时,里面的内容必须和实体类属性名保持一致。1
List<Brand> selectByCondition(Brand brand);
将多个参数封装到map集合中,将map集合作为接口的方法参数。该方式要求在映射配置文件的SQL中使用
#{内容}
时,里面的内容必须和map集合中键的名称一致。1
List<Brand> selectByCondition(Map map);
动态SQL
上述功能实现存在很大的问题。用户在输入条件时,肯定不会所有的条件都填写,这个时候我们的SQL语句就不能那样写的
例如用户只输入 当前状态 时,SQL语句就是
1 | select * from tb_brand where status = #{status} |
而用户如果只输入企业名称时,SQL语句就是
1 | select * from tb_brand where company_name like #{companName} |
而用户如果输入了 当前状态
和 企业名称
时,SQL语句又不一样
1 | select * from tb_brand where status = #{status} and company_name like #{companName} |
针对上述的需要,Mybatis对动态SQL有很强大的支撑:
if
choose (when, otherwise)
trim (where, set)
foreach
if 标签:条件判断
- test 属性:逻辑表达式
1
2
3
4
5
6
7
8
9
10
11
12
13
14<select id="selectByCondition" resultMap="brandResultMap">
select *
from tb_brand
where
<if test="status != null">
and status = #{status}
</if>
<if test="companyName != null and companyName != '' ">
and company_name like #{companyName}
</if>
<if test="brandName != null and brandName != '' ">
and brand_name like #{brandName}
</if>
</select>如上的这种SQL语句就会根据传递的参数值进行动态的拼接。如果此时status和companyName有值那么就会值拼接这两个条件。
where 标签
- 作用:
- 替换where关键字
- 会动态的去掉第一个条件前的 and
- 如果所有的参数没有值则不加where关键字
- 作用:
1 | <select id="selectByCondition" resultMap="brandResultMap"> |
注意:需要给每个条件前都加上 and 关键字。
单一查询
<choose> 相当于switch
1 | <select id="selectByConditionSingle" resultMap="brandResultMap"> |
Mybatis参数传递
Mybatis 接口方法中可以接收各种各样的参数,如下:
- 多个参数
- 单个参数:单个参数又可以是如下类型
- POJO 类型
- Map 集合类型
- Collection 集合类型
- List 集合类型
- Array 类型
- 其他类型
多个参数
如下面的代码,就是接收两个参数,而接收多个参数需要使用
@Param
注解,那么为什么要加该注解呢?这个问题要弄明白就必须来研究Mybatis
底层对于这些参数是如何处理的。
1 | User select(; String username, String password) |
1 | <select id="select" resultType="user"> |
我们在接口方法中定义多个参数,Mybatis 会将这些参数封装成 Map
集合对象,值就是参数值,而键在没有使用 @Param
注解时有以下命名规则:
以 arg 开头 :第一个参数就叫 arg0,第二个参数就叫 arg1,以此类推。如:
map.put("arg0",参数值1);
map.put("arg1",参数值2);
以 param 开头 : 第一个参数就叫 param1,第二个参数就叫 param2,依次类推。如:
map.put("param1",参数值1);
map.put("param2",参数值2);
==结论:以后接口参数是多个时,在每个参数上都使用 @Param
注解。这样代码的可读性更高。==
单个参数
POJO 类型
直接使用。要求
属性名
和参数占位符名称
一致Map 集合类型
直接使用。要求
map集合的键名
和参数占位符名称
一致Collection 集合类型
Mybatis 会将集合封装到 map 集合中,如下:
map.put("arg0",collection集合);
map.put("collection",collection集合;
==可以使用
@Param
注解替换map集合中默认的 arg 键名。==List 集合类型
Mybatis 会将集合封装到 map 集合中,如下:
map.put("arg0",list集合);
map.put("collection",list集合);
map.put("list",list集合);
==可以使用
@Param
注解替换map集合中默认的 arg 键名。==Array 类型
Mybatis 会将集合封装到 map 集合中,如下:
map.put("arg0",数组);
map.put("array",数组);
==可以使用
@Param
注解替换map集合中默认的 arg 键名。==其他类型
比如int类型,
参数占位符名称
叫什么都可以。尽量做到见名知意
注解开发
使用注解开发会比配置文件开发更加方便、
使用注解开发会比配置文件开发更加方便。如下就是使用注解进行开发
1 |
|
==注意:==
- 注解是用来替换映射配置文件方式配置的,所以使用了注解,就不需要再映射配置文件中书写对应的
statement
Mybatis 针对 CURD 操作都提供了对应的注解,已经做到见名知意。如下:
- 查询 :@Select
- 添加 :@Insert
- 修改 :@Update
- 删除 :@Delete