好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

mybatis如何批量添加一对多中间表

批量添加一对多中间表

建立中间表A,一个id对应多个lid;

传入两条参数

?

1

2

long id; //单个数值

List lid; //集合数值

dao层语句

?

1

int insertb(@Param( "id" )long id,@Param( "lid" )List lid);

mybatis中的写法

?

1

2

3

4

insert into A(id,lid) values

        <foreach collection= "lid" item= "data" separator= "," >

            (#{id},#{data})

        </foreach>

多对多条件下插入中间表(使用insert标签的属性)

说下需求

我的数据库中有两张表,一张是Blog表,一张是Type表,分别代表了博客和博客类别,它们之间是多对多关系,它们由一张中间表blog_type维护。

(简单起见,blog表只有两个数据,id和title。type表只有id和name)

那么需求就是:

现在我想插入一条Blog数据,因为blog和type是多对多关系,想插入其中一个数据,就得维护他们之间那个中间表blog_type的关系(插入中间表字段)。

解决方案

那么我能想到的解决方案是:

写两段insert标签,第一段sql语句插入blog表,第二段sql语句插入insert表:

?

1

2

3

4

5

6

7

< insert id= "insertBlogWithoutType" parameterType= "blog" >

     insert into t_blog (title)

     values (#{title});

</ insert >

< insert id= "insertBlog_Type" >

     insert into blog_type (bid, tid) values (#{blog.id},#{type.id})

</ insert >

但是这么做会有它的问题

由于blog表id为自增,所以我并没有插入id。如何在第二个insert查询语句中获取刚刚插入的id呢?

经过多方查找我发现了解决方案:

要用到MyBatis中insert标签的三个属性:

useGeneratedKeys (仅对 insert 和 update 有用)这会令 MyBatis 使用 JDBC 的 getGeneratedKeys 方法来取出由数据库内部生成的主键(比如:像 MySQL 和 SQL Server 这样的关系数据库管理系统的自动递增字段),默认值:false。 keyProperty (仅对 insert 和 update 有用)唯一标记一个属性,MyBatis 会通过 getGeneratedKeys 的返回值或者通过 insert 语句的 selectKey 子元素设置它的键值,默认:unset。如果希望得到多个生成的列,也可以是逗号分隔的属性名称列表。 keyColumn (仅对 insert 和 update 有用)通过生成的键值设置表中的列名,这个设置仅在某些数据库(像 PostgreSQL)是必须的,当主键列不是表中的第一列的时候需要设置。如果希望得到多个生成的列,也可以是逗号分隔的属性名称列表。

重新生成的代码如下所示:

?

1

2

3

4

5

6

7

< insert id= "insertBlogWithoutType" parameterType= "blog" useGeneratedKeys= "true" keyProperty= "id" keyColumn= "id" >

     insert into t_blog (title)

     values (#{title});

</ insert >

< insert id= "insertBlog_Type" >

     insert into blog_type (bid, tid) values (#{blog.id},#{type.id})

</ insert >

注意!keyProperty是Java对象的属性名!不是数据库表中字段名!

测试

编写Dao层

?

1

2

3

//分成两个方法,但是他们两个将在Service层合二为一

     int insertBlogWithoutType(Blog blog);

     int insertBlog_Type(@Param( "blog" )Blog blog, @Param( "type" )Type type);

Dao层就是对应的前面mapper文件里的两个方法

Service层

?

1

2

3

4

5

6

public void insertBlog(Blog blog, List<Type> types) {

         blogDao.insertBlogWithoutType(blog);

         for (Type type : types) {

             blogDao.insertBlog_Type(blog, type);

         }

     }

这里的意思是,先插入一个传进来的blog(第一个参数)。然后插入之后根据插进来的blog的主键(blog的id)和传入的type的主键(type的id),插入中间表。

Test类

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

@Test

     public void test2(){

         ApplicationContext context = new ClassPathXmlApplicationContext( "applicationContext.xml" );

         BlogService blogServiceImpl = (BlogService) context.getBean( "BlogServiceImpl" );

         //设置blog

         Blog blog = new Blog();

         blog.setTitle( "【MyBatis】多对多条件下插入中间表(使用insert标签的属性)" );

        

         //设置该blog对应的type

         List<Type> types = new ArrayList<Type>();

         types.add( new Type( 1 , "数据库" ));

         types.add( new Type( 2 , "Debug专题" ));

         blogServiceImpl.insertBlog(blog, types);

     }

可以看到,设置blog的时候,并没有设置blog的id属性,但是调用insertBlog时,插入中间表却已经知道了blog的id属性。这就是MyBatis中insert标签的三个属性的作用了!

执行完上面的代码,数据库里既插入了一条新的blog,又维护了他们之间那个中间表blog_type的关系(插入了中间表),至此问题解决。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持。

原文链接:https://blog.csdn.net/whwwycl/article/details/92803335

查看更多关于mybatis如何批量添加一对多中间表的详细内容...

  阅读:17次