一、前言
数据库操作怎能少了INSERT操作呢?下面记录MyBatis关于INSERT操作的笔记,以便日后查阅。
二、 insert元素
其属性如下:
parameterType
keyColumn
keyProperty
useGeneratedKeys
statementType
flushCache
timeout
databaseId
三、一般的INSERT操作——返回值为插入的记录数目
mapper接口代码:
/**
* 添加学生信息
* @param student 学生实例
* @return 成功操作的记录数目
*/
long add(EStudent student);
mapper.xml:
<insert id="add" parameterType="EStudent">
insert into TStudent(name, age) values(#{name}, #{age})
</insert
四、执行INSERT操作后获取记录主键
学生实体类
public class EStudent {
private long id;
private String name;
private String age;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
}
mapper接口代码:
/**
* 添加学生信息
* @param student 学生实例
* @return 成功操作的记录数目
*/
long add(EStudent student);
至于mapper.xml则分为两种情况了,一种是数据库(如MySQL,SQLServer)支持auto-generated key field,另一种是数据库(如Oracle)不支持auto-generated key field的。
1. 数据库(如MySQL,SQLServer)支持auto-generated key field的情况
手段①(推荐做法):
<insert id="add" parameterType="EStudent" useGeneratedKeys="true" keyProperty="id"> <!--此处的id为实体类中对应的id-->
insert into TStudent(name, age) values(#{name}, #{age})
</insert>
测试类中获取返回的主键id
@Test
public void test() {
EStudent eStudent = new EStudent();
eStudent.setName("小小");
eStudent.setAge("18");
//返回值row为受影响的行数
long row = eStudentDao.add(eStudent);
//因为在mapper中已经把主键映射到实体(EStudent)中了,所以要从实体中获取返回的主键id
System.out.println("获取返回的主键id:"+eStudent.getId());
}
手段②:
<insert id="add" parameterType="EStudent">
// 下面是SQLServer获取最近一次插入记录的主键值的方式
<selectKey resultType="_long" keyProperty="id" order="AFTER">
select @@IDENTITY as id
</selectKey>
insert into TStudent(name, age) values(#{name}, #{age})
</insert>
由于手段②获取主键的方式依赖数据库本身,因此推荐使用手段①。
2. 数据库(如Oracle)不支持auto-generated key field的情况
<insert id="add" parameterType="EStudent">
<selectKey keyProperty="id" resultType="_long" order="BEFORE">
select CAST(RANDOM * 100000 as INTEGER) a FROM SYSTEM.SYSDUMMY1
</selectKey>
insert into TStudent(id, name, age) values(#{id}, #{name}, #{age})
</insert
注意:mapper接口返回值依然是成功插入的记录数,但不同的是主键值已经赋值到领域模型实体的id中了。
五、 selectKey子元素
作用:在insert元素和update元素中插入查询语句。
其属性如下:
keyProperty
resultType
order属性
statementType
注意:selectKey操作会将操作查询结果赋值到insert元素的parameterType的入参实例下对应的属性中。并提供给insert语句使用
六、批量插入
方式1:
<insert id="add" parameterType="EStudent">
<foreach collection="list" item="item" index="index" separator=";">
INSERT INTO TStudent(name,age) VALUES(#{item.name}, #{item.age})
</foreach>
</insert>
上述方式相当语句逐条INSERT语句执行,将出现如下问题:
1. mapper接口的add方法返回值将是最一条INSERT语句的操作成功的记录数目(就是0或1),而不是所有INSERT语句的操作成功的总记录数目
2. 当其中一条不成功时,不会进行整体回滚。
方式2(仅限于MSSQL):
<insert id="add" parameterType="EStudent">
WITH R AS
<foreach collection="list" item="item" index="index" open="(" close=")" separator="union all">
SELECT #{item.name} as a, #{item.age} as b
</foreach>
INSERT INTO TStudent(name,age) SELECT a, b FROM R
</insert>
上述方式解决了方式1中的问题。但该方式仅限于MSSQL
方式3(通用解决方法)方式3(MSSQL):
INSERT INTO TStudent(name,age)
<foreach collection="list" item="item" index="index" open="(" close=")" separator="union all">
SELECT #{item.name} as a, #{item.age} as b
</foreach>
该方式与方式2效果一样,若为Oracle则采用
INSERT INTO TStudent(name,age)
<foreach collection="list" item="item" index="index" open="(" close=")" separator="union all">
SELECT #{item.name} as a, #{item.age} as b FROM DUAL
</foreach>
六、批量查询
1. 在接口UserMapper中添加批量查询方法。
1. /**
2. * 批量查询操作
3. * @param ids
4. * @return
5. */
6. public List<User> batchSelectUsers(List ids);
2.在User.xml中添加批量查询操作的配置。
1. <!-- 批量查询操作 -->
2. <select id="batchSelectUsers" resultType="User">
3. select *
4. from mhc_user where id in
5. <foreach collection="list" index="index" item="item" open="(" separator="," close=")">
6. #{item}
7. </foreach>
8. </select>