本篇會寫一支簡單的測試程式來測試MyBatis。
在前一篇使用SpringBoot打造記帳簿專案(十九)MyBatis設定中已經完成了MyBatis的設定,接著寫一支測試程式來試看看是否能正常工作。
開啟idv.matt.dao.MemberMapper.java
,然後新增一個查詢方法selectByNaturalKey()
如下:
package idv.matt.dao;
import idv.matt.entity.Member;
import java.util.List;
public interface MemberMapper {
int deleteByPrimaryKey(Long memberId);
int insert(Member record);
Member selectByPrimaryKey(Long memberId);
Member selectByNaturalKey(String memberAccount); // <-- 新增此方法
List selectAll();
int updateByPrimaryKey(Member record);
}
接著開啟idv.matt.mapper.MemberMapper.xml
,將MyBatis Generator(MBG)自動產生的<insert id="insert">
中的新增SQL修改如下:
<insert id="insert" parameterType="idv.matt.entity.Member">
insert into member (member_account, member_password,
member_name, member_status)
values (#{memberAccount,jdbcType=VARCHAR},
#{memberPassword,jdbcType=VARCHAR},
#{memberName,jdbcType=VARCHAR},
#{memberStatus,jdbcType=VARCHAR})
</insert>
因為先前的資料表設計中,資料表的主鍵id
欄位為自動遞增(AUTO_INCREMENT
),且create_time
及update_time
欄位預設為新增一筆資料時設為當下時間CURRENT_TIMESTAMP
,因此要將MBG自動產生的insert
條件中的這些欄位移除。
另外新增一個新的查詢SQL如下,此即為對應剛剛新增的selectByNaturalKey()
:
<select id="selectByNaturalKey" parameterType="java.lang.String" resultMap="BaseResultMap">
select member_id, member_account, member_password, member_name,
member_status, create_time, update_time
from member
where member_account = #{memberAccount,jdbcType=VARCHAR}
</select>
因為先前的資料表設計中,資料表的真正主鍵為代理鍵(Surrogate key),其為沒有業務意義的自動累加編號而已,MBG幫我們產生的mapper的selectByPrimaryKey()
是以代理鍵為查詢條件,所以沒什麼用處,所以這邊才會新增一個以業務鍵(Natural key)來查詢的方法。
修改完後的idv.matt.mapper.MemberMapper.xml
如下:
MemberMapper.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">
<mapper namespace="idv.matt.dao.MemberMapper">
<resultMap id="BaseResultMap"
type="idv.matt.entity.Member">
<id column="member_id" jdbcType="BIGINT" property="memberId" />
<result column="member_account" jdbcType="VARCHAR"
property="memberAccount" />
<result column="member_password" jdbcType="VARCHAR"
property="memberPassword" />
<result column="member_name" jdbcType="VARCHAR"
property="memberName" />
<result column="member_status" jdbcType="VARCHAR"
property="memberStatus" />
<result column="create_time" jdbcType="TIMESTAMP"
property="createTime" />
<result column="update_time" jdbcType="TIMESTAMP"
property="updateTime" />
</resultMap>
<delete id="deleteByPrimaryKey"
parameterType="java.lang.Long">
delete from member
where member_id = #{memberId,jdbcType=BIGINT}
</delete>
<!-- 修改這個 -->
<insert id="insert" parameterType="idv.matt.entity.Member">
insert into member (member_account, member_password,
member_name, member_status)
values (#{memberAccount,jdbcType=VARCHAR},
#{memberPassword,jdbcType=VARCHAR},
#{memberName,jdbcType=VARCHAR},
#{memberStatus,jdbcType=VARCHAR})
</insert>
<update id="updateByPrimaryKey"
parameterType="idv.matt.entity.Member">
update member
set member_account = #{memberAccount,jdbcType=VARCHAR},
member_password = #{memberPassword,jdbcType=VARCHAR},
member_name = #{memberName,jdbcType=VARCHAR},
member_status = #{memberStatus,jdbcType=VARCHAR},
create_time = #{createTime,jdbcType=TIMESTAMP},
update_time = #{updateTime,jdbcType=TIMESTAMP}
where member_id = #{memberId,jdbcType=BIGINT}
</update>
<select id="selectByPrimaryKey"
parameterType="java.lang.Long" resultMap="BaseResultMap">
select member_id, member_account, member_password, member_name,
member_status, create_time,
update_time
from member
where member_id = #{memberId,jdbcType=BIGINT}
</select>
<!-- 新增這個 -->
<select id="selectByNaturalKey"
parameterType="java.lang.String" resultMap="BaseResultMap">
select member_id, member_account, member_password, member_name,
member_status, create_time,
update_time
from member
where member_account = #{memberAccount,jdbcType=VARCHAR}
</select>
<select id="selectAll" resultMap="BaseResultMap">
select member_id, member_account, member_password, member_name,
member_status, create_time,
update_time
from member
</select>
</mapper>
完成以上修改後,在專案的src/test/java
下建立測試程式idv.matt.dao.MemberMapperTest
測試類別,用來測試src/main/java
下的idv.matt.dao.MemberMapper
。
MemberMapperTest.java
package idv.matt.dao;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.transaction.annotation.Transactional;
import idv.matt.application.MoneynoteApplication;
import idv.matt.entity.Member;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = { MoneynoteApplication.class })
@Transactional
public class MemberMapperTest {
@Autowired
private MemberMapper mapper;
@Test
@Rollback
public void testInsert() {
Member member = new Member();
member.setMemberAccount("john@abc.com");
member.setMemberName("John");
member.setMemberPassword("12345");
member.setMemberStatus("1");
mapper.insert(member); // 新增member
Member result = mapper.selectByNaturalKey(member.getMemberAccount()); // 查詢member
Assert.assertEquals(result.getMemberAccount(), member.getMemberAccount()); // 斷言相同
}
}
在測試程式testInsert()上按滑鼠右鍵 -> Run As -> JUnit Test
來執行測試程式。
上面的testInsert()
做了以下動作:
- 新增一個
Member
的物件member
。 - 設定
member
物件的內容。 - 呼叫
MamberMapper.insert()
來將此member
物件的內容新增至資料庫。 - 以剛新增的
member
物件的業務主鍵(Natural key)memberAccount
的值查詢moneynote.member
資料表。 - 斷言(Assert)
member.memberAccount
與查詢出的result.memberAccount
的值相同,相同代表通過測試。 - 交易回滾(rollback)。
測試成功可以在Eclipse的[JUnit]視窗看到以下結果。
此時去觀察資料庫的moneynote.member
資料表會發現並沒有資料,因為剛才的新增動作已經被rollback了。這是因為設定Spring的@Transactional
搭配@Rollback
annotation的效果。
這邊MyBatis的交易是由Spring來管理。
你可試著把@Transactional
拿掉,便會發現交易不會被rollback,因此在資料表中可以看到新增的資料。
另外雖然資料回滾了,但如果用上面的方法或在MySQL Workbench手動在member
資料表新增一筆資料,你會發現member_id
的值是累加後的狀態,也就是說AUTO_INCREMENT
欄位並不會rollback。
若要清空資料表,請參考MySQL 如何TRUNCATE有外鍵限制的資料表。TRUNCATE
後的AUTO_INCREMENT
欄位值會重設回1。
或是執行下面指令重設AUTO_INCREMENT
:
ALTER TABLE `moneynote`.`member`
AUTO_INCREMENT = 1 ;
接著請參考使用SpringBoot打造記帳簿專案(二十一)打包Spring Boot專案為可執行的jar檔
參考:
沒有留言:
張貼留言