相比jdbc mybatis在操作數據庫方面比jdbc節省了大量的代碼,及大量的代碼冗余.使得操作起來更加簡潔.
在Mapper中分別有着 select,insert, update,delete的這四個標簽分別對應着SQL語句中的查詢映射,添加映射,修改映射,刪除映射.
<select id=""></select> <insert id=""></insert> <update id=""></update> <delete id=""></delete>
不同點
可以看到除了標簽,SQL語句的作用不一致,以及除了select返回的數據不是受影響行數之外,其它的都是返回受影響行數,也就是返回的是int類型數據
相同點
都需要傳入參數
xml代碼如下
<select id="getProvider" resultType="Provider"> SELECT * FROM smbms_bill b JOIN smbms_provider p ON b.providerId=p.id WHERE b.providerId=#{id} </select> <update id="updatePwd" parameterType="User"> UPDATE `smbms_user` SET `userPassword` = #{userPassword} WHERE `id` = #{id} ; </update> <delete id="delUserById" parameterType="Integer"> delete from smbms_user where id=#{id} </delete> <insert id="add" parameterType="User"> INSERT INTO `smbms_user` (`userCode`, `userName`, `userPassword`, `gender`, `birthday`, `phone`, `address`, `userRole`, `createdBy`, `creationDate`, `modifyBy`, `modifyDate`) VALUES(#{userCode},#{userName},#{userPassword},#{gender}, #{birthday},#{phone},#{address},#{userRole},#{createdBy},#{creationDate}, #{modifyBy}, #{modifyDate}); </insert>
接口代碼
List<Provider> getProvider(Integer id); int add(User u); int updatePwd(User u); int delUserById(int id);
測試類代碼
public static void main(String[] args) { SqlSession sqlSession=null; List<Bill> bList = new ArrayList<>(); List<Provider> providers = new ArrayList<>(); try { sqlSession=MyBatisUtil.createSqlSession(); providers=sqlSession.getMapper(ProviderMapper.class).getProvider(1);for (Provider p : providers) { for (Bill b : p.getBills()) { System.out.println(b.getProductName()); } } } catch (Exception e) { e.printStackTrace(); logger.debug(e); }finally { MyBatisUtil.closeSqlSession(sqlSession); } } @org.junit.Test public void testAdd() { logger.debug("testAdd-----"); SqlSession sqlSession =null; int count=0; try { sqlSession = MyBatisUtil.createSqlSession(); User u = new User("測試用戶", 1); u.setUserCode("test001"); u.setUserPassword("123456"); u.setBirthday(Date.valueOf("1999-09-09")); u.setAddress("測試地址"); u.setGenfer(1); u.setPhone("19973535706"); u.setCreatedBy(1); u.setCreationDate(Date.valueOf("1999-09-09")); count = sqlSession.getMapper(UserMapper.class).add(u); sqlSession.commit(); } catch (Exception e) { e.printStackTrace(); sqlSession.rollback(); }finally { MyBatisUtil.closeSqlSession(sqlSession); } logger.debug("testAdd:"+count); } @org.junit.Test public void testModifyPwd() { logger.debug("testModifyPwd-----"); SqlSession sqlSession =null; int count=0; try { sqlSession = MyBatisUtil.createSqlSession(); User u = new User("測試用戶修改", 1); u.setUserPassword("123456"); u.setId(15); count = sqlSession.getMapper(UserMapper.class).updatePwd(u); sqlSession.commit(); } catch (Exception e) { e.printStackTrace(); sqlSession.rollback(); }finally { MyBatisUtil.closeSqlSession(sqlSession); } logger.debug("testModifyPwd:"+count); } @org.junit.Test public void testdel() { logger.debug("testdel-----"); SqlSession sqlSession =null; int count=0; try { sqlSession = MyBatisUtil.createSqlSession();; count = sqlSession.getMapper(UserMapper.class).delUserById(16); sqlSession.commit(); } catch (Exception e) { e.printStackTrace(); sqlSession.rollback(); }finally { MyBatisUtil.closeSqlSession(sqlSession); } logger.debug("testdel:"+count); }
以上一個都傳入了參數的,那么我們在來看共同點相同屬性也就是parameterType,指的是傳入的參數,一種具體的數據類型比如,int,String,自定義的對象等等
注意:傳入的參數與SQL語句中參數名兩者名稱需一致,如果是自定義對象則需與對象中自定義的屬性名稱一致
此外還有一個屬性parameterMap:參數有多個值,並且這多個值之間沒有具體的聯系,就可以考慮使用parameterMap,或者@param注解
那么再看select中的另外一個屬性:resultType指的是返回的數據類型,而除了select其他的都沒有,這是因為它們默認就是返回int因此不需要 resultType.
resultMap:必須要自己在這個xml中重新配置一個新的resultMap標簽,
注意:當受影響行數為0時返回的值就會是null,因此返回值最好設置成integer而不是int
@Param注解實現多參數
List<Bill> getBill(@Param("id") Integer billId);
使用注解@Parma來傳入多個參數,入@Param("id") Integer billId,相當於將該參數重命名為id,在映射的SQL中需要使用#{注解名}
<select id="getBill" parameterType="Integer" resultMap="billResult"> SELECT * FROM smbms_bill b JOIN smbms_provider p ON b.providerId=p.id WHERE b.providerId=#{id} </select>
resultType和resultMap的關聯
在mybatis進行查詢映射的時候,其實查詢處理的每個字段值都放在一個對應的Map里面,其中關鍵是字段名,值則是對應的值,當select提供的返回類型屬性
是在resultType的時候,My把提升會將Map里面的鍵值取出賦值給resultType所知道的對象對應的屬性(即釣魚對應的對象里的屬性的setter方法進行填充).因此
,當resulttype的時候,直接在后台就能接收到其相應的值.其實mybatis的每個查詢映射的返回類型都是resultMap,只是mybatis自動轉換成了我們需要的類型
注意:resultType屬性和resultMap屬性不能同時存在,只能二者選其一
resultMap自定義映射
<resultMap type="Bill" id="billResult"> <result property="productName" column="productName"/> <result property="productDesc" column="productDesc"/> </resultMap> <select id="getBill" parameterType="Integer" resultMap="billResult"> SELECT * FROM smbms_bill b JOIN smbms_provider p ON b.providerId=p.id WHERE b.providerId=#{id} </select>
resultMap的屬性值和子節點
- id屬性:唯一標識符,此id值用於select於是resultMap的屬性引用
- type:表示該resultMap的映射結果類型
- result節點:用於表示一些簡單屬性,其中column屬性表示從數據庫中查詢的字段名,property則表示查詢處來的字段對應的值賦給實體對象的那個屬性
設置映射級別
<settings> <!-- 設置自動匹配所有屬性 包括collection與association--> <setting name="autoMappingBehavior" value="FULL"/> </settings>
- NONE:禁止自動匹配
- PARTIAL(默認):自動匹配所以屬性,內部嵌套的(association,collection)除外
- FULL:匹配所有
有了最高映射級別,因此自定義對象中的屬性只要數據庫中的字段相對應就不需要使用使用resultMap進行手動映射結果了
association
association:映射到Javabean的某個"復雜類型"屬性,比如Javabean類,即Javabean內部嵌套一個復雜數據類型(Javabean)屬性,這種情況就屬性復雜類型的關聯.
如類類,需要注意:association僅處理一對一的關聯關系
實體類
private int id; /** * 編碼 */ private String billCode; /** * 名稱 */ private String productName; /** * 商品描述 */ private String productDesc; /** * 商品單位 */ private String productUnit; /** * 商品數量 */ private int productCount; /** * 商品總額 */ private int totalPrice; /** * 是否支付 1 未支付 0 已支付 */ private int isPayment; /** * 創建者 */ private String createdBy; /** * 創建時間 */ private Date creationDate; /** * 更新者 */ private String modifyBy; /** * 更新時間 */ private Date modifyDate; /** * 供應商id */ private int providerId; /** * 供應商 */ private Provider provider; // 省略getset方法
SQL映射
<resultMap type="Bill" id="billResult"> <result property="productName" column="productName"/> <result property="productDesc" column="productDesc"/> <association property="provider" resultMap="providerresult"></association> </resultMap> <resultMap type="Provider" id="providerresult"> <result property="proAddress" column="proAddress"/> <result property="proName" column="proName"/> </resultMap> <select id="getBill" parameterType="Integer" resultMap="billResult"> SELECT * FROM smbms_bill b JOIN smbms_provider p ON b.providerId=p.id WHERE b.providerId=#{id}
</select>
上面只選了部分屬性進行映射
association屬性
- property:映射數據庫列的實體對象屬性,此處為在Bill定義的屬性:Provider
- result:property 映射數據庫列的實體對象的屬性,此處為Provider,column數控列名或別名
collection
作用與association非常類似,只不過collection對應的是類型中的集合
<resultMap type="Bill" id="billResult"> <result property="productName" column="productName"/> <result property="productDesc" column="productDesc"/> </resultMap> <resultMap type="Provider" id="providerresult"> <result property="proAddress" column="proAddress"/> <result property="proName" column="proName"/> <collection property="bills" ofType="Bill" resultMap="billResult"></collection> </resultMap> <select id="getProvider" resultMap="providerresult" parameterType="Integer"> SELECT * FROM smbms_bill b JOIN smbms_provider p ON b.providerId=p.id WHERE b.providerId=#{id} </select>
collection屬性
- ofType:映射數據庫列的實體對象屬性,此處為在Bill定義的屬性:Provider
- result:property 映射數據庫列的實體對象的屬性,此處為Provider,column數控列名或別名
resultType