Web框架-Mybatis-映射文件
映射文件
映射器的配置
元素名称 | 描 述 | 备 注 |
---|---|---|
select | 査询语句,最常用、最复杂的元素之一 | 可以自定义参数,返回结果集等 |
insert | 插入语句 | 执行后返回一个整数,代表插入的条数 |
update | 更新语句 | 执行后返回一个整数,代表更新的条数 |
delete | 删除语句 | 执行后返回一个整数,代表删除的条数 |
parameterMap | 定义参数映射关系 | 即将被删除的兀素,不建议大家使用 |
sql | 允许定义一部分的SQL,然后在各个地方引用它 | 例如,一张表列名,我们可以一次定义,在 多个SQL语句中使用 |
resultMap | 用来描述从数据库结果集中来加载对象,它是 最复杂、最强大的元素 | 它将提供映射规则 |
cache | 给定命名空间的缓存配置 | |
cache-ref | 其他命名空间缓存配置的引用 |
mapper文件的结构
mapper映射文件是xml格式的配置文件,由一系列具有层级关系的元素组成。
一、select元素
<select>
元素就是sql查询语句。可以执行一些简单的查询操作,也可以是复杂的查询操作。例如:
<select id="findCustomerById" parameterType="Integer" resultType="com.itheima.po.Customer">
select * from t_customer where id = #{id}
</select>
属性 | 说明 |
---|---|
statementType | 用于设置mybatis使用哪个JDBC的Statement工作,其值为statement、prepared(默认值)或callable,分别对应JDBC中的Statement、PreparedStatement和CallableStatement |
二、insert元素
<insert>
元素用于映射插入语句,在执行完元素中定义的SQL语句后,会返回一个表示插入记录数的整数。
<insert>
元素的配置示例如下:
<insert
id="addCustomer"
parameterType="com.itheima.po.Customer"
flushCache="true"
statementType="PREPARED"
keyProperty=""
keyColumn=""
useGeneratedKeys=""
timeout="20">
执行插入操作后,很多时候需要返回插入成功的数据生成的主键值,此时就可以通过上面讲解的3个属性来实现。
1、对于支持主键自助增长的数据库(如MySQL),可以通过如下配置实现:
<insert id="addCustomer" parameterType="com.itheima.po.Customer" keyProperty="id" useGeneratedKeys="true" >
insert into t_customer(username,jobs,phone) values(#{username},#{jobs},#{phone})
</insert>
使用以上配置后,执行插入后会返回插入成功的行数,以及插入行的主键值。
2、对于不支持主键自助增长的数据库(如Oracle),或者支持增长的数据库取消了主键自动增长的规则时,可以通过如下配置实现自定义生成主键:
<insert id="insertCustomer" parameterType="com.itheima.po.Customer">
<selectKey keyProperty="id" resultType="Integer" order="BEFORE">
select if(max(id) is null, 1, max(id) +1) as newId from t_customer
</selectKey>
insert into t_customer(id,username,jobs,phone) values(#{id},#{username},#{jobs},#{phone})
</insert>
解析:在执行以上配置时,selectKey元素会首先执行,它会通过自定义的语句来设置数据表中的主键(如果t_customer表中没有记录,则将id设置为1,否则就将id的最大值加1来作为新的主键),然后调用插入语句。
<selectKey
keyProperty="id"
resultType="Integer"
order="BEFORE"
statementType="Prepared" (默认的)
>
其中orde属性可以设置为before或者after。当设置为before时,那么它会首先执行selectkey元素中的配置来设置主键,然后在执行插入语句;如果设置为after,则相反。
三、update和delete元素
<update>
和<delete>
元素的使用比较简单,它们的属性配置也基本相同。
1、<update>
和<delete>
元素的常用属性如下:
<update
id="updateCustomer"
parameterType="com.itheima.po.Customer"
flushCache="true"
statementType="PREPARED"
timeout="20">
<delete
id="deleteCustomer"
parameterType="com.itheima.po.Customer"
flushCache="true"
statementType="PREPARED"
timeout="20">
2、<update>
和<delete>
元素的使用示例如下:
<update id="updateCustomer" parameterType="com.itheima.po.Customer">
update t_customer
set username=#{username},jobs=#{jobs},phone=#{phone}
where id=#{id}
</update>
<delete id="deleteCustomer" parameterType="Integer">
delete from t_customer where id=#{id}
</delete>
四、sql片段元素
sql片段,可以在mapper文件中的任何地方引用,主要作用是减少代码量,复用重复的字段。
例如:
<sql id="customerColumns">id,username,jobs,phone</sql>
定义sql片段,通过<include>
元素的refid属性引用id为customerColumns的代码片段。
例如:
<select id="findCustomerById" parameterType="Integer" resultType="com.itheima.po.Customer">
select
<include refid="customerColumns"/>
from tableName
where id = #{id}
</select>
五、resultMap 结果集映射元素
<resultMap>
元素表示结果映射集,是MyBatis中最重要也是最强大的元素。它的主要作用是定义映射规则、级联的更新以及定义类型转化器等。
<resultMap>
元素中包含了一些子元素,它的元素结构如下所示:
<resultMap type="" id="">
<constructor> <!-- 类在实例化时,用来注入结果到构造方法中-->
<idArg/> <!-- ID参数;标记结果作为ID-->
<arg/> <!-- 注入到构造方法的一个普通结果-->
</constructor>
<id/> <!-- 用于表示哪个列是主键-->
<result/> <!-- 注入到字段或JavaBean属性的普通结果-->
<association property="" /> <!-- 用于一对一关联 -->
<collection property="" /> <!-- 用于一对多关联 -->
<discriminator javaType=""> <!-- 使用结果值来决定使用哪个结果映射-->
<case value="" /> <!-- 基于某些值的结果映射 -->
</discriminator>
</resultMap>
<resultMap>
元素的type属性表示需要映射的POJO,<id>
属性是这个resultMap
的唯一标识。
<resultMap>
的子元素<constructor>
用于配置构造方法(当一个POJO中未定义无参的构造方法时就可以使用<constructor>
元素进行配置)。
子元素<id>
用于表示那个列是主键,而<result>
用于表示POJO和数据表中普通列的映射关系。
<association>
和<collection>
用于处理多表时的关联关系,而<discriminator>
元素主要用于处理一个单独的数据库查询返回很多不同数据类型结果集的情况。
在默认情况下,mybatis程序在运行时会自动的将查询到的数据与需要返回的对象的属性进行匹配赋值(需要表中的列名与对象的属性名称完全一致),然而在实际开发中属性名和列名可能不一致,这个时候就需要使用resultMap元素进行映射处理。
例如:简单的结果集映射
<resultMap id="BaseResultMap" type="cn.jason.bootmybatis.model.Tests">
<id column="id" property="id" jdbcType="BIGINT"/>
<result column="name" property="name" jdbcType="VARCHAR"/>
<result column="age" property="age" jdbcType="INTEGER"/>
</resultMap>
<select id="selectByPrimaryKey" resultMap="BaseResultMap">
select
<include refid="Base_Column_List"/>
from tests
where id = #{id,jdbcType=BIGINT}
</select>
六、扩展
传递多个参数方式
- 利用参数出现的顺序,使用#{0}/#{1}
实例:
DAO层的函数方法
Public User selectUser(String name,String area);
对应的Mapper.xml
<select id="selectUser" resultMap="BaseResultMap">
select * from user_user_t where user_name = #{0} and user_area=#{1}
</select>
其中,#{0}代表接收的是dao层中的第一个参数,#{1}代表dao层中第二参数,更多参数一致往后加即可。
- 使用Map传递参数。因为Map导致业务可读性的丧失,从而导致后续扩展和维护 的困难,我们应该在实际的应用中果断废弃这样的传递参数的方式。
Dao层的函数方法
Public User selectUser(Map paramMap);
对应的Mapper.xml
<select id="selectUser" resultMap="BaseResultMap">
select * from user_user_t where user_name = #{userName,jdbcType=VARCHAR} and user_area=#{userArea,jdbcType=VARCHAR}
</select>
- 使用@Param注解传递多个参数,这种方式的使用受到参数个数(n)的影响。当n<5时,它是最佳的传参方式,它比用JavaBean更好,因为它更加直观;当n>5 时,多个参数将给调用带来困难。
Dao层的函数方法
Public User selectUser(@param(“userName”)Stringname,@param(“userArea”)String area);
对应的Mapper.xml
<select id="selectUser" resultMap="BaseResultMap">
select * from user_user_t where user_name = #{userName,jdbcType=VARCHAR} and user_area=#{userArea,jdbcType=VARCHAR}
</select>
- 当参数个数多于5个时,建议使用JavaBean方式。
Dao层的函数方法
public User selectUser(User params);
对应的Mapper.xml
<select id="selectUser" parameterType="com.test.User" resultMap="UserResultMap">
select * from user
where user_name = #{userName} and dept_id = #{deptId}
</select>