开启事务时mybatis返回主键id

先说一下没有注解的

 

先给出实体类:

public class City {
    private int city_id;
    private String city_name;
    public int getCity_id() {
        return city_id;
    }
    public void setCity_id(int city_id) {
        this.city_id = city_id;
    }
    public String getCity_name() {
        return city_name;
    }
    public void setCity_name(String city_name) {
        this.city_name = city_name;
    }
    @Override
    public String toString() {
        return "City [city_id=" + city_id + ", city_name=" + city_name + "]";
    }
    
    
}

 

 

以下为mysql的示例:

 

当我们插入一条数据的时候,需要创建一个对象,然后无论是在xml中,或者使用注解的形式,直接插入就可以了,但是需要创建一个对象来插入

 

这里我演示新增一个城市,为了简单,我就直接操作dao层了,按理来说应该从service中操作的:

    @RequestMapping("/test")
    public void test(){
        City c = new City();
        c.setCity_name("赣州");
        baseDao.addCity(c);
        System.out.println(c);
    }

上面是一个控制层,我直接new了一个城市的对象,但是并没有设置它的id,直接传到了dao层来操作,下面看dao层的代码:

 

    @Insert("insert into t_city(city_name)values(#{city_name})")
    @SelectKey(statement="SELECT LAST_INSERT_ID()",keyProperty="city_id",before=false,resultType=Integer.class)
    public void addCity(City c);

@insert注解还是和往常一样,没有变化。

重要的是@SelectKey注解,是它完成了返回主键id的功能,上面来具体说明一下

statement这个属性,它是与数据库相关的,代表着查询主键id的功能,MySql是

SELECT LAST_INSERT_ID()

Oracle是

CALL IDENTITY()  

 

keyProperty,代表着传入对象的主键id属性,所以之前说,传入的必须是一个对象,因为当插入完成后,mybaits会通过反射,掉用这个对象的set方法,把对应的id值set进去这个对象,然后在外部,就可以直接取这个对象的id属性了,这样就完成了返回主键的功能

 

 

可能 xml用的比较多一点,这里也给出xml的代码:

<insert id="insert" parameterType="实体类的地址">  
    insert into t_city (city_name) values (#{city_name})  
    <selectKey resultType="java.lang.Integer" keyProperty="city_id">
SELECT LAST_INSERT_ID()
</selectKey> </insert>

 

 

下面就是重头戏了

在有事务的时候,如何返回主键id呢?

大家都知道,开启事务的时候,是为了可以在发生异常的时候,回滚数据。那么由于这样的一个机制,在@transaction中的这个方法,如果没有执行完毕,是不会真正的操作数据库的,那么这个时候,既然没有在数据库里插入数据时候,怎么能知道数据库的主键id呢?

其实我在网上看到好多人都束手无策,但是其实是有办法解决了,mybaits真的非常强大。

 

下面给出xml的代码:

    <insert id="addCity" parameterType="com.ujia.modular.base.dao.BaseDao" useGeneratedKeys="true" keyProperty="city_id">
        insert into t_city(city_name)values(#{city_name})
    </insert>

大家可能会惊讶的发现,这里的代码竟然更少了,但是实现的效果竟然是一样的,而且更加强大。它可以在事务中,得到主键id。那么上面的参数简单的说明一下

useGeneratedKeys是使用mybaits生成的key,这一步很重要,需要数据库支持自动生成才能做到。只要指定为true,那么mybaits就会从数据库中获取生成策略,然后计算后主键id,并且设置到该对象中,那么keyProperty就是之前说所的,标明主键id,在对象中的属性名称。

 

 

如果使用注解的话,依然可以保持上面的方式:

    @Insert("insert into t_city(city_name)values(#{city_name})")
    @SelectKey(statement="SELECT LAST_INSERT_ID()",keyProperty="city_id",before=false,resultType=Integer.class)
    public void addCity(City c);

 

这里的一切代码,都是在mysql环境下测试的,本来并没有测试过oracle数据库,但是博主觉得肯定是可以的

posted @ 2016-01-26 11:21  朱小杰  阅读(4411)  评论(2编辑  收藏