MyBatis 是轻量级的对 JDBC
进行半封装
的 ORM
框架。
半封装
:相较Hibernate
的全封装
,需要手动编写sql
。
ORM
:(Object Relational Mapping,对象关系映射),将Java对象
和接口
映射成数据库中的记录。
本 wiki 基于
springboot 2.x
和mysql
编写。
核心配置
pom.xml
1 | <dependency> |
*Application.java
@MapperScan
用于扫描 DAO层interface
,并生成对应的代理对象。
1 | package tk.gushizone.mybatis; |
application.yml
1 | mybatis: |
接口式编程
Mybatis
提供了面向接口的编程方式,只需要 interface
+ sql
就可以使用面向对象的方式操作数据库。
*Mapper.java
多个入参时需要包装或使用
@Param
注解,因为java
编译后不会保存形参名。
1 | package tk.gushizone.mybatis.dao; |
*Mapper.xml
- mybatis 不允许重载,也不会校验参数,可以省略参数属性。
- 结果集列名会和entity映射,当表连接时避免同名冲突需要取别名(a.id, b.id 都是id,JDBC返回结果不会带前缀)。
<![CDATA[ ]]>
包裹的文本会被xml解析器
忽略,不需要转义。- mybatis 不允许在 sql 中使用
;
。
1 |
|
*pojo
1 | package tk.gushizone.mybatis.pojo; |
测试示例
1 | package tk.gushizone.mybatis.test; |
常用标签
mapper中支持的标签
功能 | 标签名称 |
---|---|
定义 SQL 语句 |
insert / delete / update / select |
配置 java对象 属性与查询 结果集 列名对应关系 |
resultMap |
遍历与逻辑 | foreach / if / choose |
格式化 | where / set / trim |
配置关联关系 | collection / association |
定义与引用常量 | sql / inxlude |
foreach
遍历集合
对于数array和list,index表示索引。
1 | <foreach collection="array" index="i" item="item"></foreach> |
对于map,index表示key。
1 | <foreach collection="map" index="key" item="item"></foreach> |
choose
和
带break的switch
用法相同,也可以起到if/else
作用。
1 | <choose> |
trim
动态添加和忽略前后缀
1 | <!-- 相当于set标签 --> |
1 | <!-- 相当与where标签 --> |
collection
一对多,主表对应子表。
mybatis 一对多,会自动去重
1 | package tk.gushizone.mybatis.pojo; |
1 | <resultMap id="CommandWithContentResultMap" type="tk.gushizone.mybatis.pojo.Command" > |
association
一对一/多对一,子表对应主表
1 | package tk.gushizone.mybatis.pojo; |
1 | <resultMap id="ContentWithCommandResultMap" type="tk.gushizone.mybatis.pojo.CommandContent" > |
sql
/ include
定义常量与引用常量
1 | <sql id="Base_Column_List"> |
常用属性
属性 | 说明 |
---|---|
parameterType |
接受参数映射,接受 java类型 ,一般为 参数类型 或 java.utl.Map 。 |
parameterMap |
接受参数映射,可以通过 parameterMap标签 配置。 官方不推荐使用。 |
resultType |
接受查询结果映射,接受 java类型 ,一般为 返回值类型 或 java.utl.Map 。 |
resultMap |
接受查询结果映射,可以通过 resultMap标签 配置。 |
OGNL
mapper
配置文件的 标签属性
中支持 OGNL表达式
,这里是列举 MyBatis
中常用到的 OGNL表达式
OGNL
支持使用 java方法
注意在标签语言中需要转义字符。
1 | /** java */ |
操作符 | 操作符(注意在标签语言中需要转义字符,如: && 等) |
||
---|---|---|---|
支持java的操作符 | + 、 - 、 * 、 / 、 == 、 != 、 ` |
、 &&` 等 |
|
特有的操作符 | and 、 or 、 mod 、 in 、 not in |
基本取值
单一入参下,mybatis 提供了默认的取值方式,可以使用
@Param
取别名。多个入参时需要包装或使用
@Param
注解,因为java
编译后不会保存形参名。
单入参类型 | 取值方式 | 说明 |
---|---|---|
String 与基本类型 |
_parameter |
当只有一个参数时 #{_parameter} 中 _parameter 可以是任意值,一般用参数名。 |
Map / 自定义包装类型 | key / 属性名 | 若参超过 5 个,推荐使用这种方式。 |
Collection | collection |
相应的 Array 使用 array , List 也可以使用 list 。 |
#{}
& ${}
取值符 | 是否存在 sql 注入风险 | 说明 |
---|---|---|
#{} |
否 | sql 语句中的 #{} 并不是 ognl ,其由 mybatis 处理,类似 预备语句 :1) #{} 会被替换为 ? ;2) 根据 ? 的次序,会被填入对应的参数,并加上 '' 。 |
${} |
是 | ${} 会被直接替换为指定字符串,并且不会添加 '' 。 |
常见问题
- 必须的无参构造器 :因为 mybatis 使用反射动态生成对象实例,必须含有无参构造器。
模糊查询
mysql
对于 mysql ,可以使用两种方式进行模糊查询。
若使用中文搜索,确保
spring.datasource.url
配置了characterEncoding=utf8
。
1 | <select id="selectBySearch" resultMap="BaseResultMap"> |
oracle
1 | <select id="searchUserBySearchName" parameterType="java.lang.String" resultType="org.demo.entity.User"> |
sqlserver
1 | <select id="searchUserBySearchName" parameterType="java.lang.String" resultType="org.demo.entity.User"> |
获取自增主键
*Mapper.java
1 | int insert(Message record); |
*Mapper.xml
useGeneratedKeys="true"
: 启用自增主键。keyProperty="id"
: 指定自增主键赋值属性。
1 | <insert id="insert" useGeneratedKeys="true" keyProperty="id"> |
测试示例
1 |
|
1 | 操作记录数:1, 自增主键:7。 |
枚举映射
mybatis 提供了默认的枚举处理器,但一般无法满足需求,需要自定义类型处理器。
默认枚举处理器 | 说明 |
---|---|
EnumTypeHandler |
name() 作为取值。 |
EnumOrdinalTypeHandler |
ordinal() 作为取值。 |
*BaseEnum.java
定义基础属性接口作为共通映射。
1 | package tk.gushizone.mybatis.enumeration; |
*Enum.java
1 | package tk.gushizone.mybatis.enumeration; |
*TypeHandle.java
1 | package tk.gushizone.mybatis.enumeration; |
*Mapper.xml
1 | <result column="COMMAND" property="command" typeHandler="tk.gushizone.mybatis.enumeration.CodeEnumTypeHandler"/> |