【Mybatis】04输入输出映射+动态sql+关联查询

1、输入输出映射

1.1 输入映射
QueryVo.java
public class QueryVo {

	private User user;

	public User getUser() {
		return user;
	}

	public void setUser(User user) {
		this.user = user;
	}
	
}
Mapper文件
<!-- 使用包装类型查询用户 
		使用ognl从对象中取属性值,如果是包装对象可以使用.操作符来取内容部的属性
	-->
	<select id="findUserByQueryVo" parameterType="queryvo" resultType="user">
		SELECT * FROM user where username like '%${user.username}%'
	</select>
在接口中写方法
List<User> findUserByQueryVo(QueryVo queryVo) throws Exception
测试
@Test
	public void testFindUserByQueryVo() throws Exception {
		SqlSession sqlSession = sessionFactory.openSession();
		//获得mapper的代理对象
		UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
		//创建QueryVo对象
		QueryVo queryVo = new QueryVo();
		//创建user对象
		User user = new User();
		user.setUsername("刘");
		queryVo.setUser(user);
		//根据queryvo查询用户
		List<User> list = userMapper.findUserByQueryVo(queryVo);
		System.out.println(list);
		sqlSession.close();
	}
1.2 输出映射

        resultType可以指定pojo将查询结果映射为pojo,但需要pojo的属性名和sql查询的列名一致方可映射成功。
如果sql查询字段名和pojo的属性名不一致,可以通过resultMap将字段名和属性名作一个对应关系 ,resultMap实质上还需要将查询结果映射到pojo对象中。

resultMap可以实现将查询结果映射为复杂类型的pojo,比如在查询结果映射对象中包括pojo和list实现一对一查询和一对多查询。

<!-- 一对一:手动映射 -->
	<!-- 
	id:resultMap的唯一标识
	type:将查询出的数据放入这个指定的对象中
	注意:手动映射需要指定数据库中表的字段名与java中pojo类的属性名称的对应关系
	 -->
	<resultMap type="cn.chuantao.pojo.Orders" id="orderAndUserResultMap">
		<!-- id标签指定主键字段对应关系
		column:列,数据库中的字段名称
		property:属性,java中pojo中的属性名称
		 -->
		<id column="id" property="id"/>
		
		<!-- result:标签指定非主键字段的对应关系 -->
		<result column="user_id" property="userId"/>
		<result column="number" property="number"/>
		<result column="createtime" property="createtime"/>
		<result column="note" property="note"/>
		
		<!-- 这个标签指定单个对象的对应关系 
		property:指定将数据放入Orders中的user属性中
		javaType:user属性的类型
		-->
		<association property="user" javaType="cn.chuantao.pojo.User">
			<id column="uid" property="id"/>
			<result column="username" property="username"/>
			<result column="birthday" property="birthday"/>
			<result column="sex" property="sex"/>
			<result column="address" property="address"/>
		</association>
	</resultMap>
	<select id="findOrdersAndUser2" resultMap="orderAndUserResultMap">
		select a.*, b.id uid, username, birthday, sex, address 
		from orders a, user b 
		where a.user_id = b.id
	</select>

2、动态SQL

2.1 if
<!-- 传递pojo综合查询用户信息 -->
	<select id="findUserList" parameterType="user" resultType="user"> user表示的包扫描的方式。
		select * from user 
		where 1=1 
		<if test="id!=null">
		and id=#{id}
		</if>
		<if test="username!=null and username!=''">
		and username like '%${username}%'
		</if>
	</select>
2.2 where (1)可以当做where 关键字(2) 处理第一个and 关键字
<select id="findUserList" parameterType="user" resultType="user">
		select * from user 
		<where>
		<if test="id!=null and id!=''">
		and id=#{id}
		</if>
		<if test="username!=null and username!=''">
		and username like '%${username}%'
		</if>
		</where>
	</select>
2.3 forEach  多个遍历解析处理

向sql传递数组或List,mybatis使用foreach解析,如下:
 需求
传入多个id查询用户信息,用下边两个sql实现:


SELECT * FROM USERS WHERE username LIKE '%张%' AND (id =10 OR id =89 OR id=16)
SELECT * FROM USERS WHERE username LIKE '%张%'  id IN (10,89,16)


 在pojo中定义list属性ids存储多个用户id,并添加getter/setter方法

private List<Integer> ids ;

mapper.xml

<select id="findUserByIds" parameterType="cn.chuantao.pojo.QueryVo" resultType="cn.chuantao.pojo.User">

		select * from user
		<where>
			<if test="ids != null">
				<!-- 
				foreach:循环传入的集合参数
				collection:传入的集合的变量名称
				item:每次循环将循环出的数据放入这个变量中
				open:循环开始拼接的字符串
				close:循环结束拼接的字符串
				separator:循环中拼接的分隔符
				 -->
				<foreach collection="ids" item="id" open="id in (" close=")" separator=",">
					#{id}
				</foreach>
			</if>
		</where>
	</select>

测试代码

List<Integer> ids = new ArrayList<Integer>();
		ids.add(1);//查询id为1的用户
		ids.add(10); //查询id为10的用户
		queryVo.setIds(ids);
		List<User> list = userMapper.findUserList(queryVo);
2.4 sql 片段

Sql中可将重复的sql提取出来,使用时用include引用即可,最终达到sql重用的目的,如下:

<sql id="query_user_where">
	<if test="id!=null and id!=''">
		and id=#{id}
	</if>
	<if test="username!=null and username!=''">
		and username like '%${username}%'
	</if>
</sql>

引用

<select id="findUserList" parameterType="user" resultType="user">
		select * from user 
		<where>
		<include refid="query_user_where"/>
		</where>
	</select>

注意:如果引用其它mapper.xml的sql片段,则在引用时需要加上namespace,如下:

<includerefid="namespace.sql片段”/>

3、关联查询

3.1 一对一查询
方法一:构造全体信息类
方法二:使用resultMap,定义专门的resultMap用于映射一对一查询结果

下面展示方法二:和hibernate比较相似

在Orders类中加入User属性,user属性中用于存储关联查询的用户信息,因为订单关联查询用户是一对一关系,所以这里使用单个User对象存储关联查询的用户信息。


mapper.xml

参考上面的输出映射

mapper接口

public List<Orders> findOrdersListResultMap() throws Exception;

测试

Public void testfindOrdersListResultMap()throws Exception{
		//获取session
		SqlSession session = sqlSessionFactory.openSession();
		//获限mapper接口实例
		UserMapper userMapper = session.getMapper(UserMapper.class);
		//查询订单信息
		List<Orders> list = userMapper.findOrdersList2();
		System.out.println(list);
		//关闭session
		session.close();
	}
3.2 一对多的查询

在User中加入Orders属性


mapper.xml

<resultMap type="cn.chuantao.pojo.User" id="userAndOrdersResultMap">
		<id column="id" property="id"/>
		<result column="username" property="username"/>
		<result column="birthday" property="birthday"/>
		<result column="sex" property="sex"/>
		<result column="address" property="address"/>
		
		<!-- 指定对应的集合对象关系映射
		property:将数据放入User对象中的orders属性中
		ofType:指定ordersList属性的泛型类型
		 -->
		<collection property="orders" ofType="cn.chuantao.pojo.Orders">
			<id column="oid" property="id"/>
			<result column="user_id" property="userId"/>
			<result column="number" property="number"/>
			<result column="createtime" property="createtime"/>
		</collection>
	</resultMap>
	<select id="findUserAndOrders" resultMap="userAndOrdersResultMap">
		select a.*, b.id oid ,user_id, number, createtime 
		from user a, orders b where a.id = b.user_id
	</select>
collection部分定义了用户关联的订单信息。表示关联查询结果集
property="orders":关联查询的结果集存储在User对象的上哪个属性。
ofType="orders":指定关联查询的结果集中的对象类型即List中的对象类型。此处可以使用别名,也可以使用全限定名。

<id />及<result/>的意义同一对一查询。



mapper接口

测试


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值