映射器配置的组成
元素名称 | 描述 |
---|---|
select | 查询,返回查询到的结果集 |
insert | 插入,返回实际插入的行数 |
update | 更新,返回实际更新的行数 |
delete | 删除,返回实际删除的行数 |
sql | 定义一部分sql,可在别处引用 |
select元素
属性
属性名称 | 描述 | 默认值(如有) |
---|---|---|
id | 映射器接口中的方法名称 | |
parameterType | 传入的参数类型,可以是基本类型/map/类名/别名 | |
resultType | 结果集的类型,自动绑定JavaBean,不和resultMap同时使用 | |
resultMap | 前面定义的resultMap的id引用,可自定义映射规则 | |
flushCache | 是否在调用SQL后清空之前查询的本地缓存和二级缓存 | false |
useCache | 是否要求将此次查询结果缓存(二级缓存) | true |
timeout | 超时的秒数,超时后会抛出异常 | 在JDBC驱动里 |
fetchSize | 获取结果的总行数 | 在JDBC驱动里 |
statementType | 使用哪个Statement工作,如STATEMENT(Statement) | PREPARED(PreparedStatement) |
resultSetType | FORWARD_ONLY(游标向前访问),SCROLL_SENSITIVE(双向滚动,及时更新结果集),SCROLL_INSENSITIVE(双向滚动,不更新结果集) | 在JDBC驱动里 |
databaseId | 前面学的数据库厂商标识 | |
resultOrdered | 是否包含了嵌套结果集或者分组 | false |
resultSets | 多结果集时,列出执行SQL后每个结果集的名称,逗号分隔 |
自动映射
自动映射使用上面的resultType
属性配置一下结果集类型即可。需要确保MyBatis配置文件中,settings
配置下的autoMappingBehavior
子配置不是NONE
(默认就不是),就可以实现自动映射。
自动映射一般指的是数据库的列名和POJO对象的属性名一致,这时结果集的列就会直接映射到结果对象的属性上,对于不一致的地方也可以使用列名 AS 属性名
来调整。
以上都是之前尝试过的,另外还可以在settings
配置mapUnderscoreToCamelCase
为true
,这样就能直接从下划线分割的数据库列名映射到驼峰式的POJO属性名。
自定义映射
自定义映射需要在映射配置文件中使用resultMap
元素定义一个结果集,就像第五篇中那样使用就可以手动配置property
(属性)到column
(列)的映射关系。记得在select
元素中使用resultMap
属性去引用前面配置的resultMap
的id
,并且去掉resultType
属性。
insert元素
属性
属性名称 | 描述 | 默认值(如有) |
---|---|---|
id | 映射器接口中的方法名称 | |
parameterType | 传入的参数类型,可以是基本类型/map/类名/别名 | |
flushCache | 是否在调用SQL后清空之前查询的本地缓存和二级缓存 | false |
timeout | 超时的秒数,超时后会抛出异常 | 在JDBC驱动里 |
statementType | 使用哪个Statement工作,如STATEMENT(Statement) | PREPARED(PreparedStatement) |
keyProperty | 主键的列名(联合主键用逗号隔开),不能和keyColumn同用 | |
keyColumn | 主键的列下标(联合主键用逗号隔开),不能和keyProperty同用 | |
useGeneratedKeys | 主键回填或自定义规则,要使用这个属性就必须有keyProperty或keyColumn | false |
databaseId | 前面学的数据库厂商标识 |
关于主键回填
主键回填指的是当将useGeneratedKeys
属性设置为true
时,如果在DBMS里设置了自动生成主键,MyBatis在插入后会使用JDBC的getGeneratedKeys()
方法来获取DBMS为插入的这行所生成的主键,并根据keyProperty
或者keyColumn
属性来回填到POJO对象的相应属性上。
主键回填使得在插入后能够获得这个主键,便于接下来的操作。
比如在图书上架时,刚向数据库里插入一本书,想要知道这本书的id是多少,主键回填会让持久化对象在插入后在主键属性上获得DBMS所生成的主键的值。
在第六篇的基础上做些改动来测试:
<!--开启主键回填,指明主键的那一列是名为id的列-->
<insert id="addBook" parameterType="book" useGeneratedKeys="true" keyProperty="id">
INSERT INTO book (name, type_id, type_name)
VALUES (#{name}, #{typeId,typeHandler=org.apache.ibatis.type.EnumOrdinalTypeHandler},
#{typeName,typeHandler=org.apache.ibatis.type.EnumTypeHandler})
</insert>
主函数中插入完输出一下这个POJO对象的id:
Book book1=new Book();
book1.setName("测试主键回填");
book1.setTypeId(BookType.COMPUTER);
book1.setTypeName(BookType.COMPUTER);
bookMapper.addBook(book1);
System.out.println("成功插入,DBMS为它生成的主键是"+book1.getId());
输出:
关于自定义生成主键规则
自定义主键生成规则是指当将useGeneratedKeys
属性设置为true
时,如果在DBMS里没有设置自动生成主键,可以为insert
元素添加一个名为selectKey
的子元素,将其order
属性设为BEFORE
后,就可以在真正执行插入前执行一次查询,并将结果填写到要插入的主键上。
这样就能够通过编写这个查询语句,来自定义主键的生成规则(如:从1开始每次取最大值加2)。在插入时,需要将主键一起插入,因为这时DBMS并没有自动生成主键,而是手动生成的。
还是在第六篇的例子上继续做修改:
<!--开启自定义生成主键,指明主键的那一列是名为id的列-->
<insert id="addBook" parameterType="book" useGeneratedKeys="true" keyProperty="id">
<!--查询结果给id属性,查询结果是int类型,查询发生在真正执行插入之前-->
<selectKey keyProperty="id" resultType="int" order="BEFORE">
SELECT IF(MAX(id) is NULL,1,MAX(id)+2) FROM book
</selectKey>
INSERT INTO book (id,name, type_id, type_name)
VALUES (#{id},#{name}, #{typeId,typeHandler=org.apache.ibatis.type.EnumOrdinalTypeHandler},
#{typeName,typeHandler=org.apache.ibatis.type.EnumTypeHandler})
</insert>
主函数中插入完输出一下这个POJO对象的id:
Book book1=new Book();
book1.setName("测试自定义主键生成策略");
book1.setTypeId(BookType.COMPUTER);
book1.setTypeName(BookType.COMPUTER);
bookMapper.addBook(book1);
System.out.println("成功插入,自定义策略生成的主键是"+book1.getId());
输出:
数据库中:
update元素和delete元素
属性就是前面insert
元素与select
元素里没有加粗的那些属性,那些属性是通用的,使用方式也一样。