【MyBatis Mapper文件简述】宝剑锋从磨砺出,梅花香自苦寒来。这篇文章主要讲述MyBatis Mapper文件简述相关的知识,希望能为你提供帮助。
映射文件顶级元素cache – 对给定命名空间的缓存配置。
cache-ref – 对其他命名空间缓存配置的引用。
resultMap – 是最复杂也是最强大的元素,用来描述如何从数据库结果集中来加载对象。
sql – 可被其他语句引用的可重用语句块。
insert – 映射插入语句
update – 映射更新语句
delete – 映射删除语句
select – 映射查询语句
参数填充与字符串替换使用#{param}
或者#{0}
的格式,可以在SQL语句中放置参数,等调用的时候再向里面填充,可以使用#{property,javaType=int,jdbcType=NUMERIC,typeHandler=MyTypeHandler,numericScale=2}
的形式,指定参数的具体类型、处理器类以及保留的小数位数。在搭配储存过程时,允许指定mode=IN/OUT/INOUT
,即数据库输入参数或者输出参数或者输入输出参数。
${}是字符串替换拼接,是MyBatis中变量的值的替换,无法防止注入,而#{}是SQL预编译过程中替换为一个?再进行注入,注入的值会带引号。
表名或者列名作为参数时,必须使用${},order by 时,必须使用${}(否则会多个引号),使用${}时要注意何时加或不加单引号以及注入问题。
select
<
select
id="
selectPerson"
语句唯一标识符
parameterType="
int"
传入参数的完全限定名或者别名,可以不设置
resultType="
hashmap"
返回期望类型的完全限定名或者别名(对于集合,是集合内部类型而不是集合类型),和resultMap参数二选一
resultMap="
personResultMap"
外部resultMap的命名引用
flushCache="
false"
每次调用语句是否刷新cache
useCache="
true"
本语句结果是否被二级缓存
timeout="
10"
超时时间
fetchSize="
256"
这是一个给驱动的提示,尝试让驱动程序每次批量返回的结果行数和这个设置值相等
statementType="
PREPARED"
使用什么的对象操作SQL语句,STATEMENT直接操作SQL,PREPARED预处理编译,CALLABLE执行存储过程
resultSetType="
FORWARD_ONLY"
结果集对象的类型,是否只能获取next还是能进行滚动,滚动时是否对更改敏感
databaseId="
oracle"
数据库厂商标识
resultOrdered="
false"
嵌套结果 select 语句适用,返回的主结果行不会带来对前面结果集的引用,不会导致内存不够用
resultSets="
cls1,cls2"
>
多结果集,为每个结果集指定一个名字
insert, update 和 delete
<
insert/update/delete
id="
insertAuthor"
SQL语句的ID
parameterType="
domain.blog.Author"
传入参数的类名
flushCache="
true"
语句调用会导致本地缓存和二级缓存清空
statementType="
PREPARED"
SQL执行方式
keyProperty="
id"
(仅对 insert 和 update 有用)使MyBatis取出数据库生成的键并向某个目标属性赋值
keyColumn="
"
(仅对 insert 和 update 有用)通过生成的键值设置的表中的列名,主键不是表中第一列时需要设置
useGeneratedKeys="
true"
(仅对 insert 和 update 有用)使MyBatis取出数据库自动生成的主键
timeout="
20"
抛出异常前的超时时间
databaseId="
oracle"
>
数据库厂商标识
selectKey标签可以插入在insert标签中,与select标签相比,多了order属性,该属性如果设置为 BEFORE,那么它会首先生成主键,设置 keyProperty 然后执行插入语句。如果设置为 AFTER,那么先执行插入语句,然后是 selectKey 中的语句
<
selectKey
keyProperty="
id"
resultType="
int"
order="
BEFORE"
statementType="
PREPARED"
>
SQL语句可以定义可重用的SQL代码段,例如
<
sql id="
userColumns"
>
${alias}.id,${alias}.username,${alias}.password <
/sql>
<
select id="
selectUsers"
resultType="
map"
>
select
<
include refid="
userColumns"
>
<
property name="
alias"
value=https://www.songbingjia.com/android/"
t1"
/>
<
/include>
,
<
include refid="
userColumns"
>
<
property name="
alias"
value="
t2"
/>
<
/include>
from some_table t1
cross join some_table t2
<
/select>
属性值也可以被用在 include 元素的 refid 属性里或 include 元素的内部语句中,如
<
include refid="
${include_target}"
/>
,可能因为${}是在XML解析时进行字符串拼接替换。resultMap结果映射resultMap 元素是 MyBatis 中最重要最强大的元素。它可以将从数据库中获取的复杂对象直接映射为Java中的对象。
如下,即为使用resultType将数据库中的结果直接映射为类对象,如果数据库中的列名与类属性名没有完全匹配,那么可以使用as来匹配:
<
!-- mybatis-config.xml 中 -->
<
typeAlias type="
com.someapp.model.User"
alias="
User"
/>
<
!-- SQL 映射 XML 中 -->
<
select id="
selectUsers"
resultType="
User"
>
select id,
user_nameas "
userName"
,
hashed_passwordas "
hashedPassword"
from some_table
where id = #{id}
<
/select>
数据库结果与类的不匹配,除了上面简单的方式,还可以通过resultMap中的id和result参数进行绑定。
resultMap标签还能对一对一和一对多结果进行关系映射。
resultMap高级结果映射resultMap标签可以配置许多属性子标签:
- constructor - 用于在实例化类时,注入结果到构造方法中
- idArg - ID 参数;标记出作为 ID 的结果可以帮助提高整体性能
- arg - 将被注入到构造方法的一个普通结果
- id – 一个 ID 结果;标记出作为 ID 的结果可以帮助提高整体性能
- result – 注入到字段或 JavaBean 属性的普通结果
- association – 一个复杂类型的关联;许多结果将包装成这种类型
- 嵌套结果映射 – 关联本身可以是一个 resultMap 元素,或者从别处引用一个
- collection – 一个复杂类型的集合
- 嵌套结果映射 – 集合本身可以是一个 resultMap 元素,或者从别处引用一个
- discriminator – 使用结果值来决定使用哪个 resultMap
- case – 基于某些值的结果映射
- 嵌套结果映射 – case 本身可以是一个 resultMap 元素,因此可以具有相同的结构和元素,或者从别处引用一个
- case – 基于某些值的结果映射
这两个标签功能一致,但是id时对象的标识属性,在比较实例是否相等时用到,可以提高整体性能,尤其是进行缓存和嵌套结果映射时。
这两个标签有5个属性:
- property 映射到Java对象属性的字段或属性。支持用点限定具体的属性,如“address.street.number”
- column 数据库中的列名,或者是列的别名。
- javaType 希望映射到的Java类的完全限定名,或一个类型别名
- jdbcType 属性对应的JDBC 类型
- typeHandler 针对这个属性使用的类型处理器
当创建数据库结果映射到的Java对象时,可能需要进行一些初始化处理,该标签就是映射到类的构造方法的形参。
该标签下的idArg标签与arg标签的区别和id以及result标签的区别类似。
该标签下的属性有column,javaType,jdbcType,typeHandler,与其他标签类似。
该标签下有select属性,用于加载复杂类型属性的映射语句的 ID,它会从 column 属性中指定的列检索数据,作为参数传递给此 select 语句。还有resultMap,可以将嵌套的结果集映射到一个合适的对象树中,可以替代select语句。
该标签下有name属性,是Java对象构造方法的名字,搭配@Param注解可以乱序传参,否则该标签内的参数顺序和构造方法参数顺序必须一致。
association
关联,数据库关系中处理“有一个”类型的关系。如一个订单对应一个用户。属性有property,javaType,jdbcType和typeHandler。子标签有id和result两种。
关联的嵌套查询select-> resultMap-> association-> select
该association标签有select属性,可以指定一个select标签对象,进行一对一的级联查询。
该标签具有fetchType属性,可以指定为lazy或eager,即关联对象是懒加载还是积极加载。
使用该标签的查询叫做嵌套查询,存在N+1查询的问题,即对母查询的每个结果再进行一次子查询,会带来极大的性能问题,使用lazy的加载查询模式可以缓解这个问题,但是还有使用嵌套结果的方法来解决这个问题。
关联的嵌套结果映射select-> resultMap-> association-> resultMap
使用association标签的resultMap属性,可以进行结果的级联,即在数据库端,使用join的方法,将表联合在一起,查询到关联了两个表的结果,然后使用association指定两个表的关系,把子表添加到association的resultMap中,MyBatis就会按照这个关系,将两个表的对象进行关联,并返回结果。
在使用这种方式关联时,如果有多个相同的表被关联,就会产生重名的问题,比如一个文章有一个作者还有一个共同作者,而两个作者的表是一模一样的,这是可以使用columnPrefix=" co_" 属性指定某个表的前缀,以此进行区分。
如果被关联的子对象有空属性,默认为至少有一个属性不为空才会创建子对象,但可以使用notNullColumn=" " 属性指定当某列(多个列用,隔开)不为空时才创建子对象。
resultSets关联的多结果集这是N+1查询问题的另一种解决办法。
推荐阅读
- 创建并运行rn app项目
- App crash原因以及解决办法
- uniapp - cell组件
- 最佳编程编辑器(没有明确胜利者的永无止境的战斗)
- OpenGL简介(3D文本渲染教程)
- 学习Markdown(面向软件开发人员的写作工具)
- Vulkan API的简要概述
- Selenium中的自动化(页面对象模型和页面工厂)
- SVG文本教程(Web上的文本注释)