1. 快速入门
导入依赖
1 |
|
定义 mapper 接口和xml
1 |
|
1 |
|
- 方法名和 SQL 的 id 一致
- 方法返回值和
resultType
一致 - 方法的参数和 SQL 的参数一致
- 接口的全类名和映射配置文件的名称空间一致
准备 MyBatis 配置文件
习惯上命名为 mybatis-config.xml
1 |
|
运行和测试
1 |
|
2. SQL语句传参
2.1 日志输出配置
MyBatis 配置文件设计标签和顶层结构如下:
- configuration(配置)
- properties(属性)
- settings(设置)
- typeAliases(类型别名)
- typeHandlers(类型处理器)
- objectFactory(对象工厂)
- plugins(插件)
- environments(环境配置)
- environment(环境变量)
- transactionManager(事务管理器)
- dataSource(数据源)
- environment(环境变量)
- databaseIdProvider(数据库厂商标识)
- mappers(映射器)
可以在配置文件使用settings标签设置,输出运过程SQL日志!
设置名 | 描述 | 有效值 | 默认值 |
---|---|---|---|
logImpl | 指定 MyBatis 所用日志的具体实现,未指定时将自动查找。 | 未设置 |
1 |
|
2.2 #{}, ${}
#{}
- MyBatis 会将 SQL 语句中的
#{}
转换为问号占位符。
${}
${}
形式传参,底层MyBatis做的是字符串拼接操作, 通常不会使用,有 SQL 注入的风险
一个特定的适用场景是:通过Java程序动态生成数据库表,表名部分需要Java程序通过参数传入;而JDBC对于表名部分是不能使用问号占位符的,此时只能使用${}
1
2
@Select("select * from user where ${column} = #{value}")
User findByColumn(@Param("column") String column, @Param("value") String value);
3. 数据输入
3.1 单个简单类型参数
单个简单类型参数,在#{}
中可以随意命名,但是没有必要。通常还是使用和接口方法参数同名
3.2 多个简单类型参数
当有多个简单类型参数时,MyBatis无法识别抽象方法参数的自定义名称,需要使用 @Param
标记
或者通过 arg0, arg1; param1, param2 表示
3.3 Map类型参数
若mapper接口方法的参数有多个时,可以手动将这些参数放在一个map中存储
- 只需要通过
#{}
和${}
以键的方式访问值即可,但是需要注意后者的单引号问题 - 如果有很多零散的参数需要传递,但是没有对应的实体类类型可以使用,封装到Map中会很简洁
3.4 实体类类型参数
以属性的方式访问值即可
MyBatis会根据 #{}
中传入的数据,加工成 getXxx()
方法,通过反射在实体类对象中调用这个方法,从而获取到对应的数据。填充到 #{}
解析后的问号占位符的位置
4. 数据输出
数据输出总体上有两种形式:
- 增删改操作返回的受影响行数:直接使用 int 或 long 类型接收即可
- 查询操作的查询结果,需要我们指定输出数据类型
以及插入场景下,实现主键数据回显
4.1 返回单个简单类型
1 |
|
select标签,通过resultType指定查询返回值类型!
resultType = “全限定符|别名|如果是返回集合类型,写范型类型即可”
Mybatis 内部给常用的数据类型设定了很多别名。
以 int 类型为例,可以写的名称有:int、integer、Integer、java.lang.Integer、Int、INT、INTEGER 等等
4.2 返回实体类对象
通过给数据库表字段加别名,让查询结果的每一列都和Java实体类中属性对应起来
1 |
|
或者通过增加全局配置自动识别对应关系
1 |
|
4.3 返回Map类型
若查询出的数据只有一条
1 |
|
1 |
|
返回的结果中key为属性名
若查询出多条数据
1 |
|
- 可以通过map类型的list集合接收
1 |
|
- 可以在mapper接口的方法上添加
@MapKey
注解,此时就可以将每条数据转换的map集合作为值,以某个字段的值作为键,放在同一个map集合中
1 |
|
4.4 返回List类型
不需要任何特殊处理,在resultType属性中还是设置实体类类型即可
4.5 返回主键值
自增长类型主键
1 |
|
MyBatis是将自增主键的值设置到实体类对象中,而不是以Mapper接口方法返回值的形式返回
非自增长类型主键
对于不支持自增型主键的数据库(例如 Oracle)或者字符串类型主键,则可以使用 selectKey
子元素。selectKey
元素将会首先运行,id 会被设置,然后插入语句会被调用
使用 selectKey
帮助插入UUID作为字符串类型主键示例:
1 |
|
通过 keyProperty
属性来指定查询到的 UUID 赋值给对象中的 id
属性,而 resultType
属性指定了 UUID 的类型为 java.lang.String
。
需要注意的是,selectKey
在插入语句的前面,这是因为 MySQL 在 insert
语句中只支持一个 select
子句,而 selectKey
中查询 UUID 的语句就是一个 select
子句,因此我们需要将其放在前面。
最后,在将 User
对象插入到 user
表中时,我们直接使用对象中的 id
属性来插入主键值。
4.6 实体类属性和数据库字段对应关系
别名对应
- SQL语句中手动转换
全局配置自动识别驼峰式命名规则
- SQL语句中可以不使用别名
resultMap
使用 resultMap
标签定义对应关系,再在后面的SQL语句中引用这个对应关系
此处简单介绍一下,涉及到一对多多对一映射的在后面部分展开
1 |
|
5. Mapper标签总结
select 标签
1 |
|
select 元素允许配置很多属性来配置每条语句的行为细节:
属性 | 描述 |
---|---|
id |
在命名空间中唯一的标识符,可以被用来引用这条语句。 |
resultType |
期望从这条语句中返回结果的类全限定名或别名。 注意,如果返回的是集合,那应该设置为集合包含的类型,而不是集合本身的类型。 resultType 和 resultMap 之间只能同时使用一个。 |
resultMap |
对外部 resultMap 的命名引用。结果映射是 MyBatis 最强大的特性,如果你对其理解透彻,许多复杂的映射问题都能迎刃而解。 resultType 和 resultMap 之间只能同时使用一个。 |
timeout |
这个设置是在抛出异常之前,驱动程序等待数据库返回请求结果的秒数。默认值为未设置(unset)(依赖数据库驱动)。 |
statementType |
可选 STATEMENT,PREPARED 或 CALLABLE。这会让 MyBatis 分别使用 Statement,PreparedStatement 或 CallableStatement,默认值:PREPARED。 |
insert, update 和 delete 标签
1 |
|
属性 | 描述 |
---|---|
id |
在命名空间中唯一的标识符,可以被用来引用这条语句。 |
timeout |
这个设置是在抛出异常之前,驱动程序等待数据库返回请求结果的秒数。默认值为未设置(unset)(依赖数据库驱动)。 |
statementType |
可选 STATEMENT,PREPARED 或 CALLABLE。这会让 MyBatis 分别使用 Statement,PreparedStatement 或 CallableStatement,默认值:PREPARED。 |
useGeneratedKeys |
(仅适用于 insert 和 update)这会令 MyBatis 使用 JDBC 的 getGeneratedKeys 方法来取出由数据库内部生成的主键(比如:像 MySQL 和 SQL Server 这样的关系型数据库管理系统的自动递增字段),默认值:false。 |
keyProperty |
(仅适用于 insert 和 update)指定能够唯一识别对象的属性,MyBatis 会使用 getGeneratedKeys 的返回值或 insert 语句的 selectKey 子元素设置它的值,默认值:未设置(unset )。如果生成列不止一个,可以用逗号分隔多个属性名称。 |
keyColumn |
(仅适用于 insert 和 update)设置生成键值在表中的列名,在某些数据库(像 PostgreSQL)中,当主键列不是表中的第一列的时候,是必须设置的。如果生成列不止一个,可以用逗号分隔多个属性名称。 |