有時候新增一條數據,知道新增成功即可,但是有時候,需要這條新增數據的主鍵,以便邏輯使用,再將其查詢出來明顯不符合要求,效率也變低了。
這時候,通過一些設置,mybatis可以將insert的數據的主鍵返回,直接拿到新增數據的主鍵,以便后續使用。
這里主要說的是selectKey標簽
設計表的時候有兩種主鍵,一種自增主鍵,一般為int類型,一種為非自增的主鍵,例如用uuid等。
自增類型的主鍵
1 映射xml中添加如下代碼,注釋寫的很清楚了,不多做贅述。
<!--新增信息,並拿到新增信息的表主鍵信息。 新增數據,得到主鍵的外層寫法沒什么特別,跟普通的insert一樣。只不過里面加了selectKey--> <insert id="insertAndgetkey" parameterType="com.soft.mybatis.model.User"> <!--selectKey 會將 SELECT LAST_INSERT_ID()的結果放入到傳入的model的主鍵里面, keyProperty 對應的model中的主鍵的屬性名,這里是 user 中的id,因為它跟數據庫的主鍵對應 order AFTER 表示 SELECT LAST_INSERT_ID() 在insert執行之后執行,多用與自增主鍵, BEFORE 表示 SELECT LAST_INSERT_ID() 在insert執行之前執行,這樣的話就拿不到主鍵了, 這種適合那種主鍵不是自增的類型 resultType 主鍵類型 --> <selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer"> SELECT LAST_INSERT_ID() </selectKey> insert into t_user (username,password,create_date) values(#{username},#{password},#{createDate}) </insert>
2 接口 UserDao
/** * 新增用戶信息,並得到新增數據的主鍵 * 主鍵自增 * @return */ int insertAndGeyKey(User user);
3 實現類 UserDaoImpl
public int insertAndGeyKey(User user) { SqlSession sqlSession = null; try { sqlSession = SqlsessionUtil.getSqlSession(); int key = sqlSession.insert("test.insertAndgetkey",user); // commit sqlSession.commit(); return key; } catch (Exception e) { sqlSession.rollback(); e.printStackTrace(); } finally { SqlsessionUtil.closeSession(sqlSession); } return 0; }
接下來就是測試了,
UserDaoTest
/** * 注意,user.xml中已經說過,selectKey會將得到的主鍵放入model的主鍵屬性中, * 所以這里獲取主鍵的方法一定是通過model.get主鍵才能獲取新增的主鍵 * @throws Exception */ @Test public void insertAndGeyKey() throws Exception { User user = new User(); user.setUsername("新增得到主鍵5"); user.setPassword("123456"); user.setCreateDate(new Date()); int result = dao.insertAndGeyKey(user); System.out.println("insertAndGeyKey :" + result); // 獲取新增數據主鍵 System.out.println("新增數據的主鍵 :" + user.getId()); }
數據庫表新增數據主鍵為 34
junit測試結果 得到主鍵 34 測試成功。
非自增主鍵
由於只有一張表,這里又新建了一張表,對應的xml,別忘了將新建的xml添加到sqlMapConfig.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"> <!-- namespace命名空間,有種java package的感覺,sql隔離,這個名字必須唯一 並且不能省略不寫也不能為空,不過名字倒是可以隨意,只要不跟另外一個文件中的名字一樣即可--> <mapper namespace="customer"> <!-- 跟普通的insert沒有什么不同的地方 --> <insert id="insert" parameterType="com.soft.mybatis.model.Customer"> <!-- 跟自增主鍵方式相比,這里的不同之處只有兩點 1 insert語句需要寫id字段了,並且 values里面也不能省略 2 selectKey 的order屬性需要寫成BEFORE 因為這樣才能將生成的uuid主鍵放入到model中, 這樣后面的insert的values里面的id才不會獲取為空 跟自增主鍵相比就這點區別,當然了這里的獲取主鍵id的方式為 select uuid() 當然也可以另寫別生成函數。--> <selectKey keyProperty="id" order="BEFORE" resultType="String"> select uuid() </selectKey> insert into t_customer (id,c_name,c_sex,c_ceroNo,c_ceroType,c_age) values (#{id},#{name},#{sex},#{ceroNo},#{ceroType},#{age}) </insert> </mapper>
接口 CustomerDao
package com.soft.mybatis.dao; import com.soft.mybatis.model.Customer; /** * Created by xuweiwei on 2017/9/10. */ public interface CustomerDao { int add(Customer customer); }
實現類 CustomerDaoImpl
package com.soft.mybatis.dao.impl; import com.soft.mybatis.Util.SqlsessionUtil; import com.soft.mybatis.dao.CustomerDao; import com.soft.mybatis.model.Customer; import org.apache.ibatis.session.SqlSession; /** * Created by xuweiwei on 2017/9/10. */ public class CustomerDaoImpl implements CustomerDao { public int add(Customer customer) { SqlSession sqlSession = null; try { sqlSession = SqlsessionUtil.getSqlSession(); int key = sqlSession.insert("customer.insert", customer); // commit sqlSession.commit(); return key; } catch (Exception e) { sqlSession.rollback(); e.printStackTrace(); } finally { SqlsessionUtil.closeSession(sqlSession); } return 0; } }
准備工作完畢,下面進行測試。
執行前的數據
測試類 CustomerDaoImplTest
package com.soft.mybatis.dao.impl; import com.soft.mybatis.dao.CustomerDao; import com.soft.mybatis.model.Customer; import org.junit.Test; import static org.junit.Assert.*; /** * Created by xuweiwei on 2017/9/10. */ public class CustomerDaoImplTest { private CustomerDao customerDao = new CustomerDaoImpl(); @Test public void add() throws Exception { Customer customer = new Customer(); customer.setName("全球鷹1"); customer.setAge(15); customer.setCeroNo("888888888888"); customer.setCeroType(2); customer.setSex(1); int result = customerDao.add(customer); System.out.println("插入結果 : "+result); System.out.println("插入主鍵id : "+customer.getId()); } }
測試結果
數據庫
可以看到新增的數據的主鍵已經獲取到了。
注意點:獲取主鍵,一定要從穿進去的model中獲取。
附 新增customer表的建表ddl
CREATE TABLE `t_customer` ( `id` varchar(50) NOT NULL, `c_name` varchar(20) DEFAULT NULL COMMENT '姓名', `c_sex` tinyint(4) DEFAULT NULL COMMENT '性別', `c_ceroNo` varchar(18) DEFAULT NULL COMMENT '證件號碼', `c_ceroType` tinyint(4) DEFAULT NULL COMMENT '1 身份證 2其他', `c_age` int(3) DEFAULT NULL COMMENT '年齡', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8