目录
- 映射文件
- select元素
- insert元素
- update元素和delete元素
- sql元素
- resultMap元素
映射文件
映射文件是MyBatis框架中十分重要的文件。在映射文件中,<mapper>
元素是映射文件的根元素,其他元素都是它的子元素。映射文件中的主要元素如下所示。
<mapper>
<!--映射查询语句,可自定义参数,返回结果集等-->
<select/>
<!--映射插入语句,执行后返回一个整数,代表插入的条数-->
<insert/>
<!--映射更新语句,执行后返回一个整数,代表更新的条数-->
<update/>
<!--映射删除语句,执行后返回一个整数,代表删除的条数-->
<delete/>
<!--用于定义一部分SQL,然后可被其他语句引用此SQL-->
<sql/>
<!--给定命名空间的缓存配置-->
<cache/>
<!--其他命名空间缓存配置的引用-->
<cache-ref/>
<!--用来描述如何从数据库结果集中加载对象-->
<resultMap/>
</mapper>
select元素
<select>
元素用于映射查询语句,从数据库中读取数据,并组装数据给业务开发人员。示例如下:
<select id="findUserById" parameterType="Integer" resultType="com.ssm.po.User">
select * from t_user where id=#{id}
</select>
上述语句中的唯一标识为findUserById,它接收一个Integer类型的参数,并返回一个User类型的对象。
在<select>
元素中,除了上述示例代码中的几个属性外,还有其他可以配置的属性,如下表所示。
insert元素
<insert>
元素用于映射插入语句,在执行完元素中定义的SQL语句后,会返回一个表示插入记录数的整数。<insert>
元素的配置示例如下:
<insert id="addUser" parameterType="com.ssm.po.User" flushCache="true"
statementType="PREPARED" keyProperty="id" keyColumn="" useGeneratedKeys="" timeout="20">
insert into t_user(username, jobs, phone)values (#{username}, #{jobs},#{phone})
</insert>
<insert>
元素的属性与<select>
元素的属性大部分相同,但还包含3个特有属性(仅对insert和update有用),如下表所示。
执行插入操作后,很多时候我们会需要返回插入成功的数据生成的主键值,此时就可以通过上面所讲解的3个属性来实现。
【示例】如果使用的数据库支持主键自动增长(如MSQL),那么可以通过keyProperty属性指定PO类的某个属性接收主键返回值(通常会设置到id属性上),然后将useGeneratedKeys的属性值设置为true。使用上述配置执行插入后,会返回插入成功的行数以及插入行的主键值。可以通过如下代码测试。
@Test
public void addUserTest() throws Exception {
String resourse = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resourse);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
//创建User对象,并向对象中添加数据
User user = new User();
user.setUsername("tom");
user.setJobs("worker");
user.setPhone("17339880001");
int rows = sqlSession.insert("com.ssm.mapper.UserMapper.addUser", user);
//输出插入数据的主键id值
System.out.println(user.getId());
if (rows > 0) {
System.out.println("成功添加" + rows + "条数据!");
} else {
System.out.println("添加数据失败!");
}
sqlSession.commit();
sqlSession.commit();
}
如果使用的数据库不支持主键自动增长(如Oracle),或者支持增长的数据库取消了主键自增的规则,就可以使用MyBatis提供的另一种方式来自定义生成主键,具体配置示例如下。
<insert id="insertUser" parameterType="com.ssm.po.User">
<selectKey keyProperty="id" resultType="Integer" order="BEFORE">
select if(max(id) is null , 1, max(id)+1) as newId from t_user
</selectKey>
insert into t_user(id, username, jobs, phone) values (#{id}, #{username}, #{jobs},#{phone})
</insert>
在执行上述示例代码时,<selectKey>
元素会首先运行,它会通过自定义的语句来设置数据表中的主键(如果t_uesr表中没有记录,就将id设置为1,否则将id的最大值加1作为新的主键),然后调用插入语句。
<selectKey>
元素在使用时可以设置以下几种属性。
<selectKey
keyProperty="id"
resultType="Integer"
order="BEFORE"
statement="PREPARED">
在上述<selectKey>
元素的几个属性中,keyProperty、resultType和statement的作用与前面讲解的相同。order属性可以被设置为BEFORE或AFTER。如果设置为BEFORE,那么它会先执行<selectKey>
元素中的配置来设置主键,再执行插入语句;如果设置为AFTER,那么它会先执行插入语句,再执行<selectKey>
元素中的配置内容。
update元素和delete元素
<update>
元素和<delete>
元素的使用比较简单,它们的属性配置也基本相同(<delete>
元素中不包含表中的3个属性),其常用属性如下所示。
<update
id="updateUser"
parameterType="com.ssm.po.User"
flushCache="true"
statementType="PREPARED"
timeout="20">
<delete
id="deleteUser"
parameterType="com.ssm.po.User"
flushCache="true"
statementType="PREPARED"
timeout="20">
从上述配置代码中可以看出,<update>
元素和<delete>
元素的属性基本与<select>
元素中的属性一致。与<insert>
元素一样,<update>
元素和<delete>
元素在执行完之后,也会返回一个表示影响记录条数的整数,其使用示例如下。
更新用户信息
<update id="updateUser" parameterType="com.ssm.po.User">
update t_user set username=#{username}, jobs=#{jobs}, phone=#{phone} where id=#{id}
</update>
删除用户信息
<delete id="deleteUser" parameterType="Integer">
delete from t_user where id=#{id}
</delete>
sql元素
在一个映射文件中,通常需要定义多条SQL语句,这些SQL语句的组成可能有一部分是相同的(如多条select语句中都查询相同的id、username、jobs字段),如果每一个SQL语句都重写一遍相同的部分,势必会增加代码量,导致映射文件过于臃肿。那么有没有什么办法将这些SQL语句中相同的组成部分抽取出来,然后在需要的地方引用呢?答案是肯定的,我们可以在映射文件中使用MyBatis提供的<sql>
元素来解决上述问题。
<sql>
元素的作用是定义可重用的SQL代码片段,然后在其他语句中引用这一代码片段。例如,定义一个包含id、username、jobs和phone字段的代码片段:
<sql id ="user Columns">id,username,jobs,phone</sql>
这一代码片段可以包含在其他语句中使用,具体如下:
<select id="findUserById" parameterType="Integer" resultType="com.ssm.po.User">
select <include refid="user Columns">
from t_user
where id =#{id}
</select>
在上述代码中,使用元素的refid属性引用了自定义的代码片段,refid属性值为自定义代码片段的id。
resultMap元素
<resultMap>
元素表示结果映射集,主要作用是定义映射规则、级联更新以及定义类型转化器等。< resultMap>
元素中包含一些子元素,元素结构如下所示。
<!--resultMap的元素结构-->
<resultMap type="" id="">
<constructor> <!--类在实例化时,用来注入结果到构造方法中-->
<idArg /> <!--ID参数,标记结果为ID-->
<arg /> <!--注入到构造方法的一个普通结果-->
</constructor>
<id /> <!--用于表示那个列是主键-->
<result /> <!--注入到字段或JavaBeab属性的普通结果-->
<association property="" /> <!--用于一对一关联-->
<collection property="" /> <!--用于一对多关联-->
<discriminator iavaType=""> <!--使用结果值来决定使用哪个结果映射-->
<case value="" /> <!--基于某些值的结果映射-->
</discriminator>
</resultMap>
<resultMap>
元素的type属性表示需要映射的POJO,id属性是这个resultMap的唯一标识。它的子元素<constructor>
用于配置构造方法(当一个POJO中未定义无参的构造方法时,就可以使用<constructor>
元素进行配置)。子元素<id>
用于表示哪个列是主键,而<result>
用于表示POJO和数据表中普通列的映射关系。<association>
和<collection>
用于处理多表时的关联关系,而<discriminator>
元素主要用于处理一个单独的数据库查询返回很多不同数据类型结果集的情况。
在默认情况下,MyBatis程序在运行时会自动地将查询到的数据与需要返回的对象的属性进行匹配赋值(需要表中的列名与对象的属性名称完全一致)。然而实际开发时,数据表中的列和需要返回的对象的属性可能不会完全一致,这种情况下MyBatis是不会自动赋值的。此时,就可以使用<resultMap>
元素进行处理,示例代码UserMapper.xml如下所示。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ssm.mapper.UserMapper">
<resultMap type="com.ssm.po.User.UserMapper" id="resultMap">
<id property="id" column="t_id"/>
<result property="name" column="t_username"/>
<result property="age" column="t_age"/>
</resultMap>
<select id="findAllUser" resultMap="resultMap">-->
select * from t_user
</select>
</mapper>
<resultMap>
的子元素<id>
和<result>
的property属性表示User类的属性名,column属性表示数据表t_user的列名。<select>
元素的resultMap属性表示引用上面定义的resultMap。接下来可以在配置文件中引入UserMapper.xml。