MyBatis insert标签

MyBatis insert 标签用来定义插入语句,执行插入操作。当 MyBatis 执行完一条插入语句后,就会返回其影响数据库的行数。

下面通过一个示例演示 insert 标签的具体用法。

1. 修改 WebsiteMapper.xml,增加插入语句,代码如下。

<!-- 增加网站信息 -->
<insert id="addWebsite" parameterType="string">
    insert into website(name)
    values(#{name})
</insert>

2. 在 WebsiteMapper 接口中定义一个 add() 方法,代码如下。

public int addWebsite(String name);

参数为 Sting 类型的字符串;返回值为 int 类型,即执行 SQL 后,插入记录的行数。

3. 测试代码如下。

//插入 name 为编程帮4 的记录
String name = "编程帮4";
int i = websiteMapper.addWebsite(name);
System.out.println("共插入了 " + i + " 条记录");


4. 执行测试代码,控制台输出如下。

共插入了 1 条记录

insert 标签常用属性

insert 标签中常用的属性如下表。

属性名称 描述 备注
id 它和 Mapper 的命名空间组合起来使用,是唯一标识符,供 MyBatis 调用 如果命名空间+ id 不唯一,那么 MyBatis 抛出异常
parameterType 传入 SQL 语句的参数类型的全限定名或别名,它是一个可选属性。 支持基本数据类型和 JavaBean、Map 等复杂数据类型
keyProperty 该属性的作用是将插入操作的返回值赋给 PO 类的某个属性,通常为主键对应的属性。如果是联合主键,可以将多个值用逗号隔开。
useGeneratedKe 该属性用来设置,是否使用 JDBC 提供的 getGenereatedKeys() 方法,获取数据库内部产生的主键并赋值到 keyProperty 属性设置的请求对象的属性中,例如 MySQL、SQL Server 等自动递增的字段,其默认值为 false。 该属性值设置为 true 后,会将数据库生成的主键回填到请求对象中,以供其他业务使用。
flushCache 该属性用于设置执行该操作后,是否会清空二级缓存和本地缓存,默认值为 true。
timeout 该属性用于设置执行该操作的最大时限,如果超时,就抛异常。
databaseId 取值范围 oracle、mysql 等,表示数据库厂家;元素内部可通过 <if test="_databaseId = 'oracle'"> 来为特定数据库指定不同的 sql 语句。 MyBatis 可以根据不同的数据库厂商执行不同的语句,这种多厂商的支持是基于映射语句中的 databaseId 属性。 MyBatis 会加载不带 databaseId 属性和带有匹配当前数据库 databaseId 属性的所有语句。 如果同时找到带有 databaseId 和不带 databaseId 的相同语句,则后者会被舍弃。
keyColumn 该属性用于设置第几列是主键,当主键列不是表中的第 1 列时,就需要设置该属性。如果是联合主键,可以将多个值用逗号隔开。

注意:insert 标签中没有 resultType 属性,只有查询操作才需要对返回结果类型进行相应的指定。

传递多个参数

在上面的示例中,我们在插入语句中只使用了一个 String 类型的参数,而在实际的开发过程中,我们的插入语句往往需要使用多个参数,Mybatis 为我们提供以下 3 种方式,来实现给映射器传递多个参数:

  • 使用 Map 传递参数
  • 使用注解传递参数
  • 使用 JavaBean 传递参数

使用 Map 传递参数

我们可以将参数封装到一个 Map 对象中,然后传递给 MyBatis 的映射器,示例如下。

1. 在 WebsiteMapper 接口中,定义一个 addWebsiteByMap() 方法,并使用 Map 传递参数,方法如下。

int addWebsiteByMap(Map<String, String> params);

2. 在 WebsiteMapper.xml 中,使用 insert 标签定义一条插入语句,并接收通过 Map 传递的参数,配置如下。

<!--接收 Map 参数-->
<insert id="addWebsiteByMap" parameterType="map">
    insert into Website (name, url) values (#{name}, #{url})
</insert>

3. 测试代码如下。

Map<String, String> params = new HashMap<>();
params.put("name", "编程帮");
params.put("url", "https://www.biancheng.net/");
int i = websiteMapper.addWebsiteByMap(params);
System.out.println("通过 Map 成功向数据库中添加了 " + i + " 条记录");

4. 执行测试代码,控制台输出如下。

通过 Map 成功向数据库中添加了 1 条记录

使用注解传递参数

我们还可以使用 MyBatis 提供的 @Param 注解给注解器传递参数,示例代码如下。

1. 在 WebsiteMapper 接口中,定义一个 addWebsiteByParam() 方法,并使用 @Param 注解传递参数,方法如下

int addWebsiteByParam(@Param("name") String name, @Param("url") String url);

2. 在 WebsiteMapper.xml 中使用 insert 标签定义一条插入语句,并接收通过 @Param 注解传递的参数,配置如下。

<!--接收 @Param 注解传递的参数-->
<insert id="addWebsiteByParam">
    insert into Website (name, url)  values (#{name}, #{url})
</insert>

3. 测试代码如下。

int i = websiteMapper.addWebsiteByParam("bianchengbang", "www.biancheng.net");
System.out.println("通过 @Param 注解成功向数据库中添加了 " + i + " 条记录");

4. 执行测试代码,控制台输出如下。

通过 @Param 注解成功向数据库中添加了 1 条记录

使用 JavaBean 传递参数

在参数过多的情况下,我们可以将参数通过 setter 方法封装到 JavaBean(实体类)对象中 ,传递给映射器。

1. 在 WebsiteMapper 接口中,定义一个 addWebsiteByJavaBean() 方法,并使用 JavaBean 传递参数,方法如下。

int addWebsiteByJavaBean(Website website);

2. 在 WebsiteMapper.xml 中使用 insert 标签定义一条插入语句,并接收通过 JavaBean 传递的参数,配置如下。

<!--接收通过 JavaBean 传递的参数-->
<insert id="addWebsiteByJavaBean" parameterType="net.biancheng.www.po.Website">
    insert into Website (name, url) values (#{name}, #{url})
</insert>

3. 测试代码如下。

//创建 JavaBean 对象
Website website = new Website();
//通过 setter 方法将参数封装
website.setName("编程帮 JavaBean");
website.setUrl("www.biancheng.net");
int i = websiteMapper.addWebsiteByJavaBean(website);
System.out.println("通过 JavaBean 成功向数据库中添加了 " + i + " 条记录");

4. 执行测试代码,控制台输出如下。

通过 JavaBean 成功向数据库中添加了 1 条记录

区别

以上 3 种方式的区别如下:

  • 使用 Map 传递参数会导致业务可读性的丧失,继而导致后续扩展和维护的困难,所以在实际应用中我们应该果断废弃该方式。
  • 使用 @Param 注解传递参数会受到参数个数的影响。当 n≤5 时,它是最佳的传参方式,因为它更加直观;当 n>5 时,多个参数将给调用带来困难。
  • 当参数个数大于 5 个时,建议使用 JavaBean 方式。

主键(自动递增)回填

我们知道,MySQL、SQL Server 等数据库表可以采用自动递增的字段作为其主键,当向这样的数据库表插入数据时,即使不指定自增主键的值,数据库也会根据自增规则自动生成主键并插入到表中。

一些特殊情况下,我们可能需要将这个刚刚生成的主键回填到请求对象(原本不包含主键信息的请求对象)中,供其他业务使用。此时,我们就可以通过在 insert 标签中添加  keyProperty 和 useGeneratedKeys 属性,来实现该功能。

下面我们通过一个示例,来演示主键(自动递增)回填功能。

1. 为 WebsiteMapper.xml 中 id 为 addWebsite 的 insert 标签添加 keyProperty 和 useGeneratedKeys 属性,具体代码如下:

<!--添加一个网站信息,成功后将主键值返回填给id(po的属性)-->
<insert id="addWebsite" parameterType="net.biancheng.po.Website" keyProperty="id" useGeneratedKeys="true">
    insert into Website (name,url) values(#{name},#{url})
</insert>

2. 测试代码如下:

// 添加一个网站信息
Website addsite = new Website();
//插入的对象中不包含主键 id 
addsite.setName("编程帮");
addsite.setUrl("https://www.biancheng.net/");
//执行插入
int num = websiteMapper.addWebsite(addsite);
System.out.println("添加了 " + num + " 条记录");
//获取回填的主键
System.out.println("添加记录的主键是:" + addsite.getId());

3. 执行测试代码,控制台输出如下。

添加了 1 条记录
添加记录的主键是:3

自定义主键

如果在实际项目中,若数据库不支持主键自动递增(例如 Oracle),或者取消了主键自动递增的规则,我们可以使用 MyBatis 的 <selectKey> 标签自定义生成主键,具体配置代码如下。

<!-- 添加一个网站,#{name}为 net.biancheng.po.Website 的属性值 -->
<insert id="insertWebsite" parameterType="net.biancheng.po.Website">
    <!-- 先使用selectKey标签定义主键,然后再定义SQL语句 -->
    <selectKey keyProperty="id" resultType="Integer" order="BEFORE">
        select if(max(id) is null,1,max(id)+1) as newId from Website
    </selectKey>
    insert into Website (id,name,url) values(#{id},#{name},#{url})
</insert>

<selectKey> 标签中属性说明如下:

  • keyProperty:用于指定主键值对应的 PO 类的属性。
  • order:该属性取值可以为 BEFORE 或 AFTER。BEFORE 表示先执行 <selectKey> 标签内的语句,再执行插入语句;AFTER 表示先执行插入语句再执行 <selectKey> 标签内的语句。

原创文章,作者:奋斗,如若转载,请注明出处:https://blog.ytso.com/24132.html

(0)
上一篇 2021年7月20日
下一篇 2021年7月20日

相关推荐

发表回复

登录后才能评论