Mybatis學習筆記(五) —— Mapper.xml(輸入對映和輸出對映)
一、parameterType(輸入型別)
1.1 傳遞簡單型別
<!-- 根據使用者id查詢使用者 --> <select id="queryUserById" parameterType="int" resultType="cn.itcast.mybatis.pojo.User"> SELECT * FROM `user` WHERE id = #{id} </select> <!-- 根據使用者名稱模糊查詢使用者 --> <select id="queryUserByUsername"parameterType="string" resultType="cn.itcast.mybatis.pojo.User"> SELECT * FROM `user` WHERE username LIKE '%${value}%' </select>
使用#{}佔位符,或者${}進行sql拼接
1.2 傳遞pojo物件
<!-- 儲存使用者 --> <insert id="saveUser" parameterType="cn.itcast.mybatis.pojo.User"> INSERT INTO `user`(username,birthday,sex,address) VALUES (#{username},#{birthday},#{sex},#{address}); </insert>
Mybatis使用ognl表示式解析物件欄位的值,#{}或者${}括號中的值為pojo屬性名稱。
1.3 傳遞pojo包裝物件
包裝物件:Pojo類中的一個屬性是另外一個pojo。
需求:根據使用者名稱模糊查詢使用者資訊,查詢條件放到QueryVo的user屬性中。
1.3.1 編寫QueryVo
public class QueryVo { // 包含其他的pojo private User user; public User getUser() { return user; } public void setUser(User user) { this.user = user; } }
1.3.2 Mapper.xml檔案
在UserMapper.xml中配置sql:
<!-- 使用包裝型別查詢使用者 --> <select id="queryUserByQueryVo" parameterType="queryVo" resultType="user"> SELECT * FROM `user` WHERE username LIKE '%${user.username}%' </select>
1.3.3 Mapper介面
在UserMapper介面中新增方法:
/** * 根據包裝型別查詢使用者 * @param queryVo * @return */ List<User> queryUserByQueryVo(QueryVo queryVo);
1.3.4 測試方法
@Test public void testQueryUserByQueryVo() throws Exception { // mybatis和spring整合,整合之後,交給spring管理 SqlSession sqlSession = sqlSessionFactory.openSession(); // 建立Mapper介面的動態代理物件,整合之後,交給spring管理 UserMapper userMapper = sqlSession.getMapper(UserMapper.class); // 使用userMapper執行查詢,使用包裝物件 QueryVo queryVo = new QueryVo(); // 設定user條件 User user = new User(); user.setUsername("張"); // 設定到包裝物件中 queryVo.setUser(user); // 執行查詢 List<User> list = userMapper.queryUserByQueryVo(queryVo); for (User user2 : list) { System.out.println(user2); } // mybatis和spring整合,整合之後,交給spring管理 sqlSession.close(); }
二、resultType(輸出型別)
2.1 輸出簡單型別
需求:查詢使用者表資料條數
sql:SELECT count(*) FROM `user`
2.1.1 Mapper.xml檔案
在UserMapper.xml中配置sql:
<!-- 查詢使用者資料條數 --> <select id="queryUserCount" resultType="int"> SELECT COUNT(*) FROM `user` </select>
2.1.2 Mapper介面
在UserMapper新增方法:
/** * 查詢使用者資料條數 * @return */ int queryUserCount();
2.1.3 測試方法
@Test public void testQueryUserCount() throws Exception { // mybatis和spring整合,整合之後,交給spring管理 SqlSession sqlSession = sqlSessionFactory.openSession(); // 建立Mapper介面的動態代理物件,整合之後,交給spring管理 UserMapper userMapper = sqlSession.getMapper(UserMapper.class); // 使用userMapper執行查詢使用者資料條數 int count = userMapper.queryUserCount(); System.out.println(count); // mybatis和spring整合,整合之後,交給spring管理 sqlSession.close(); }
2.2 輸出pojo物件
<select id="queryUserById" parameterType="int" resultType="cn.itcast.mybatis.pojo.User"> SELECT * FROM `user` WHERE id = #{id} </select>
2.3 輸出pojo列表
<!-- 根據使用者名稱模糊查詢使用者 --> <select id="queryUserByUsername" parameterType="string" resultType="cn.itcast.mybatis.pojo.User"> SELECT * FROM `user` WHERE username LIKE '%${value}%' </select>
三、resultMap
resultType可以指定將查詢結果對映為pojo,但需要pojo的屬性名和sql查詢的列名一致方可對映成功。
如果sql查詢欄位名和pojo的屬性名不一致,可以通過resultMap將欄位名和屬性名作一個對應關係 ,resultMap實質上還需要將查詢結果對映到pojo物件中。
resultMap可以實現將查詢結果對映為複雜型別的pojo,比如在查詢結果對映物件中包括pojo和list實現一對一查詢和一對多查詢。
需求:查詢訂單表order的所有資料
sql:SELECT id, user_id, number, createtime, note FROM `order`
3.1 宣告pojo物件
資料庫表如下圖:
Order物件:
public class Order { // 訂單id private int id; // 使用者id private Integer userId; // 訂單號 private String number; // 訂單建立時間 private Date createtime; // 備註 private String note; get/set。。。 }
3.2 Mapper.xml檔案
建立OrderMapper.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"> <!-- namespace:名稱空間,用於隔離sql,還有一個很重要的作用,Mapper動態代理開發的時候使用,需要指定Mapper的類路徑 --> <mapper namespace="cn.itcast.mybatis.mapper.OrderMapper"> <!-- 查詢所有的訂單資料 --> <select id="queryOrderAll" resultType="order"> SELECT id,user_id,number,createtime,note FROM `order` </select> </mapper>
3.3 Mapper介面
public interface OrderMapper { /** * 查詢所有訂單 * @return */ List<Order> queryOrderAll(); }
3.4 測試方法
public class OrderMapperTest { private SqlSessionFactory sqlSessionFactory; @Before public void init() throws Exception{ SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder(); InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml"); sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream); } @Test public void testQueryOrderAll() throws Exception { // 獲取sqlSession SqlSession sqlSession = sqlSessionFactory.openSession(); // 獲取OrderMapper OrderMapper orderMapper = sqlSession.getMapper(OrderMapper.class); // 執行查詢 List<Order> list = orderMapper.queryOrderAll(); for (Order order : list) { System.out.println(order); } sqlSession.close(); } }
3.5 測試效果
發現userId為null
解決方案:使用resultMap
3.6 使用resultMap
由於上邊的mapper.xml中sql查詢列(user_id)和Order類屬性(userId)不一致,所以查詢結果不能對映到pojo中。
需要定義resultMap,把orderResultMap將sql查詢列(user_id)和Order類屬性(userId)對應起來。
改造OrderMapper.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"> <!-- namespace:名稱空間,用於隔離sql,還有一個很重要的作用,Mapper動態代理開發的時候使用,需要指定Mapper的類路徑 --> <mapper namespace="cn.itcast.mybatis.mapper.OrderMapper"> <!-- resultMap最終還是要將結果對映到pojo上,type就是指定對映到哪一個pojo --> <!-- id:設定ResultMap的id --> <resultMap type="order" id="orderResultMap"> <!-- 定義主鍵 ,非常重要。如果是多個欄位,則定義多個id --> <!-- property:主鍵在pojo中的屬性名 --> <!-- column:主鍵在資料庫中的列名 --> <id property="id" column="id" /> <!-- 定義普通屬性 --> <result property="userId" column="user_id" /> <result property="number" column="number" /> <result property="createtime" column="createtime" /> <result property="note" column="note" /> </resultMap> <!-- 查詢所有的訂單資料 --> <select id="queryOrderAll" resultMap="orderResultMap"> SELECT id,user_id,number,createtime,note FROM `order` </select> </mapper>
3.7 測試效果