MaBatis(5)輸入/輸出對映
輸入對映:
通過parameType指定輸入引數的型別,型別可以是簡單型別,hashmap,pojo等
傳遞pojo的包裝物件
需求:
即使一個綜合查詢,需要傳入多個查詢的條件
開始敲程式碼了......

在這次使實踐裡面,需要新建兩個類,和使用之前的的測試類進行測試
新建UserCustomer.java 主要是繼承User.java其他的程式碼不寫
public class UserCustomer extends User{ }
在UserView.java中:
//在這裡包裝所需要的查詢條件 //使用者綜合查詢查詢條件 private UserCustomer userCustomer; public UserCustomer getUserCustomer() { return userCustomer; } public void setUserCustomer(UserCustomer userCustomer) { this.userCustomer = userCustomer; }
在UserMapper.java中定義綜合查詢的方法
//綜合查詢 public List<User> findBySelect(UserView userView) throws Exception;
在UserMapper.xml檔案中實現查詢的程式碼:
<!-- 綜合查詢 --> <select id="findBySelect" parameterType="com.MrChengs.po.UserView" resultType="com.MrChengs.po.UserCustomer" > select * from user where user.id=#{userCustomer.id} and user.username like '%${userCustomer.username}%' </select>
講解:parameterType這個是我們輸入引數的型別, #{userCustomer.id} 由此可以定位到UserView.java這個類面,在進行定位就是userCustomer,
對userCustomer在進一步就是UserCustomer這個類,他是繼承User這個類,此時到User這個類,已經到底,我們可以發現id這和屬性,這個 userCustomer.id相當於一個連點的方法
resultType:使我們綜合查詢的型別,此時使userCustomer
測試類中:
//綜合查詢 @Test public void testfindBySelect() throws Exception{ SqlSession sqlSession = getSqlSessionFactory().openSession(); UserMapper mapper = sqlSession.getMapper(UserMapper.class); UserView userView = new UserView(); UserCustomer userCustomer = new UserCustomer(); userCustomer.setId(16); userCustomer.setUsername("小明"); userView.setUserCustomer(userCustomer); List<User> user = mapper.findBySelect(userView); for(User u : user){ System.out.println(u); } sqlSession.close(); }
查詢成功:
DEBUG [main] - ==>Preparing: select * from user where user.id=? and user.username like '%小明%' DEBUG [main] - ==> Parameters: 16(Integer) DEBUG [main] - <==Total: 1 User [id=16, username=張小明, birthday=null, sex=1, address=河南鄭州]
生成的動態代理物件中是根據mapper方法的返回值型別確定是呼叫selectOne(返回單個物件呼叫)還是selectList (返回集合物件呼叫 ).
輸出對映:
對於resultType:
使用此屬性進行輸出對映時,只有在查詢出來的列和pojo中的屬性名一致,該列才可以對映成功
若查詢出來的列名和pojo中的屬性名全部不一致,沒有建立pojo物件
只要查詢出來的列名和pojo中的屬性名有一個一致,就會建立pojo物件
現在來實現一個測試的例子:
在UserMapper.java的介面類中:
//擦尋使用者資訊總數 public int findUserCount(UserView userView) throws Exception;
在UserMapper.xml檔案中:
<!-- 輸出對映查詢使用者資訊總數 --> <select id="findUserCount" parameterType="com.MrChengs.po.UserView" resultType="int"> select count(*) From user where sex=#{userCustomer.sex} and user.username like '%${userCustomer.username}%' </select>
在測試類中進行測試:
//查詢使用者資訊總數 @Test public void testfindUserCount() throws Exception{ SqlSession sqlSession = getSqlSessionFactory().openSession(); UserMapper mapper = sqlSession.getMapper(UserMapper.class); UserView userView = new UserView(); UserCustomer userCustomer = new UserCustomer(); userCustomer.setSex(1); userCustomer.setUsername("小明"); userView.setUserCustomer(userCustomer); int count = mapper.findUserCount(userView); System.out.println(count); sqlSession.close(); }
結果:
DEBUG [main] - Opening JDBC Connection DEBUG [main] - Created connection 963522361. DEBUG [main] - Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@396e2f39] DEBUG [main] - ==>Preparing: select count(*) From user where sex=? and user.username like '%小明%' DEBUG [main] - ==> Parameters: 1(Integer) DEBUG [main] - <==Total: 1 3 DEBUG [main] - Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@396e2f39]
輸出pojo物件和輸出pojo列表在sql中定義的resultType是一樣的。
返回單個pojo物件要保證sql查詢出來的結果集為單條,內部使用session.selectOne方法呼叫,mapper介面使用pojo物件作為方法返回值。
返回pojo列表表示查詢出來的結果集可能為多條,內部使用session.selectList方法,mapper介面使用List<pojo>物件作為方法返回值。
resultMap:
resultType可以指定pojo將查詢結果對映為pojo,但需要pojo的屬性名和sql查詢的列名一致方可對映成功。
如果sql查詢欄位名和pojo的屬性名不一致,可以通過resultMap將欄位名和屬性名作一個對應關係 ,resultMap實質上還需要將查詢結果對映到pojo物件中。
resultMap可以實現將查詢結果對映為複雜型別的pojo,比如在查詢結果對映物件中包括pojo和list實現一對一查詢和一對多查詢。
下面是程式碼的實踐:
測試:
在UserMapper.java介面中:
//測試resultMap public User findByMap(int id) throws Exception;
在UserMapper.xml中:
<!-- 簡單測試resultMap的使用 --> <!-- type:resultMap最終對映的java 物件型別,可以使用別名/全類名 --> <!-- id:使當前resultMap的唯一標識 --> <resultMap type="com.MrChengs.po.User" id="ByMap"> <!-- id標識查詢結果的唯一標識 --> <!-- column:查詢出來的列名 --> <!-- property:type指定型別的pojo型別的對映屬性,最終resultMap對cloumn和property做出一對一的對映 --> <id column="_id" property="id"/> <!-- result:對普通列名的對映 --> <!-- column:查詢出來的列名 --> <!-- property:和type的型別一一對映 --> <result column="_username" property="username"/> </resultMap> <select id="findByMap" parameterType="int"resultMap="ByMap"> select id _id,username _username from user where id=#{id} </select>
可以在sql軟體中測試select id _id,username _username from user where id=? 檢視我們得到的結果。
<id />:此屬性表示查詢結果集的唯一標識,非常重要。如果是多個欄位為複合唯一約束則定義多個<id />。
Property:表示person類的屬性。
Column:表示sql查詢出來的欄位名。
Column和property放在一塊兒表示將sql查詢出來的欄位對映到指定的pojo類屬性上。
<result />:普通結果,即pojo的屬性。
在測試類中:
//測試resultMap @Test public void testfindByMap() throws Exception{ SqlSession sqlSession = getSqlSessionFactory().openSession(); UserMapper mapper = sqlSession.getMapper(UserMapper.class); User user = mapper.findByMap(1); System.out.println(user); sqlSession.close(); }
結果:
DEBUG [main] - Opening JDBC Connection DEBUG [main] - Created connection 2050835901. DEBUG [main] - Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@7a3d45bd] DEBUG [main] - ==>Preparing: select id _id,username _username from user where id=? DEBUG [main] - ==> Parameters: 1(Integer) DEBUG [main] - <==Total: 1 User [id=1, username=王五, birthday=null, sex=0, address=null]
小結:
使用resultType進行輸出對映,只有查詢出來的列名和pojo中的屬性名一致,該列才可以對映成功。
如果查詢出來的列名和pojo的屬性名不一致,通過定義一個resultMap對列名和pojo屬性名之間作一個對映關係。