昆明北京網(wǎng)站建設(shè)網(wǎng)絡(luò)營(yíng)銷的五個(gè)發(fā)展階段
簡(jiǎn)單介紹:
在某些時(shí)候,我們?cè)诓迦胪瓿梢粭l語(yǔ)句之后,我們會(huì)想要返回之前插入的這條語(yǔ)句的主鍵列的數(shù)據(jù),進(jìn)行下一步的展示或者修改,我們就可以使用MyBatis的主鍵回寫(xiě)功能,幫助我們獲取插入成功的一條數(shù)據(jù)的主鍵列。不同的數(shù)據(jù)庫(kù)獲取主鍵列的方式不同,主要針對(duì)兩種情況:一種是主鍵支持自增的情況,一種是主鍵不支持自增的情況。我們會(huì)針對(duì)這兩種情況分別進(jìn)行說(shuō)明。
前期準(zhǔn)備:
在數(shù)據(jù)庫(kù)方面,我們需要準(zhǔn)備一個(gè)數(shù)據(jù)庫(kù),并在里面提前存放一些數(shù)據(jù):
注意這里我們并沒(méi)有設(shè)置主鍵,我們先演示沒(méi)有主鍵或主鍵不支持自增的時(shí)候的情況,之后再添加主鍵演示當(dāng)支持主鍵自增時(shí)候的情況。然后就是MyBatis環(huán)境的基本準(zhǔn)備,如果之前有一個(gè)可以運(yùn)行的MyBatis的基礎(chǔ)環(huán)境這一步就可以省略了。
實(shí)現(xiàn)原理:
如果這個(gè)表支持主鍵自增的情況,在我們使用<insert>進(jìn)行插入的時(shí)候,可以使用幾個(gè)特殊的屬性:
keyProperty:這個(gè)屬性用來(lái)設(shè)置返回的主鍵復(fù)制給POJO實(shí)體類的那一個(gè)屬性。
keyColumn:這個(gè)屬性用來(lái)設(shè)置第幾列是主鍵,當(dāng)主鍵不是數(shù)據(jù)表中的第一列的時(shí)候需要設(shè)置。
useGeneratedKeys:該屬性會(huì)使MyBatis調(diào)用JDBC的getGeneratedKeys()方法來(lái)獲取由數(shù)據(jù)庫(kù)內(nèi)部生產(chǎn)的主鍵,比如MySQL中的自動(dòng)遞增的字段,默認(rèn)值使false。說(shuō)人話就是MySQL支持逐漸自增,也就是說(shuō)如果這個(gè)表里有一個(gè)列自增了,那么這個(gè)自增的列就是主鍵。因?yàn)樵贛ySQL中只有主鍵是支持自增的,其他的列不會(huì)自增,所以MyBatis就會(huì)捕捉到這個(gè)現(xiàn)象,并將自增的數(shù)據(jù)返回到我們的POJO實(shí)體類中,這樣就可以獲取到這個(gè)自增的主鍵列。
但是當(dāng)這個(gè)表中的主鍵不支持自增的時(shí)候,就需要使用特殊的規(guī)則獲取我們插入的主鍵,或者我們自定義規(guī)則插入一個(gè)主鍵然后獲取,這時(shí)候就需要我們的另一個(gè)標(biāo)簽:selectKey
這個(gè)標(biāo)簽用來(lái)配置我們的主鍵規(guī)則,因?yàn)樵谟行r(shí)候,我們不會(huì)插入主鍵,但是主鍵是必須的,所以我們會(huì)設(shè)定一個(gè)規(guī)則來(lái)幫助我們?cè)跊](méi)有主鍵自增長(zhǎng)的時(shí)候還能自動(dòng)插入主鍵:
這個(gè)標(biāo)簽有幾個(gè)常用的屬性:
keyProperty,resultType,order,statementType。其中其他幾個(gè)屬性的作用和上面的一樣,order屬性的值有兩個(gè):BAFORE和AFTER。BEFORE表示在執(zhí)行插入語(yǔ)句之前先執(zhí)行selectKey中配置的SQL語(yǔ)句,一般用于無(wú)法手動(dòng)插入主鍵的時(shí)候使用。AFTER表示在插入語(yǔ)句之后再執(zhí)行selectKey中配置的SQL語(yǔ)句,一般用于手動(dòng)插入主鍵時(shí)使用。
1.當(dāng)數(shù)據(jù)庫(kù)的主鍵不支持自動(dòng)增長(zhǎng)或者主鍵沒(méi)有設(shè)置自動(dòng)增長(zhǎng)的時(shí)候:
代碼實(shí)現(xiàn):
我們首先來(lái)看當(dāng)不支持主鍵自增的時(shí)候我們?nèi)绾问褂肑ava代碼幫助我們自動(dòng)插入主鍵:
SQL語(yǔ)句映射文件:
<!-- 測(cè)試主鍵回寫(xiě)--><insert id="insertAuto" parameterType="student"><selectKey keyProperty="id" order="BEFORE" resultType="Integer">
# 設(shè)置自動(dòng)添加主鍵的規(guī)則,表示當(dāng)主鍵列的最大值為空,表示這是第一條數(shù)據(jù)的時(shí)候,返回1,如果這條主鍵列最大的值不是null,則返回最大的值再加一
# 使用這種方法也可以達(dá)到主鍵自增的效果select if(max(id) is null ,1,max(id) + 1) as idNum from student;</selectKey>insert into student values (#{id},#{name},#{password});</insert>
接口映射文件:
package Mappers;
import com.mybatis.POJO.student;
import com.mybatis.POJO.user;import java.util.List;public interface select {public student selectOne(int i);public List<student> selectAll();public student selectName();public void insertInto(student s);public int deleteOne(int i);public void insertAuto(student s);
}
?測(cè)試類:
package Mappers;import com.mybatis.POJO.Tools.createSqlSession;
import com.mybatis.POJO.student;
import org.apache.ibatis.session.SqlSession;public class TestInsertAuto {select mapper = null;SqlSession session = null;@org.junit.Testpublic void insertNotAuto(){
// 使用工具類獲取連接mapper = new createSqlSession().createMapper();
// 測(cè)試接口中映射的方法
// 創(chuàng)建插入表中的對(duì)應(yīng)的POJO類的對(duì)象
// 注意我們并不設(shè)置主鍵列也就是id的值,主要是為了查看能否達(dá)到自動(dòng)填充并增加的效果student s = new student();s.setName("趙六");s.setPassword("1234556");mapper.insertAuto(s);
// 遍歷數(shù)據(jù)庫(kù)中的數(shù)據(jù)for (student student : mapper.selectAll()) {System.out.println(student);}
// 然后我們?cè)佾@取一次看能不能獲取的對(duì)象的id的值System.out.println("插入的數(shù)據(jù)的id值是:"+s.getId());}
}
運(yùn)行結(jié)果:
可以看到,在我們沒(méi)有設(shè)置id的值的時(shí)候,我們依然完成了主鍵的自增和獲取,這就說(shuō)明我們之前的配置是正確的。?
注意點(diǎn):
整個(gè)的運(yùn)行流程是當(dāng)我們插入一條數(shù)據(jù)的時(shí)候,因?yàn)槲覀僺electKey的order屬性配置的是BEFORE,所以我們首先會(huì)執(zhí)行selectKey中的語(yǔ)句,然后他會(huì)判斷我們數(shù)據(jù)表的主鍵列是否有數(shù)據(jù),如果有數(shù)據(jù),則獲取最大的數(shù)據(jù)加一得到一個(gè)新的數(shù)據(jù)。這個(gè)過(guò)程就是我們?cè)趕electKey中配置的SQL語(yǔ)句來(lái)幫我們完成的。然后selectKey的另外兩個(gè)屬性,keyProperty的值表示將得到的數(shù)據(jù)插入到POJO實(shí)體類的哪一個(gè)屬性中,resultType的值表示這個(gè)值的類型。然后執(zhí)行insert標(biāo)簽中的SQL語(yǔ)句,最后將數(shù)據(jù)插入完成之后,會(huì)將我們剛才設(shè)置的值返回給student類,我們就可以通過(guò)getId的方法得到我們剛才自動(dòng)生成的值。
需要注意的是我們要明確selectKey中配置的SQL語(yǔ)句是幫助我們自動(dòng)生成主鍵的值的,這個(gè)值會(huì)被復(fù)制給POJO類的id屬性。然后就是SQL語(yǔ)句中的if語(yǔ)句的使用方法。
1.當(dāng)數(shù)據(jù)庫(kù)的主鍵支持自動(dòng)增長(zhǎng)并且設(shè)置了自動(dòng)增長(zhǎng)的時(shí)候:
實(shí)現(xiàn)原理:
當(dāng)主鍵設(shè)置了自動(dòng)增長(zhǎng)的時(shí)候,就不需要我們手動(dòng)填充主鍵,MyBatis會(huì)自動(dòng)的幫我們?nèi)z測(cè)某一列的值是否自動(dòng)增加了,如果在我們沒(méi)有填充的情況下自動(dòng)填充了,那么這個(gè)列就是主鍵,MyBatis會(huì)自動(dòng)幫我們把填充后的值獲取到,我們只需要正確的配置即可。
代碼實(shí)現(xiàn):
SQL映射文件:
<!-- 當(dāng)支持主鍵自增時(shí)候的主鍵回寫(xiě)--><insert id="insertAuto" parameterType="student" keyProperty="id" useGeneratedKeys="true">insert into student values (#{id},#{name},#{password});</insert>
接口文件:
package Mappers;
import com.mybatis.POJO.student;
import com.mybatis.POJO.user;import java.util.List;public interface select {public student selectOne(int i);public List<student> selectAll();public student selectName();public void insertInto(student s);public int deleteOne(int i);public void insertNotAuto(student s);public void insertIntoAuto(student s);
}
?測(cè)試類:
@org.junit.Testpublic void insertIntoAuto(){// 使用工具類獲取連接mapper = new createSqlSession().createMapper();
// 測(cè)試接口中映射的方法,這次測(cè)試的是帶有主鍵自增的數(shù)據(jù)表student s = new student();s.setName("趙六");s.setPassword("1234556");mapper.insertIntoAuto(s);
// 遍歷數(shù)據(jù)庫(kù)中的數(shù)據(jù)for (student student : mapper.selectAll()) {System.out.println(student);}
// 然后我們?cè)佾@取一次看能不能獲取的對(duì)象的id的值System.out.println("插入的數(shù)據(jù)的id值是:"+s.getId());}
運(yùn)行結(jié)果:
?可以看到,在我們沒(méi)有設(shè)置id主鍵值的時(shí)候,自動(dòng)填充主鍵值的操作是由數(shù)據(jù)庫(kù)完成的,而MyBatis負(fù)責(zé)監(jiān)控那一列的值自動(dòng)填充了,并返回這一列的值讓我們可以通過(guò)對(duì)象查詢到
注意點(diǎn):
唯一的注意點(diǎn)就是當(dāng)我們需要區(qū)分我們具體是操作何種情況,合理的使用這兩種方法返回的結(jié)果