有時候新增一條數據,知道新增成功即可,但是有時候,需要這條新增數據的主鍵,以便邏輯使用,再將其查詢出來明顯不符合要求,效率也變低了。
這時候,通過一些設置,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 測試成功
2 自增主鍵的獲取方法,說完了,下面來講講非自增主鍵的獲取方法。大致一樣,些許不同。
由於只有一張表,這里又新建了一張表,對應的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