文章目录
映射器
MyBatis 的真正强大在于它的语句映射。由于它的异常强大,映射器的 XML 文件就显得相对简单。如果拿它跟具有相同功能的 JDBC 代码进行对比,你会立即发现省掉了将近 95% 的代码。MyBatis 致力于减少使用成本,让用户能更专注于 SQL 代码。
MyBatis文档地址:https://mybatis.org/mybatis-3/zh/sqlmap-xml.html
XML映射器
元素名称 | 描 述 | 备 注 |
---|---|---|
select | 映射查询语句,最常用、最复杂的元素之一 | 可以自定义参数,返回结果集等 |
insert | 映射插入语句 | 执行后返回一个整数,代表插入的行数 |
update | 映射更新语句 | 执行后返回一个整数,代表更新的行数 |
delete | 映射删除语句 | 执行后返回一个整数,代表删除的行数 |
sql | 定义一部分SQL,在多个位置被引用–被其它语句引用的可重用的语句块 | 例如,一张表列名,一次定义,可1以在多个SQL语句中使用 |
resultMap | 用来描述从数据库结果集中来加载对象,是最复杂也是最强大的元素 | 提供映射规则 |
cache-ref | 引用其它命名空间的缓存配置 | 提供其它命名空间下的缓存映射 |
cache | 该命名空间的缓存配置 | 分为一级缓存和二级缓存 |
1. select元素【**】
MyBatis的查询语句
属性名称 | 描 述 |
---|---|
id | 它和Mapper的命名空间组合起来使用,是唯一标识符,供MyBatis调用 |
parameterType | 表示传入SQL语句的参数类型的全限定名或别名。是个可选属性,MyBatis能推断出具体传入语句的参数。 |
resultType | SQL语句执行后返回的类型(全限定名或者别名)。如果是集合类型,返回的是集合元素的类型。返回时可以使用resultType或resultMap之一 |
resultMap | 它是映射集的引用,与< resultMap>元素一起使用。返回时可以使用resultType或resultMap之一 |
flushCache | 它的作用是在调用SQL语句后,是否要求MyBatis清空之前查询本地缓存和二级缓存。默认值为false。如果设置为true,则任何时候只要SQL语句被调用,都将清空本地缓存和二级缓存 |
useCache | 启动二级缓存的开关。默认值为true,表示将查询结果存入二级缓存中 |
timeout | 用于设置超时参数,单位是秒。超时将抛出异常。 |
fetchSize | 获取记录的总条数设定 |
statementType | 告诉MyBatis使用哪个JDBC的Statement工作,取值为STATEMENT(Statement)、PREPARED(PreparedStatement)、CALLABLE(CallableStatement) |
resultSetType | 这是针对JDBC的ResultSet接口而言,其值可设置为FORWARD_ONLY(只允许向前访问)、SCROLL_SENSITIVE(双向滚动,但不及时更新)、SCROLL_INSENSITIVE(双向滚动,及时更新) |
2. insert元素
insert元素用于映射插入语句,update元素用于映射更新语句,delete元素用于映射删除语句。执行insert都将返回一个整数表示其影响的行数。
2.1 insert元素特有的属性:
insert的特有属性 | 描述 |
---|---|
keyProperty | 该属性的作用是将插入或更新操作时的返回值赋值给PO类的某个属性,通常会设置为主键对应的属性。如果是联合主键,可以在多个值之间用逗号隔开。 |
keyColumn | 该属性用于设置第几列是主键,当主键列不是表中的第一列时需要设置。如果是联合主键时,可以在多个值之间用逗号隔开。 |
useGeneratedKeys | 该属性将使MyBatis使用JDBC的getGeneratedKeys()方法获取由数据库内部生产的主键,如MySQL、SQL Server等自动递增的字段,其默认值为false。 |
2.2 insert元素主键回填(设置为自动递增的主键)
MySQL、SQL Server等数据库的表格可以采用自动递增的字段作为主键。有时可能需要使用这个刚刚产生的主键,用以关联其他业务。
<!-- 添加一个用户,成功后将主键值回填给uid(javabean类的属性)-->
<insert id="addUser" parameterType="com.po.MyUser"
keyProperty="uid" useGeneratedKeys="true">
insert into user (uname,usex) values(#{uname},#{usex})
</insert>
2.3 自定义主键(实现主键自动递增)
如果实际工程中使用的数据库不支持主键自动递增(如Oracle),或者取消了主键自动递增的规则时,可以使用MyBatis的**< selectKey >元素来自定义生成主键。**
<insert id="insertUser" parameterType="com.xgf.bean.User">
<!-- 先使用selectKey元素定义主键,然后再定义SQL语句 -->
<selectKey keyProperty="uid" resultType="Integer" order="BEFORE">
select if(max(uid) is null, 1 , max(uid)+1) as newUid from user
</selectKey>
insert into user (uid,uname,usex) values(#{uid},#{uname},#{usex})
</insert>
3. update、delete元素
和元素比较简单,它们的属性和元素、元素的属性差不多,执行后也返回一个整数,表示影响了数据库的记录行数。
<!-- 修改一个用户 -->
<update id="updateUser" parameterType="com.xgf.bean.User">
update user set uname = #{uname},usex = #{usex} where uid = #{uid}
</update>
<!-- 删除一个用户 -->
<delete id="deleteUser" parameterType="Integer">
delete from user where uid = #{uid}
</delete>
4. resultMap元素(结果映射)【*****】
resultMap元素表示结果映射集,是MyBatis中最重要也是最强大的元素。主要用来定义映射规则、级联的更新以及定义类型转化器等。
resultMap标签的属性:
resultMap属性 | 描述 |
---|---|
id | 当前命名空间中的一个唯一标识,用于标识一个结果映射。 |
type | 类的完全限定名, 或者一个类型别名。 |
autoMapping | 如果设置这个属性,MyBatis 将会为本结果映射开启或者关闭自动映射。 这个属性会覆盖全局的属性 autoMappingBehavior。默认值:未设置(unset)。 |
resultMap的子元素:
<resultMap type="" id="">
<constructor> <!-- 类在实例化时,用来注入结果到构造方法 -->
<idArg/> <!-- ID参数,结果为ID -->
<arg/> <!-- 注入到构造方法的一个普通结果 -->
</constructor>
<id/> <!-- 用于表示哪个列是主键 -->
<result/> <!-- 注入到字段或JavaBean属性的普通结果,非主键外的 -->
<association property=""/> <!-- 用于一对一关联 -->
<collection property=""/> <!-- 用于一对多、多对多关联 -->
<discriminator javaType=""> <!-- 使用结果值来决定使用哪个结果映射 -->
<case value=""/> <!-- 基于某些值的结果映射 -->
</discriminator>
</resultMap>
基本案例写法:
<!-- 自定义resultMap 结果集类型 -->
<resultMap type="com.xgf.bean.User" id="userResultMap">
<!-- property对应的是javabean类中的属性-->
<!-- column对应的是数据库表的列名,可以来自不同的表 -->
<id property="uid" column="uid"/>
<result property="uname" column="uname"/>
<result property="usex" column="usex"/>
</resultMap>
<!-- 使用自定义结果集类型查询所有用户 -->
<select id="selectAllUser" resultMap="userResultMap">
select uid,uname,usex from user
</select>
级联关系【*****】
4.1 一对一关联查询 (association) - 用javaType来指定对象类型
MyBatis中,通过<resultMap>
元素的子元素<association>
处理这种一对一级联关系。
属性 | 描述 |
---|---|
property | 指定映射到实体类的对象属性(javabean对应的对象属性值) ---- 就是一对一关联的对象(定义的bean中的对象属性名) |
javaType | 指定映射到实体对象属性的类型(javabean对象的完全限定名/类型别名) —就是一对一关联的对象的完全限定名,或别名 |
select | 指定引入嵌套查询的子SQL语句,该属性用于关联映射中的嵌套查询。 |
<!-- 一对一关联查询 person人和card身份证-->
<resultMap id="personMap" type="com.xgf.correlation.one_to_one.bean.Person" autoMapping="true">
<!--
<id>主键
<result>其它属性列
如果设置了autoMapping="true" 自动映射,那么数据库表列名和类对象属性名一致的情况下
,可以不用写<result>属性,自动映射
-->
<id property="id" column="id"/>
<result property="username" column="username"/>
<!--
封装person对象对应的card
一对一关联 用association封装对象类型
property就是关联对象card在的person类中的属性值,javaType就是person关联的对象完全限定名
-->
<association property="card" javaType="com.xgf.correlation.one_to_one.bean.Card">
<id property="id" column="id"/>
<result property="code" column="code"/>
</association>
</resultMap>
<!-- 查询结构封装成map对象 -->
<select id="getPersonById" resultMap="personMap">
select p.id,p.username,c.id,c.code
from person p inner join card c on p.id_card = c.id
where p.id = #{id}
</select>
4.2 一对多、多对多关联查询 (collection) - 用ofType来制定对象类型
多对多关联就是两个一对多关联进行交互替换。
一对多关联查询:
<!--一对多关联关系 user和task表 一个user可以有多个task任务,一个task只能由一个user完成-->
<resultMap id="userTaskMap" type="com.xgf.correlation.one_to_many.bean.User">
<id column="id" property="id"/>
<result property="username" column="username"/>
<!-- property就是在user中定义的task集合的属性名taskList
ofType就是对应这个集合的属性类task类的完全限定名
-->
<collection property="taskList" ofType="com.xgf.correlation.one_to_many.bean.Task" >
<id column="tid" property="id"/>
<result column="taskName" property="taskName"/>
</collection>
</resultMap>
<select id="getUserTaskById" resultMap="userTaskMap">
SELECT u.id,u.username,t.id tid,t.taskName
from users u inner join task t on u.id = t.userId
where u.id=#{id}
</select>
多对多关联查询:
<!-- order订单表和product 产品表,一个订单可以有多份产品,一个产品可以有多个订单
创建中间表orders_product
-->
<resultMap id="orderMap" type="com.xgf.mybatis.correlation.many_to_many.bean.Order">
<id column="oid" property="id"/>
<result property="description" column="description"/>
<collection property="productList" ofType="com.xgf.mybatis.correlation.many_to_many.bean.Product">
<id column="pid" property="id"/>
<result property="name" column="name"/>
</collection>
</resultMap>
<select id="getOrderById" parameterType="int" resultMap="orderMap">
select o.id oid,o.description,p.id pid,p.name
from orders o left outer join orders_product op on o.id = op.ordersId
left outer join product p on p.id = op.productId
where o.id = #{id}
</select>