1. 程式人生 > >【Mybatis框架】輸入對映-pojo包裝型別

【Mybatis框架】輸入對映-pojo包裝型別

下面說說關於mapper.xml檔案中的輸入對映

我們看一下之前為User配置的mapper檔案UserMapper.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進行分類化管理,理解sql隔離
注意:使用mapper代理方法開發,namespace有特殊重要的作用 -->
<mapper namespace="cn.edu.hpu.mybatis.mapper.UserMapper">
	<!-- 在對映檔案中配置很多sql語句 -->
	
	<!-- 需求:通過id查詢使用者表的記錄 -->
	<!-- 通過select執行資料庫查詢,
	     id:標示對映檔案中的sql,成為Statement的id 
	     將sql語句封裝到mappedStatement物件中,所以將id稱為statement的id,
	     
	     parameterType:指定輸入引數的型別,
	     
	     #{}標示一個佔位符,
	     
	     #{id}其中id表示接收輸入引數的名稱,如果輸入引數是簡單型別,那麼#{}中的值可以任意(如value)。
	     
	     resultType:指定sql輸出結果的對映的java物件型別,
	     select指定resultType表示將單條記錄對映成java物件-->	
	<select id="findUserById" parameterType="int" resultType="cn.edu.hpu.mybatis.PO.User">
	  SELECT * FROM USER WHERE id=#{id}
	</select>
	
	<!-- ${}:表示拼接sql串,將接收到的引數內容不加任何修飾拼接在sql中。
		 使用${}拼接sql,引起sql注入。
		 ${}中只能使用value-->
	<select id="findUserByUserName" parameterType="java.lang.String" 
			resultType="cn.edu.hpu.mybatis.PO.User">
	   select * from user where username like '%${value}%' 
	</select>
	
	<!-- 新增使用者
	parameterType:指定輸入引數型別是pojo(包括使用者資訊) 
	#{}中指定POJO的屬性名,接收到POJO物件的屬性值,mybatis通過OGNL獲取物件的屬性
	-->
	<insert id="insertUser" parameterType="cn.edu.hpu.mybatis.PO.User">
		<!-- 將插入資料的主鍵返回,返回到user物件中。
		SELECT_INSERT_ID():得到剛insert進去的主鍵值,只適用於自增主鍵 
		KeyProperty:將查詢到主鍵值設定到parameterType指定物件的哪個屬性。
		order:SELECT LAST_INSERT_ID()執行順序,相對於insert語句來說它的執行順序
		-->
		<selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">
			SELECT LAST_INSERT_ID()
		</selectKey>
		
		<!-- 使用MySql的UUID來生成主鍵
		執行過程:
		首先通過uuid()得到主鍵,將主鍵設定到user物件的id屬性中
		其次在insert執行時,從user物件中取出id屬性值 
		<selectKey keyProperty="id" order="BEFORE" resultType="java.lang.String">
			SELECT uuid()
		</selectKey>
		insert into user(id,birthday,sex,address) value(#{id},#{birthday,jdbcType=DATE},#{sex},#{address})-->
		
		insert into user(username,birthday,sex,address) value(#{username},#{birthday,jdbcType=DATE},#{sex},#{address})
	</insert>
	
	<!-- 刪除使用者 -->
	<delete id="deleteUser" parameterType="java.lang.Integer">
		delete from user where id=#{id}
	</delete>
	
	<!-- 更新使用者 
	分析:
	需要傳入使用者的id,需要傳入使用者的更新資訊.
	parameterType指定user物件,包括id和更新資訊(注意:id必須存在)
	#{id}:從輸入user物件中獲取id屬性值-->
	<update id="updateUser" parameterType="cn.edu.hpu.mybatis.PO.User">
		update user set username=#{username},birthday=#{birthday,jdbcType=DATE},sex=#{sex},address=#{address} 
		where id=#{id}
	</update>
</mapper>

在mapper.xml中我們通過parameterType指定輸入引數的型別,型別可以是簡單型別、hashmap、pojo的包裝型別

上面的查詢語句輸入的都是一個查詢引數,當我們輸入多個查詢引數時應當怎麼操作呢?這就要用到POJO的包裝物件把大量的查詢引數包裝在物件中傳遞給只能接收單個引數的Mapper操作方法了,看看如何來定義POJO包裝物件

1傳遞pojo的包裝物件
1.1需求
完成使用者資訊的綜合查詢,需要傳入查詢條件很複雜(可能包括使用者資訊、其它資訊,比如商品、訂單的)

1.2定義包裝型別pojo
針對上邊需求,建議使用自定義的包裝型別的pojo。
在包裝型別的pojo中將複雜的查詢條件包裝進去。

寫一個例子
首先我們前面定義了一個User類物件,如果物件中的值要發生拓展,在原始碼上改是不合適的(因為我們後期要使用工具自動生成User類,裡面的東西建議不要改動),這裡我們建立一個User的拓展類UserCustom,繼承自User類,我們下面包裝查詢條件時使用的是UserCustom,特此說明。

查詢包裝類UserQueryVo:
package cn.edu.hpu.mybatis.PO;

public class UserQueryVo {

	//在這裡包裝需要的查詢條件
	
	//使用者查詢條件
	private UserCustom userCustom;

	public UserCustom getUserCustom() {
		return userCustom;
	}

	public void setUserCustom(UserCustom userCustom) {
		this.userCustom = userCustom;
	}
	
	//包裝其他的查詢條件,訂單、商品
	//......
}

1.3mapper.xml
在UserMapper.xml中定義使用者資訊綜合查詢(查詢條件複雜,通過高階查詢進行復雜關聯查詢)。
<!-- 使用者資訊綜合查詢 
	#{UserCustom.sex}取出包裝物件中性別值
	${UserCustom.username}取得pojo包裝物件中使用者名稱稱
	-->
<select id="findUserList" parameterType="cn.edu.hpu.mybatis.PO.UserQueryVo" 
    resultType="cn.edu.hpu.mybatis.PO.UserCustom">
	select * from user where user.sex=#{userCustom.sex} and user.username like '%${userCustom.username}%'
</select>

在UserMapper類中定義綜合查詢方法:
//使用者管理的Dao介面
public interface UserMapper {
	
	//使用者資訊綜合查詢
	public List<UserCustom> findUserList(UserQueryVo userQueryVo) throws Exception;
	......
}

之後進行測試:
//使用者資訊綜合查詢
@Test
public void testFindUserList() throws Exception{
	
	SqlSession sqlSession=sqlSessionFactory.openSession();
	
	//建立UserMapper代理物件
	UserMapper userMapper=sqlSession.getMapper(UserMapper.class);
	
	//建立包裝物件,設定查詢條件
	UserQueryVo userQueryVo=new UserQueryVo();
	UserCustom userCustom=new UserCustom();
	userCustom.setSex("男");
	userCustom.setUsername("張三");
	userQueryVo.setUserCustom(userCustom);
	
	//呼叫userMapper的方法
	List<UserCustom> users=userMapper.findUserList(userQueryVo);
	
	for (int i = 0; i < users.size(); i++) {
		UserCustom user=(UserCustom)users.get(i);
		System.out.println(user.getId()+":"+user.getUsername());
	}
}

測試結果:
1:張三
4:張三丰

輸出日誌:
DEBUG [main] - Opening JDBC Connection
DEBUG [main] - Created connection 13994297.
DEBUG [main] - Setting autocommit to false on JDBC Connection [com.mysql.jdbc.Connection@d58939]
DEBUG [main] - ==>  Preparing: select * from user where user.sex=? and user.username like '%張三%' 
DEBUG [main] - ==> Parameters: 男(String)
DEBUG [main] - <==      Total: 2

傳遞HashMap與此類似,就不再贅述