最近在讀劉增輝老師所著的《MyBatis從入門到精通》一書,頗有收穫,因而將本身學習的過程以博客形式輸出,若有錯誤,歡迎指正,如幫助到你,不勝榮幸!java
假如如今咱們想新增一個用戶,該如何操做呢?git
首先,在接口SysUserMapper中添加以下方法。github
/** * 新增用戶 * * @param sysUser * @return */ int insert(SysUser sysUser);
而後打開對應的SysUserMapper.xml文件,添加以下語句。sql
<insert id="insert"> INSERT INTO sys_user(id, user_name, user_password, user_email, user_info, head_img, create_time) VALUES (#{id},#{userName},#{userPassword},#{userEmail},#{userInfo},#{headImg,jdbcType=BLOB},#{createTime,jdbcType=TIMESTAMP}) </insert>
特別說明:數據庫
1)爲了防止類型錯誤,對於一些特殊的數據類型,建議指定具體的jdbcType值。例如headImg指定BLOB類型,createTime指定TIMESTAMP類型。數組
2)BLOB對應的類型是ByteArrayInputStream,就是二進制數據流。mybatis
3)因爲數據庫區分date、time、datetime類型,可是在Java中通常都使用java.util.Date類型。所以爲了保證數據類型的正確,須要手動指定日期類型。date、time、datetime對應的JDBC類型分別爲DATE、TIME、TIMESTAMP。app
在SysUserMapperTest測試類中添加以下代碼,測試下insert()方法。學習
@Test public void testInsert() { SqlSession sqlSession = getSqlSession(); try { SysUserMapper sysUserMapper = sqlSession.getMapper(SysUserMapper.class); SysUser sysUser = new SysUser(); sysUser.setUserName("test1"); sysUser.setUserPassword("123456"); sysUser.setUserEmail("test@mybatis.tk"); sysUser.setUserInfo("test info"); // 正常狀況下應該讀入一張圖片保存到byte數組中 sysUser.setHeadImg(new byte[]{1, 2, 3}); sysUser.setCreateTime(new Date()); // 這裏的返回值result是執行的SQL影響的行數 int result = sysUserMapper.insert(sysUser); // 只插入1條數據 Assert.assertEquals(1, result); // id爲null,沒有給id賦值,而且沒有配置回寫id的值 Assert.assertNull(sysUser.getId()); } finally { // 爲了避免影響其餘測試,這裏選擇回滾 // 默認的sqlSessionFactory.openSession()是不自動提交的 // 所以不手動執行commit也不會提交到數據庫 sqlSession.rollback(); sqlSession.close(); } }
運行該測試方法,輸出日誌以下。測試
DEBUG [main] - ==> Preparing: INSERT INTO sys_user(id, user_name, user_password, user_email, user_info, head_img, create_time) VALUES (?,?,?,?,?,?,?)
DEBUG [main] - ==> Parameters: null, test1(String), 123456(String), test@mybatis.tk(String), test info(String), java.io.ByteArrayInputStream@544a2ea6(ByteArrayInputStream), 2019-07-02 13:09:07.822(Timestamp)
DEBUG [main] - <== Updates: 1
如今咱們修改下createTime指定的jdbcType類型,直觀的理解下jdbcType值的做用。
createTime,jdbcType=DATE
再次運行測試方法,日誌中createTime字段的值以下。
2019-07-02(Date)
再次修改createTime指定的jdbcType類型爲TIME。
createTime,jdbcType=TIME
再次運行測試方法,發現報以下錯誤:
報錯的緣由是,數據庫中的字段類型爲datetime,可是這裏只有time部分的值。
經過上面的測試,說明數據庫的datetime類型能夠存儲DATE(時間部分默認爲00:00:00)和TIMESTAMP這兩種類型的時間,不能存儲TIME類型的時間。
在1.1的例子中,新增完數據,咱們並無拿到數據庫中自增的id值,但有些場景中,咱們須要先拿到數據庫中自增的值,而後再處理其他的邏輯,那麼如何拿到數據庫中的自增的id值呢?
首先,在接口SysUserMapper中添加方法以下。
/** * 新增用戶-使用useGeneratedKeys方式 * * @param sysUser * @return */ int insertUseGeneratedKeys(SysUser sysUser);
而後打開對應的SysUserMapper.xml,添加以下代碼。
<insert id="insertUseGeneratedKeys" useGeneratedKeys="true" keyProperty="id"> INSERT INTO sys_user(user_name, user_password, user_email, user_info, head_img, create_time) VALUES (#{userName},#{userPassword},#{userEmail},#{userInfo},#{headImg,jdbcType=BLOB},#{createTime,jdbcType=TIMESTAMP}) </insert>
useGeneratedKeys設置爲ture後,MyBatis會使用JDBC的getGeneratedKeys()方法來取出由數據庫內部生成的主鍵。獲取到主鍵後將其賦值給keyProperty配置的id屬性。
在SysUserMapperTest測試類中添加以下代碼,測試新增的insertUseGeneratedKeys()方法。
@Test public void testInsertUseGeneratedKeys() { SqlSession sqlSession = getSqlSession(); try { SysUserMapper sysUserMapper = sqlSession.getMapper(SysUserMapper.class); SysUser sysUser = new SysUser(); sysUser.setUserName("test1"); sysUser.setUserPassword("123456"); sysUser.setUserEmail("test@mybatis.tk"); sysUser.setUserInfo("test info"); // 正常狀況下應該讀入一張圖片保存到byte數組中 sysUser.setHeadImg(new byte[]{1, 2, 3}); sysUser.setCreateTime(new Date()); // 這裏的返回值result是執行的SQL影響的行數 int result = sysUserMapper.insertUseGeneratedKeys(sysUser); // 只插入1條數據 Assert.assertEquals(1, result); // 由於id回寫,因此id不爲null Assert.assertNotNull(sysUser.getId()); } finally { sqlSession.rollback(); sqlSession.close(); } }
運行該測試方法,測試經過,輸出日誌以下。
DEBUG [main] - ==> Preparing: INSERT INTO sys_user(user_name, user_password, user_email, user_info, head_img, create_time) VALUES (?,?,?,?,?,?)
DEBUG [main] - ==> Parameters: test1(String), 123456(String), test@mybatis.tk(String), test info(String), java.io.ByteArrayInputStream@544a2ea6(ByteArrayInputStream), 2019-07-02 14:02:22.506(Timestamp)
DEBUG [main] - <== Updates: 1
1.2中回寫主鍵的方法只適用於支持主鍵自增的數據庫。
但有些數據庫(好比Oracle)不提供主鍵自增的功能,而是使用序列獲得一個值,而後將這個值賦給id,再將數據插入到數據庫。
對於這種狀況,就能夠採用selectKey方式,由於selectKey方式不只適用於不提供主鍵自增功能的數據庫,也適用於提供主鍵自增功能的數據庫。
咱們先來看下MySql的例子。
首先,在接口SysUserMapper中添加以下方法。
/** * 新增用戶-使用selectKey方式 * * @param sysUser * @return */ int insertUseSelectKey(SysUser sysUser);
而後打開對應的SysUserMapper.xml文件,添加以下代碼。
<insert id="insertUseSelectKey"> INSERT INTO sys_user(user_name, user_password, user_email, user_info, head_img, create_time) VALUES (#{userName},#{userPassword},#{userEmail},#{userInfo},#{headImg,jdbcType=BLOB},#{createTime,jdbcType=TIMESTAMP}) <selectKey keyColumn="id" resultType="long" keyProperty="id" order="AFTER"> SELECT LAST_INSERT_ID() </selectKey> </insert>
和1.2相比,這裏的語句多了selectKey標籤,其中:
若是數據庫是Oracle的話,語句以下(由於環境問題,如下代碼我並未驗證,有興趣的同窗能夠本身試下)。
<insert id="insertUseSelectKey"> <selectKey keyColumn="id" resultType="long" keyProperty="id" order="BEFORE"> SELECT SEQ_ID.nextval from dual </selectKey> INSERT INTO sys_user(id,user_name, user_password, user_email, user_info, head_img, create_time) VALUES (#{id},#{userName},#{userPassword},#{userEmail},#{userInfo},#{headImg,jdbcType=BLOB},#{createTime,jdbcType=TIMESTAMP}) </insert>
假如咱們如今但願經過主鍵id來更新用戶信息,該如何操做呢?
首先,在接口SysUserMapper中添加以下方法。
/** * 根據主鍵更新 * * @param sysUser * @return */ int updateById(SysUser sysUser);
而後,打開對應的SysUserMapper.xml文件,添加以下代碼。
<update id="updateById"> UPDATE sys_user SET user_name = #{userName}, user_password = #{userPassword}, user_email = #{userEmail}, user_info = #{userInfo}, head_img = #{headImg,jdbcType=BLOB}, create_time = #{createTime,jdbcType=TIMESTAMP} WHERE id = #{id} </update>
最後在SysUserMapperTest測試類中,添加以下測試方法。
@Test public void testUpdateById() { SqlSession sqlSession = getSqlSession(); try { SysUserMapper sysUserMapper = sqlSession.getMapper(SysUserMapper.class); SysUser sysUser = sysUserMapper.selectById(1L); Assert.assertEquals("admin", sysUser.getUserName()); sysUser.setUserName("admin_test"); sysUser.setUserEmail("admin_test@mybatis.tk"); sysUser.setUserInfo("test info"); // 正常狀況下應該讀入一張圖片保存到byte數組中 sysUser.setHeadImg(new byte[]{1, 2, 3}); sysUser.setCreateTime(new Date()); // 這裏的返回值result是執行的SQL影響的行數 int result = sysUserMapper.updateById(sysUser); // 只更新1條數據 Assert.assertEquals(1, result); sysUser = sysUserMapper.selectById(1L); Assert.assertEquals("admin_test", sysUser.getUserName()); Assert.assertEquals("admin_test@mybatis.tk", sysUser.getUserEmail()); } finally { sqlSession.rollback(); sqlSession.close(); } }
運行測試方法,測試經過,輸出的部分日誌以下。
DEBUG [main] - ==> Preparing: UPDATE sys_user SET user_name = ?, user_password = ?, user_email = ?, user_info = ?, head_img = ?, create_time = ? WHERE id = ?
DEBUG [main] - ==> Parameters: admin_test(String), 123456(String), admin_test@mybatis.tk(String), test info(String), java.io.ByteArrayInputStream@78186a70(ByteArrayInputStream), 2019-07-02 14:57:34.792(Timestamp), 1(Long)
DEBUG [main] - <== Updates: 1
假如咱們如今但願經過主鍵id來刪除用戶信息,該如何操做呢?
首先,在接口SysUserMapper中添加以下方法。
/** * 根據主鍵刪除 * * @param id * @return */ int deleteById(Long id); /** * 根據對象的主鍵刪除 * * @param sysUser * @return */ int deleteBySysUser(SysUser sysUser);
而後,打開對應的SysUserMapper.xml文件,添加以下代碼。
<delete id="deleteById"> DELETE FROM sys_user WHERE id = #{id} </delete> <delete id="deleteBySysUser"> DELETE FROM sys_user WHERE id = #{id} </delete>
最後在SysUserMapperTest測試類中,添加以下測試方法。
@Test public void testDeleteById() { SqlSession sqlSession = getSqlSession(); try { SysUserMapper sysUserMapper = sqlSession.getMapper(SysUserMapper.class); SysUser sysUser = sysUserMapper.selectById(1L); Assert.assertNotNull(sysUser); // 這裏是直接根據id刪除 int result = sysUserMapper.deleteById(1L); // 只刪除1條數據 Assert.assertEquals(1, result); Assert.assertNull(sysUserMapper.selectById(1L)); SysUser sysUser2 = sysUserMapper.selectById(1001L); Assert.assertNotNull(sysUser2); // 這裏是根據對象的id屬性刪除 Assert.assertEquals(1, sysUserMapper.deleteBySysUser(sysUser2)); Assert.assertNull(sysUserMapper.selectById(1001L)); } finally { sqlSession.rollback(); sqlSession.close(); } }
運行測試方法,測試經過,輸出的部分日誌以下。
DEBUG [main] - ==> Preparing: DELETE FROM sys_user WHERE id = ?
DEBUG [main] - ==> Parameters: 1(Long)
DEBUG [main] - <== Updates: 1
源碼地址:https://github.com/zwwhnly/mybatis-action.git,歡迎下載。
劉增輝《MyBatis從入門到精通》