1. 程式人生 > 程式設計 >MyBatis註解方式之@Update/@Delete使用詳解

MyBatis註解方式之@Update/@Delete使用詳解

@Update

1. RoleMapper介面增加介面方法

 /**
  * 
  * 
  * @Title: updateSysRoleById
  * 
  * @Description: updateSysRoleById
  * 
  * @param sysRole
  * @return
  * 
  * @return: int
  */
 @Update({ "update sys_role set role_name = #{roleName},enabled = #{enabled},create_by = #{createBy},create_time = #{createTime,jdbcType=TIMESTAMP} where id = #{id}" })
 int updateSysRoleById(SysRole sysRole);

2. 單元測試

@Test
 public void updateSysRoleByIdTest() {
  logger.info("updateSysRoleByIdTest");
  // 獲取SqlSession
  SqlSession sqlSession = getSqlSession();
  try {
   // 獲取RoleMapper介面
   RoleMapper roleMapper = sqlSession.getMapper(RoleMapper.class);

   // 先根據ID查詢出對應的sysRole
   SysRole sysRole = roleMapper.selectSysRoleById((long) 1);
   // roleName期望為管理員
   Assert.assertEquals("管理員",sysRole.getRoleName());

   // 修改RoleName
   sysRole.setRoleName("管理員Artisan");
   // 修改CreateBy
   sysRole.setCreateBy("Artisan");
   // 修改使用者,返回受影響的行數
   int result = roleMapper.updateSysRoleById(sysRole);

   // 只插入一條資料,期望是1
   Assert.assertEquals(1,result);
   logger.info("受影響的行數:" + result);

   // 期望的RoleName為管理員Artisan
   Assert.assertEquals("管理員Artisan",sysRole.getRoleName());
   // 期望的CreateBy為Artisan
   Assert.assertEquals("Artisan",sysRole.getCreateBy());

   logger.info("sysRole:" + sysRole);


  } catch (Exception e) {
   e.printStackTrace();
  } finally {
   // 為了保持測試資料的乾淨,這裡選擇回滾
   // 由於預設的sqlSessionFactory.openSession()是不自動提交的
   // 除非顯式的commit,否則不會提交到資料庫
   sqlSession.rollback();
   logger.info("為了保持測試資料的乾淨,這裡選擇回滾,不寫入mysql,請觀察日誌,回滾完成");

   sqlSession.close();
   logger.info("sqlSession close successfully ");
  }
 }
2018-04-19 02:55:57,225 INFO [main] (BaseMapperTest.java:26) - sessionFactory bulit successfully
2018-04-19 02:55:57,230 INFO [main] (BaseMapperTest.java:29) - reader close successfully
2018-04-19 02:55:57,233 INFO [main] (RoleMapperTest.java:229) - updateSysRoleByIdTest
2018-04-19 02:55:57,726 DEBUG [main] (BaseJdbcLogger.java:145) - ==> Preparing: SELECT a.id,a.role_name roleName,a.enabled,a.create_by createBy,a.create_time createTime FROM sys_role a WHERE a.id = ? 
2018-04-19 02:55:57,799 DEBUG [main] (BaseJdbcLogger.java:145) - ==> Parameters: 1(Long)
2018-04-19 02:55:57,824 TRACE [main] (BaseJdbcLogger.java:151) - <== Columns: id,roleName,enabled,createBy,createTime
2018-04-19 02:55:57,825 TRACE [main] (BaseJdbcLogger.java:151) - <==  Row: 1,管理員,1,2018-04-13 21:12:46.0
2018-04-19 02:55:57,828 DEBUG [main] (BaseJdbcLogger.java:145) - <==  Total: 1
2018-04-19 02:55:57,829 DEBUG [main] (BaseJdbcLogger.java:145) - ==> Preparing: update sys_role set role_name = ?,enabled = ?,create_by = ?,create_time = ? where id = ? 
2018-04-19 02:55:57,835 DEBUG [main] (BaseJdbcLogger.java:145) - ==> Parameters: 管理員Artisan(String),1(Integer),Artisan(String),2018-04-13 21:12:46.0(Timestamp),1(Long)
2018-04-19 02:55:57,839 DEBUG [main] (BaseJdbcLogger.java:145) - <== Updates: 1
2018-04-19 02:55:57,840 INFO [main] (RoleMapperTest.java:250) - 受影響的行數:1
2018-04-19 02:55:57,845 INFO [main] (RoleMapperTest.java:257) - sysRole:SysRole [id=1,roleName=管理員Artisan,enabled=1,createBy=Artisan,createTime=Fri Apr 13 21:12:46 BOT 2018,user=null,privilegeList=null]
2018-04-19 02:55:57,849 INFO [main] (RoleMapperTest.java:267) - 為了保持測試資料的乾淨,這裡選擇回滾,請觀察日誌,回滾完成
2018-04-19 02:55:57,851 INFO [main] (RoleMapperTest.java:270) - sqlSession close successfully 

@Delete

1. RoleMapper介面增加介面方法

/**
  * 
  * 
  * @Title: deleteSysRoleById
  * 
  * @Description: deleteSysRoleById
  * 
  * @param id
  * @return
  * 
  * @return: int
  */
 @Delete("delete from sys_role where id = #{id}")
 int deleteSysRoleById(Long id);

2. 單元測試

@Test
 public void deleteSysRoleByIdTest() {
  logger.info("deleteSysRoleByIdTest");
  // 獲取SqlSession
  SqlSession sqlSession = getSqlSession();
  try {
   // 獲取roleMapper介面
   RoleMapper roleMapper = sqlSession.getMapper(RoleMapper.class);

   // 呼叫刪除介面
   int result = roleMapper.deleteSysRoleById((long) 1);
   // 期望影響的結果條數為 1
   Assert.assertEquals(1,result);

   // 再次查詢
   SysRole sysRole = roleMapper.selectSysRoleById((long) 1);
   // 期望查詢出來的sysRole 為 null
   Assert.assertNull(sysRole);
  } catch (Exception e) {
   e.printStackTrace();
  } finally {
   // 為了保持測試資料的乾淨,這裡選擇回滾
   // 由於預設的sqlSessionFactory.openSession()是不自動提交的
   // 除非顯式的commit,否則不會提交到資料庫
   sqlSession.rollback();
   logger.info("為了保持測試資料的乾淨,這裡選擇回滾,請觀察日誌,回滾完成");

   sqlSession.close();
   logger.info("sqlSession close successfully ");
  }
 }
2018-04-19 02:56:23,024 INFO [main] (BaseMapperTest.java:26) - sessionFactory bulit successfully
2018-04-19 02:56:23,027 INFO [main] (BaseMapperTest.java:29) - reader close successfully
2018-04-19 02:56:23,030 INFO [main] (RoleMapperTest.java:276) - deleteSysRoleByIdTest
2018-04-19 02:56:23,517 DEBUG [main] (BaseJdbcLogger.java:145) - ==> Preparing: delete from sys_role where id = ? 
2018-04-19 02:56:23,589 DEBUG [main] (BaseJdbcLogger.java:145) - ==> Parameters: 1(Long)
2018-04-19 02:56:23,596 DEBUG [main] (BaseJdbcLogger.java:145) - <== Updates: 1
2018-04-19 02:56:23,599 DEBUG [main] (BaseJdbcLogger.java:145) - ==> Preparing: SELECT a.id,a.create_time createTime FROM sys_role a WHERE a.id = ? 
2018-04-19 02:56:23,599 DEBUG [main] (BaseJdbcLogger.java:145) - ==> Parameters: 1(Long)
2018-04-19 02:56:23,625 DEBUG [main] (BaseJdbcLogger.java:145) - <==  Total: 0
2018-04-19 02:56:23,628 INFO [main] (RoleMapperTest.java:299) - 為了保持測試資料的乾淨,這裡選擇回滾,請觀察日誌,回滾完成
2018-04-19 02:56:23,631 INFO [main] (RoleMapperTest.java:302) - sqlSession close successfully 

補充知識:Mybatis註解大全 Mybatis支援的所有註解說明

註解 使用物件 相對應的XML 描述
@CacheNamespace <cache> 為給定的名稱空間(比如類)配置快取。屬性有:implemetation,eviction,flushInterval,size,readWrite,blocking 和properties。
@Property N/A <property> 指定引數值或佔位值(placeholder)(能被 mybatis-config.xml內的配置屬性覆蓋)。屬性有:name,value。(僅在MyBatis 3.4.2以上版本生效)
@CacheNamespaceRef <cacheRef> 參照另外一個名稱空間的快取來使用。屬性有:value,name。如果你使用了這個註解,你應設定 value 或者 name 屬性的其中一個。value 屬性用於指定 Java 型別而指定名稱空間(名稱空間名就是指定的 Java 型別的全限定名),name 屬性(這個屬性僅在MyBatis 3.4.2以上版本生效)直接指定了名稱空間的名字。
@ConstructorArgs 方法 <constructor> 收集一組結果傳遞給一個結果物件的構造方法。屬性有:value,它是形式引數陣列。
@Arg N/A <arg>``<idArg> 單引數構造方法,是 ConstructorArgs 集合的一部分。屬性有:id,column,javaType,jdbcType,typeHandler,select 和 resultMap。id 屬性是布林值,來標識用於比較的屬性,和<idArg> XML 元素相似。
@TypeDiscriminator 方法 <discriminator> 一組例項值被用來決定結果對映的表現。屬性有:column,typeHandler 和 cases。cases 屬性是例項陣列。
@Case N/A <case> 單獨例項的值和它對應的對映。屬性有:value,type,results。results 屬性是結果陣列,因此這個註解和實際的 ResultMap 很相似,由下面的 Results 註解指定。
@Results 方法 <resultMap> 結果對映的列表,包含了一個特別結果列如何被對映到屬性或欄位的詳情。屬性有:value,id。value 屬性是 Result 註解的陣列。這個 id 的屬性是結果對映的名稱。
@Result N/A <result>``<id> 在列和屬性或欄位之間的單獨結果對映。屬性有:id,one,many。id 屬性是一個布林值,來標識應該被用於比較(和在 XML 對映中的<id>相似)的屬性。one 屬性是單獨的聯絡,和 <association> 相似,而 many 屬性是對集合而言的,和<collection>相似。它們這樣命名是為了避免名稱衝突。
@One N/A <association> 複雜型別的單獨屬性值對映。屬性有:select,已對映語句(也就是對映器方法)的全限定名,它可以載入合適型別的例項。fetchType會覆蓋全域性的配置引數 lazyLoadingEnabled。注意 聯合對映在註解 API中是不支援的。這是因為 Java 註解的限制,不允許迴圈引用。
@Many N/A <collection> 對映到複雜型別的集合屬性。屬性有:select,已對映語句(也就是對映器方法)的全限定名,它可以載入合適型別的例項的集合,fetchType 會覆蓋全域性的配置引數 lazyLoadingEnabled。注意 聯合對映在註解 API中是不支援的。這是因為 Java 註解的限制,不允許迴圈引用
@MapKey 方法 ?? 這是一個用在返回值為 Map 的方法上的註解。它能夠將存放物件的 List 轉化為 key 值為物件的某一屬性的 Map。屬性有: value,填入的是物件的屬性名,作為 Map 的 key 值。
@Options 方法 對映語句的屬性 這個註解提供訪問大範圍的交換和配置選項的入口,它們通常在對映語句上作為屬性出現。Options 註解提供了通俗易懂的方式來訪問它們,而不是讓每條語句註解變複雜。屬性有:useCache=true,flushCache=FlushCachePolicy.DEFAULT,resultSetType=DEFAULT,statementType=PREPARED,fetchSize=-1,timeout=-1,useGeneratedKeys=false,keyProperty="",keyColumn="",resultSets=""。值得一提的是, Java 註解無法指定 null 值。因此,一旦你使用了 Options 註解,你的語句就會被上述屬性的預設值所影響。要注意避免預設值帶來的預期以外的行為。 注意: keyColumn 屬性只在某些資料庫中有效(如 Oracle、PostgreSQL等)。請在插入語句一節檢視更多關於 keyColumn和 keyProperty 兩者的有效值詳情。
@Insert @Update @Delete @Select 方法 <insert> <update> <delete> <select> 這四個註解分別代表將會被執行的 SQL 語句。它們用字串陣列(或單個字串)作為引數。如果傳遞的是字串陣列,字串之間先會被填充一個空格再連線成單個完整的字串。這有效避免了以 Java 程式碼構建 SQL 語句時的“丟失空格”的問題。然而,你也可以提前手動連線好字串。屬性有:value,填入的值是用來組成單個 SQL 語句的字串陣列。
@InsertProvider @UpdateProvider @DeleteProvider @SelectProvider 方法 <insert> <update> <delete> <select> 允許構建動態 SQL。這些備選的 SQL 註解允許你指定類名和返回在執行時執行的 SQL 語句的方法。(自從MyBatis 3.4.6開始,你可以用 CharSequence 代替 String 來返回型別返回值了。)當執行對映語句的時候,MyBatis 會例項化類並執行方法,類和方法就是填入了註解的值。你可以把已經傳遞給對映方法了的物件作為引數,“Mapper interface type” 和 “Mapper method” and “Database ID” 會經過 ProviderContext (僅在MyBatis 3.4.5及以上支援)作為引數值。(MyBatis 3.4及以上的版本,支援多引數傳入) 屬性有: type,method。 type 屬性需填入類。 method 需填入該類定義了的方法名 (Since 3.5.1,you can omit method attribute,the MyBatis will resolve a target method via the ProviderMethodResolver interface. If not resolve by it,the MyBatis use the reserved fallback method that named provideSql)。 注意 接下來的小節將會討論類,能幫助你更輕鬆地構建動態 SQL。
@Param 引數 N/A 如果你的對映方法的形參有多個,這個註解使用在對映方法的引數上就能為它們取自定義名字。若不給出自定義名字,多引數(不包括 RowBounds 引數)則先以 “param” 作字首,再加上它們的引數位置作為引數別名。例如 #{param1},#{param2},這個是預設值。如果註解是 @Param("person"),那麼引數就會被命名為 #{person}。
@SelectKey 方法 <selectKey> 這個註解的功能與 <selectKey> 標籤完全一致,用在已經被 @Insert 或 @InsertProvider 或 @Update 或 @UpdateProvider 註解了的方法上。若在未被上述四個註解的方法上作 @SelectKey 註解則視為無效。如果你指定了 @SelectKey 註解,那麼 MyBatis 就會忽略掉由 @Options註解所設定的生成主鍵或設定(configuration)屬性。屬性有:statement填入將會被執行的 SQL 字串陣列,keyProperty 填入將會被更新的引數物件的屬性的值,before 填入 true 或 false 以指明 SQL 語句應被在插入語句的之前還是之後執行。resultType 填入 keyProperty 的 Java 型別和用 Statement、 PreparedStatement 和 CallableStatement中的 STATEMENT、 PREPARED 或 CALLABLE中任一值填入 statementType。預設值是 PREPARED。
@ResultMap 方法 N/A 這個註解給 @Select 或者 @SelectProvider提供在 XML 對映中的 <resultMap> 的id。這使得註解的 select 可以複用那些定義在 XML 中的 ResultMap。如果同一 select 註解中還存在 @Results 或者 @ConstructorArgs,那麼這兩個註解將被此註解覆蓋。
@ResultType 方法 N/A 此註解在使用了結果處理器的情況下使用。在這種情況下,返回型別為 void,所以 Mybatis 必須有一種方式決定物件的型別,用於構造每行資料。如果有 XML 的結果對映,請使用 @ResultMap 註解。如果結果型別在 XML 的 <select> 節點中指定了,就不需要其他的註解了。其他情況下則使用此註解。比如,如果 @Select 註解在一個將使用結果處理器的方法上,那麼返回型別必須是 void 並且這個註解(或者@ResultMap)必選。這個註解僅在方法返回型別是 void 的情況下生效。
@Flush 方法 N/A 如果使用了這個註解,定義在 Mapper 介面中的方法能夠呼叫 SqlSession#flushStatements() 方法。(Mybatis 3.3及以上)

以上這篇MyBatis註解方式之@Update/@Delete使用詳解就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支援我們。