【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与此类似,就不再赘述

转载请注明出处:http://blog.csdn.net/acmman/article/details/46509307

上一篇:写了一套优雅接口之后,领导让我给大家讲讲这背后的技术原理


下一篇:Mybatis插件原理,源码解读