Mybatis学习二

输入映射和输出映射 (自动映射和手动映射)

Sql映射文件(mapper.xml)中定义了操作数据库的sql,每个sql是一个statement,映射文件是mybatis的核心。

parameterType(输入类型)

1传递简单类型:使用#{}占位符,或者${}进行sql拼接。

2传递pojo对象:Mybatis使用ognl表达式解析对象字段的值,#{}或者${}括号中的值为pojo属性名称。

3传递pojo包装对象:开发中通过可以使用pojo传递查询条件。

查询条件可能是综合的查询条件,不仅包括用户查询条件还包括其它的查询条件(比如查询用户信息的时候,将用户购买商品信息也作为查询条件),这时可以使用包装对象传递输入参数

包装对象:Pojo类中的一个属性是另外一个pojo

需求1:根据用户名模糊查询用户信息,查询条件放到QueryVouser属性中

使用包装类型查询用户。

创建Mapper接口的动态代理对象,整合之后,交给spring管理。

UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

创建对象,设置到包装对象中。

 

resultType(输出类型)

1)输出简单类型,输出简单类型必须查询出来的结果集有一条记录,最终将第一个字段的值转换为输出类型。

2)输出pojo对象

3)输出pojo集合

 

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

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

数据库表、Order对象、创建OrderMapper.xml配置文件、Mapper接口

使用resultMap:由于上边的mapper.xmlsql查询列(user_id)Order类属性(userId)不一致,所以查询结果不能映射到pojo中。

需要定义resultMap,将sql查询列(user_id)Order类属性(userId)对应起来。

 

<mapper namespace="cn.itcast.mybatis.mapper.OrderMapper">

<!-- resultMap最终还是要将结果映射到pojo上,type就是指定映射到哪一个pojo -->

<!-- id设置ResultMapid -->

<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>

 

动态sql:通过mybatis提供的各种标签方法实现动态拼接sql

需求:根据性别和名字查询用户

查询sqlSELECT id, username, birthday, sex, address FROM `user` WHERE sex = 1 AND username LIKE '%%'

解决方案:使用动态sqlif标签。

<select id="queryUserByWhere" parameterType="user" resultType="user">

SELECT id, username, birthday, sex, address FROM `user`

WHERE 1=1

<if test="sex != null and sex != ''">

AND sex = #{sex}

</if>

<if test="username != null and username != ''">

AND username LIKE

'%${username}%'

</if>

</select>

注意字符串类型的数据需要要做不等于空字符串校验。

Where标签

<!-- 根据条件查询用户 -->

<select id="queryUserByWhere" parameterType="user" resultType="user">

SELECT id, username, birthday, sex, address FROM `user`

<!-- where标签可以自动添加where,同时处理sql语句中第一个and关键字-->

<where>

<if test="sex != null">

AND sex = #{sex}

</if>

<if test="username != null and username != ''">

AND username LIKE

'%${username}%'

</if>

</where>

</select>

 

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

sql片段确定id,复用sql语句的目的。

把上面例子中的id, username, birthday, sex, address提取出来,作为sql片段。

SELECT <include refid="userFields" /> FROM `user`

<!-- 使用include标签加载sql片段;refidsql片段id -->

如果要使用别的Mapper.xml配置的sql片段,可以在refid前面加上对应的Mapper.xmlnamespace

 

foreach标签:向sql传递数组或Listmybatis使用foreach解析。

根据多个id查询用户信息

查询sqlSELECT * FROM user WHERE id IN (1,10,24)

<!-- 根据ids查询用户-->

<select id="queryUserByIds" parameterType="queryVo" resultType="user">

SELECT * FROM `user`

<where>

<!-- foreach标签,进行遍历 -->

<!-- collection:遍历的集合,这里是QueryVoids属性-->

<!-- item:遍历的项目,可以随便写,,但是和后面的#{}里面要一致-->

<!-- open:在前面添加的sql片段-->

<!-- close:在结尾处添加的sql片段-->

<!-- separator:指定遍历的元素之间使用的分隔符 -->

<foreach collection="ids" item="item" open="id IN (" close=")"

separator=",">

#{item}

</foreach>

</where>

</select>

oreach循环遍历注意事项:

传递数组:array 。传递集合:list。和数据类型有关系,和变量名称没有关系的。


关联查询:连接查询(关联条件)

一对一关联查询一对多关联查询。一个用户可以有多个订单,一个订单不能归属于多个人。

需求:查询所有订单信息,关联查询下单用户信息。

注意:因为一个订单信息只会是一个人下的订单,所以从查询订单信息出发关联查询用户信息为一对一查询。如果从用户信息出发查询用户下的订单信息则为一对多查询,因为一个用户可以下多个订单。

Left join  左关联   full join 全关联(求交集或者并集)  on  主外键相等(关联条件)

要查询出哪些字段?

记忆关联查询的sql语句。

以订单为中心,关联用户进行查询。把sql映射文件中的数据库语句写的工整一些。

 

单表查询,如何进行映射;多表查询,每个字段都需要进行手动映射,不能省略。

定义专门的pojo类作为输出类型,其中定义了sql查询结果集所有的字段。此方法较为简单,企业中使用普遍。

使用resultMap,定义专门的resultMap用于映射一对一查询结果

<resultMap type="order" id="orderUserResultMap">

<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" />

 

<!-- association :配置一对一属性 -->

<!-- property:order里面的User属性名 -->

<!-- javaType:属性类型 -->

<association property="user" javaType="user">

<!-- id:声明主键,表示user_id是关联查询对象的唯一标识-->

<id property="id" column="user_id" />

<result property="username" column="username" />

<result property="address" column="address" />

</association>

 

</resultMap>

 

<!-- 一对一关联,查询订单,订单内部包含用户属性 -->

<select id="queryOrderUserResultMap" resultMap="orderUserResultMap">

SELECT

o.id,

o.user_id,

o.number,

o.createtime,

o.note,

u.username,

u.address

FROM

`order` o

LEFT JOIN `user` u ON o.user_id = u.id

</select>

 

查询所有用户信息及用户关联的订单信息。

用户信息和订单信息为一对多关系。

附加对象集合

<resultMap type="user" id="userOrderResultMap">

<id property="id" column="id" />

<result property="username" column="username" />

<result property="birthday" column="birthday" />

<result property="sex" column="sex" />

<result property="address" column="address" />

 

<!-- 配置一对多的关系 -->

<collection property="orders" javaType="list" ofType="order">

<!-- 配置主键,是关联Order的唯一标识 -->

<id property="id" column="oid" />

<result property="number" column="number" />

<result property="createtime" column="createtime" />

<result property="note" column="note" />

</collection>

</resultMap>

 

<!-- 一对多关联,查询订单同时查询该用户下的订单 -->

<select id="queryUserOrder" resultMap="userOrderResultMap">

SELECT

u.id,

u.username,

u.birthday,

u.sex,

u.address,

o.id oid,

o.number,

o.createtime,

o.note

FROM

`user` u

LEFT JOIN `order` o ON u.id = o.user_id

</select>



代码如下:

mapper接口:

package com.aowu.cn.mapper;

import java.util.List;

import com.aowu.cn.pojo.Order;
import com.aowu.cn.pojo.QueryVo;
import com.aowu.cn.pojo.User;

/**
 * 新建接口
 * @author chenrushui
 *
 */
public interface UserMapper {
	//通过用户名进行模糊查询
	public List<User> selectUserByQueryVo(QueryVo vo);
	
	//查询用户表的条数
	public Integer countUser();
	
	//查询所有的用户数据
	public List<User> userList();
	
	//通过用户名和性别查询用户
	public List<User> selectUserByNameAndAge(User user);
	
	//通过用户名和性别查询用户
    public List<User> selectUserByNameAndAgeWhere(User user);
    
    //根据多个id查询用户信息
    public List<User> selectUserByIds(List<Integer> ids);
    
    //获取用户订单信息
    public List<Order> selectOrdersList();	
    
    //获取用户所有的订单信息
    public List<User> selectOrders();
}

test类

package com.aowu.cn.junit;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;

import com.aowu.cn.mapper.UserMapper;
import com.aowu.cn.pojo.Order;
import com.aowu.cn.pojo.QueryVo;
import com.aowu.cn.pojo.User;
import com.aowu.cn.pojo.UserTest;

public class TestMyBatis {

	/**
	 * 传入参数的类型是:pojo的包装类
	 * 
	 * @throws IOException
	 */
	@Test
	public void testSelectUserByQueryVo() throws IOException {
		// MyBatis与Spring没有整合之前的操作
		String path = "sqlMapConfig.xml";
		InputStream in = Resources.getResourceAsStream(path);
		SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder()
				.build(in);
		SqlSession sqlSession = sqlSessionFactory.openSession();
		// 加载接口文件,生成动态代理文件
		UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
		User user = new User();
		user.setName("陈");
		QueryVo queryVo = new QueryVo();
		queryVo.setUser(user);
		List<User> userList = (List<User>) userMapper
				.selectUserByQueryVo(queryVo);
		for (User item : userList) {
			System.out.println(item);
		}
		sqlSession.close();
	}

	/**
	 * 输出参数为简单类型
	 * 
	 * @throws IOException
	 */
	@Test
	public void testCountUser() throws IOException {
		String path = "sqlMapConfig.xml";
		InputStream in = Resources.getResourceAsStream(path);
		SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder()
				.build(in);
		SqlSession openSession = sqlSessionFactory.openSession();
		// SqlSession帮助我们生成了一个接口的实现类
		UserMapper mapper = openSession.getMapper(UserMapper.class);
		Integer countUser = mapper.countUser();
		System.out.println("总的条目人数" + countUser);
	}

	/**
	 * 查询用户表中的所有数据 对象属性和数据表字段不对应
	 * 
	 * @throws IOException
	 */
	@Test
	public void testUserList() throws IOException {
		String path = "sqlMapConfig.xml";
		InputStream in = Resources.getResourceAsStream(path);
		SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder()
				.build(in);
		SqlSession openSession = sqlSessionFactory.openSession();
		UserMapper mapper = openSession.getMapper(UserMapper.class);
		List<User> userList = mapper.userList();
		for (User user : userList) {
			System.out.println("test:" + user.toString());
		}
		// 因为是Integer类型,数据不能自动映射,所以为0;想要显示正确的数据,需要手动映射。
		// 需要自动建立手动映射的信息
	}

	/**
	 * if标签
	 * 
	 * @throws IOException
	 */
	@Test
	public void testIfTag() throws IOException {
		String path = "sqlMapConfig.xml";
		InputStream in = Resources.getResourceAsStream(path);
		SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder()
				.build(in);
		SqlSession openSession = sqlSessionFactory.openSession();
		UserMapper mapper = openSession.getMapper(UserMapper.class);
		User userParam = new User();
		userParam.setAge(20);
		// userParam.setName("陈诗音");
		List<User> userList = mapper.selectUserByNameAndAge(userParam);
		if (userList != null && userList.size() > 0) {
			for (User user : userList) {
				System.out.println("测试对象:" + user.toString());
			}
		} else {
			System.out.println("测试对象:" + "没有拿到数据");
		}
	}

	/**
	 * Where标签
	 * 
	 * @throws IOException
	 */
	@Test
	public void testWhereTag() throws IOException {
		String path = "sqlMapConfig.xml";
		InputStream in = Resources.getResourceAsStream(path);
		SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder()
				.build(in);
		SqlSession openSession = sqlSessionFactory.openSession();
		UserMapper mapper = openSession.getMapper(UserMapper.class);
		User userParam = new User();
		// userParam.setAge(20);
		userParam.setName("陈诗音");
		List<User> userList = mapper.selectUserByNameAndAgeWhere(userParam);
		if (userList != null && userList.size() > 0) {
			for (User user : userList) {
				System.out.println("测试对象:" + user.toString());
			}
		} else {
			System.out.println("测试对象:" + "没有拿到数据");
		}
	}

	/**
	 * 测试ForEach标签:根据多个id查询用户信息 用于向sql语句传递集合或者数组
	 * 
	 * @throws IOException
	 */
	@Test
	public void testForEachTag() throws IOException {
		String path = "sqlMapConfig.xml";
		InputStream in = Resources.getResourceAsStream(path);
		SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder()
				.build(in);
		SqlSession openSession = sqlSessionFactory.openSession();
		UserMapper mapper = openSession.getMapper(UserMapper.class);
		ArrayList<Integer> list = new ArrayList<Integer>();
		list.add(2);
		list.add(3);
		list.add(4);
		QueryVo queryVo = new QueryVo();
		queryVo.setIds(list);
		List<User> userList = mapper.selectUserByIds(list);
		if (userList != null && userList.size() > 0) {
			for (User user : userList) {
				System.out.println("测试对象:" + user.toString());
			}
		} else {
			System.out.println("测试对象:" + "没有拿到数据");
		}
	}

	/**
	 * 测试一对一关联
	 * 
	 * @throws IOException
	 */
	@Test
	public void testSelectOrdersList() throws IOException {
		String path = "sqlMapConfig.xml";
		InputStream in = Resources.getResourceAsStream(path);
		SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder()
				.build(in);
		SqlSession openSession = sqlSessionFactory.openSession();
		UserMapper mapper = openSession.getMapper(UserMapper.class);
		List<Order> selectOrdersList = mapper.selectOrdersList();
		for (Order user : selectOrdersList) {
			System.out.println("test:" + user.toString());
		}
	}

	/*
	 * 一对多关联映射:一个用户可能有多个订单信息
	 */
	@Test
	public void testSelectOrders() throws IOException {
		String path = "sqlMapConfig.xml";
		InputStream in = Resources.getResourceAsStream(path);
		SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder()
				.build(in);
		SqlSession openSession = sqlSessionFactory.openSession();
		UserMapper mapper = openSession.getMapper(UserMapper.class);
		List<User> selectOrders = mapper.selectOrders();
		for (User user : selectOrders) {
			System.out.println(user.toString());
		}
	}
}


sql映射文件:具体业务逻辑的sql语句

<?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映射文件存放在单独的目录里面 -->
<!-- Sql映射文件,每张表对应一个sql映射文件,所有对表的操作都写在sql映射文件中 -->
<mapper namespace="com.aowu.cn.mapper.UserMapper">
	<!-- 基本类型的包装类 -->
	<select id="selectUserByQueryVo" parameterType="com.aowu.cn.pojo.QueryVo"
		resultType="com.aowu.cn.pojo.User">
		select * from user where name like "%"#{user.name}"%"
	</select>

	<!-- 基本的输出参数 -->
	<select id="countUser" resultType="Integer">
		select count(*) from user;
	</select>

	<!-- 数据库列字段和对象属性字段不对应,需要手动映射 -->
	<!-- <select id="userList" resultType="com.aowu.cn.pojo.User"> select * 
		from user; </select> -->
	<!-- 手动映射,让字段一一对应起来 -->
	<resultMap type="com.aowu.cn.pojo.User" id="testResultMap">
		<result column="age" property="age_i" />
	</resultMap>
	<select id="userList" resultMap="testResultMap">
		select * from user;
	</select>

	<!-- if标签的使用,如果数据为空,就相当于去掉此判断条件 -->
	<select id="selectUserByNameAndAge" parameterType="com.aowu.cn.pojo.User"
		resultType="com.aowu.cn.pojo.User">
		select * from user
		where age=#{age}
		<if test="name!=null and name!=''">
			and name =#{name}
		</if>
	</select>

	<!-- where标签的使用,前and是可以没有的值的,不会报错;但是如果后面的值没有就会报错 -->
	<!-- sql片段主要用于代码的复用,id refid -->
	<sql id="getData">select * from user</sql>

	<select id="selectUserByNameAndAgeWhere" parameterType="com.aowu.cn.pojo.User"
		resultType="com.aowu.cn.pojo.User">
		<!-- 引用sql片段,复用代码 -->
		<include refid="getData" />
		<where>
			<if test="age!=0">
				age=#{age}
			</if>
			<if test="name!=null and name!=''">
				and name =#{name}
			</if>
		</where>
	</select>

	<!-- ForEach 标签的使用,用于向sql语句传递集合或者数组 id in (1,2,3) -->
	<!-- 如果是数组,集合的类型就是array,必须这样写 -->
	<select id="selectUserByIds" parameterType="com.aowu.cn.pojo.QueryVo"
		resultType="com.aowu.cn.pojo.User">
		<include refid="getData" />
		<where>
			<foreach collection="list" item="id" separator="," open="id in ("
				close=")">
				#{id}
			</foreach>
		</where>
	</select>


	<!-- 一对一关联查询:查询用户信息以及对应的订单信息 ,一个订单对应一个用户 -->
	<!-- 手动映射:要对每一个字段进行手动赋值 -->
	<resultMap type="com.aowu.cn.pojo.Order" id="orderList">
		<result column="product" property="product" />
		<result column="user_id" property="id" />
		<association property="user" javaType="com.aowu.cn.pojo.User">
			<result column="age" property="age" />
			<result column="name" property="name" />
		</association>
	</resultMap>
	<select id="selectOrdersList" resultMap="orderList">
		select
		user.id,
		user.name,
		user.age,
		user_order.user_id,
		user_order.product
		from user left
		join user_order
		on
		user.id=user_order.user_id;
	</select>

	<!--一对多关联查询,一个人可能有多个订单表信息 -->
	<!--手动映射 -->

	<resultMap type="com.aowu.cn.pojo.User" id="orders">
		<result column="id" property="id" />
		<result column="name" property="name" />
		<result column="age" property="age" />
		<collection property="orderList" ofType="com.aowu.cn.pojo.Order">
			<result column="product" property="product" />
			<result column="id" property="id" />
		</collection>
	</resultMap>
	<select id="selectOrders" resultMap="orders">
		select
		user.id,
		user.name,
		user.age,
		user_order.id,
		user_order.product
		from user left join user_order
		on
		user.id=user_order.user_id;
	</select>
</mapper>




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值