Mybatis獲取自增主鍵的值

WorkHaH發表於2022-01-03

pojo:

public class User {
    private Integer id;
    private String name;
    private String pwd;
    setter和getter....
}

資料庫:
在這裡插入圖片描述

1、獲取自增主鍵的值

對映檔案:

	<!-- UserMapper介面 public void addUser(User user); -->
	<insert id="addUser" parameterType="com.workhah.pojo.User" useGeneratedKeys="true" keyProperty="id" databaseId="mysql">
		insert into user(name,pwd) 
		values(#{name},#{pwd})
	</insert>

獲取自增主鍵的值:

  • \(Mysql\) 支援自增主鍵,自增主鍵值的獲取,\(Mybatis\) 也是利用statement.getGenreatedKeys()
  • useGeneratedKeys="true"使用自增主鍵獲取主鍵值策略
  • keyProperty指定對應的主鍵屬性,也就是\(Mybatis\) 獲取到主鍵值以後,將這個值封裝給\(javaBean\) 的哪個屬性。

測試獲取主鍵值:

    @Test
    public void test() {
        SqlSession sqlSession = getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        User user = new User(0, "workhah", "123");
        mapper.addUser(user); 
        System.out.println(user.getId());	// 14
        // 原本user表就有13條資料,現在插入一條資料該資料的id就為14,而且這個自增主鍵id的值返回了給user變數。
    }

原本user表就有13條資料,現在插入一條資料該資料的id就為14,而且這個自增主鍵id的值返回了給user變數。

因此要注意的是,想要獲取自增主鍵的值,必須得有對應得\(JavaBean\)類(如上例中的user變數),該類來封裝自增主鍵的值。

2、獲取非自增主鍵的值

Oracle不支援自增;Oracle使用序列來模擬自增;每次插入的資料的主鍵是從序列中拿到的值;

	<!-- UserMapper介面 public void addUser(User user); -->
	<insert id="addUser" databaseId="oracle">
		<selectKey keyProperty="id" order="BEFORE" resultType="Integer">
			<!-- 編寫查詢主鍵的sql語句 -->
			<!-- BEFORE-->
			select USER_SEQ.nextval from dual 
		</selectKey>
		
		<!-- 插入時的主鍵是從序列中拿到的 -->
		<!-- BEFORE:-->
		insert into user(id,name,pwd) 
		values(#{id},#{name},#{pwd})
	</insert>
  • keyProperty:查出的主鍵值封裝給 \(javaBean\) 的哪個屬性

  • order="BEFORE":當前 sql 在插入 sql 之前執行
    AFTER:當前 sql 在插入 sql 之後執行

    • BEFORE執行順序:
      先執行selectKey查詢 id 的 sql;查出 id 值封裝給 \(javaBean\) 的 id 屬性
      在執行插入的 sql;就可以取出 id 屬性對應的值
    • AFTER執行順序:
      先執行插入的 sql(從序列中取出新值作為 id)
      再執行selectKey查詢 id 的 sql;
  • resultType:查出的資料的返回值型別

測試獲取主鍵值:

    @Test
    public void test() {
        SqlSession sqlSession = MyTest.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        User user = new User(0, "workhah", "123");
        mapper.addUser(user); 
        System.out.println(user.getId());	// 12
    }

思考

問題

既然 selectKey提前執行把獲取到的主鍵值封裝到 \(JavaBean\) 中,然後再作為 sql 的輸入執行 sql 語句,那麼selectKey可不可以獲取的是其他的值,甚至是另一個表獲取的資料作為輸出呢

驗證

答案是可以的!
blog類

public class Blog {
    private int id;
    private String title;
    private String author;
    private String createTime;
    private int views;
    setter和getter....
}

對映檔案

<!-- UserMapper介面 public void updateUser(Blog blog); -->
<update id="updateUser" parameterType="user">
	<selectKey keyProperty="title" resultType="String" order="BEFORE">
		select title from blog where id = 1
	</selectKey>
	update user set name = #{title} where id = 13
</update>

測試

@Test
    public void test() {
        SqlSession sqlSession = MyTest.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        Blog blog = new Blog(0, null, null, null,0);
        System.out.println(blog);
        // 結果
        // Blog(id=0, title=Mybatis, author=null, createTime=null, views=0)
    }

資料庫
在這裡插入圖片描述

selectKey的返回值作為 sql 語句的輸入成功修改和資料庫,並且成功返回給了變數blog。這介面方法雖然可以實現跨表,但是需要用到Blog類引數協作,在實際開發中邏輯比較奇怪,這裡只是作為對問題猜測的驗證。

相關文章