mybatis高级映射

 

 mybatis动态代理实现高级映射,主要整合了mybatis和mysql间的复杂查询方法。在本项目中主要在用户,订单,订单明细,商品明细间进行关联查询操作来理解高级映射。

以下一对一查询,一对多查询,多对多查询三种查询方法主要以resultType(对结果没有特殊的映射要求resultMap(对结果有特殊的映射要求)两种封装方法完成。如果对结果没有特殊的映射要求建议使用resultType,但resultMap 可以实现延迟加载, resultType 无法实现延迟加载。

 

工程结构搭建

  1. 在工程src下创建一个总包cn.mybatis.xhchen
  2. 在总包下创建两个包,cn.mybatis.xhchen.entity实体类包和cn.mybatis.xhchen.mapper接口mapper包
  3. 工程下创建config文件集与src同级
  4. Config下创建mapper包,数据源文件db.properties,日志文件log4j.properties和mybatis的核心配置文件SqlMapConfig.xml

 

 

工程环境搭建

Jar包

db.properties

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8
jdbc.username=root
jdbc.password=root

log4j.properties

# Global logging configuration
log4j.rootLogger=DEBUG, stdout
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n

SqlMapConfig.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration 
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">

<configuration>

	<!-- 加载db.properties配置 -->
	<properties resource="db.properties"></properties>

	<!-- 和spring整合后 environments配置将废除 -->
	<environments default="development">
		<environment id="development">
			<!-- 使用jdbc事务管理 -->
			<transactionManager type="JDBC" />
			<!-- 数据库连接池 -->
			<dataSource type="POOLED">
				<property name="driver" value="${jdbc.driver}" />
				<property name="url" value="${jdbc.url}" />
				<property name="username" value="${jdbc.username}" />
				<property name="password" value="${jdbc.password}" />
			</dataSource>
		</environment>
	</environments>

	<!-- 加载映射文件 -->
	<mappers>
		<!-- 动态代理数据库操作配置文件 -->
		<mapper resource="mapper/ordersMapper.xml"/>
	</mappers>

</configuration>

 

工程编写

 

一对一查询

将查询结果映射到pojo封装,为了更好的了解和区别两种方法,在一对一查询中用了两种封装方法进行查询 。

项目用到的需求:查询订单信息,关联查询用户信息

  1. resultType的封装方法查询

实现较为简单,如果 pojo 中没有包括查询出来的列名,需要增加列名对应的属性,即可完成映射。

映射思路

在Orders.java中添加用户信息字段private Customer customer; 并生成getter/setter。最终会将订单信息映射到 orders 中,订单所对应的用户信息映射到 orders 中的 customer属性中。

cn.mybatis.xhchen.entity下创建订单类Orders.java及其拓展类OrdersCustomer.java,用户类Customer.java

Orders.java

package cn.mybatis.xhchen.entity;

import java.util.Date;
import java.util.List;

/**
 * 
 * ClassName: Orders
 * 
 * @Description: 订单实体类
 * @author XHChen
 * @date 2018年10月12日 下午2:29:25
 */
public class Orders {

	private Integer id; // 订单Id

	private Integer user_id; // 下单用户id

	private String number; // 订单号

	private Date createtime; // 创建订单时间

	private String note; // 备注

	private Customer customer; // 用户信息

	private List<OrderDetail> orderDetail; // 订单明细

	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public Integer getUser_id() {
		return user_id;
	}

	public void setUser_id(Integer user_id) {
		this.user_id = user_id;
	}

	public String getNumber() {
		return number;
	}

	public void setNumber(String number) {
		this.number = number;
	}

	public Date getCreatetime() {
		return createtime;
	}

	public void setCreatetime(Date createtime) {
		this.createtime = createtime;
	}

	public String getNote() {
		return note;
	}

	public void setNote(String note) {
		this.note = note;
	}

	public Customer getCustomer() {
		return customer;
	}

	public void setCustomer(Customer customer) {
		this.customer = customer;
	}

	public List<OrderDetail> getOrderDetail() {
		return orderDetail;
	}

	public void setOrderDetail(List<OrderDetail> orderDetail) {
		this.orderDetail = orderDetail;
	}

	@Override
	public String toString() {
		return "Orders [id=" + id + ", user_id=" + user_id + ", number="
				+ number + ", createtime=" + createtime + ", note=" + note
				+ ", customer=" + customer + ", orderDetail=" + orderDetail
				+ "]";
	}

}

OrdersCustomer.java

package cn.mybatis.xhchen.entity;

/**
 * 
 * ClassName: OrdersCustom
 * 
 * @Description: Custom的拓展类
 * @author XHChen
 * @date 2018年10月12日 下午2:29:44
 */
public class OrdersCustom extends Orders {	

	// 添加用户其他的属性

}

Customer.java

package cn.mybatis.xhchen.entity;

import java.util.List;

/**
 * 
 * ClassName: Customer
 * 
 * @Description: 用户信息
 * @author XHChen
 * @date 2018年10月12日 下午2:34:13
 */
public class Customer {

	private Integer id; // 用户id

	private String username; // 用户名称

	private String sex; // 用户性别

	private String address; // 用户地址

	private List<Orders> orderslist; // 订单列表

	public List<Orders> getOrderslist() {
		return orderslist;
	}

	public void setOrderslist(List<Orders> orderslist) {
		this.orderslist = orderslist;
	}

	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public String getSex() {
		return sex;
	}

	public void setSex(String sex) {
		this.sex = sex;
	}

	public String getAddress() {
		return address;
	}

	public void setAddress(String address) {
		this.address = address;
	}

	@Override
	public String toString() {
		return "Customer [id=" + id + ", username=" + username + ", sex=" + sex
				+ ", address=" + address + ", orderslist=" + orderslist + "]";
	}

}

/config/mapper下创建sql编写文件ordersMapper.xml 编写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">

<mapper namespace="cn.mybatis.xhchen.mapper.OrdersCustomMapper">

	<!-- 一对一查询 -->
	<!-- 查询订单,关联查询用户信息,使用resultType实现 -->
	<select id="findOrderCustomerResultType" resultType="cn.mybatis.xhchen.entity.OrdersCustom">
		SELECT
			orders.*,
			customer.username,
			customer.sex,
			customer.address
		FROM
			orders,
			customer
		WHERE 
			orders.user_id=customer.id

	</select>
</mapper>

 

cn.mybatis.xhchen.mapper下编写OrdersCustomMapper.java接口方法(后面只提供方法内容)

package cn.mybatis.xhchen.mapper;

import java.util.List;

import cn.mybatis.xhchen.entity.Customer;
import cn.mybatis.xhchen.entity.Orders;
import cn.mybatis.xhchen.entity.OrdersCustom;

/**
 * 
 * ClassName: OrdersCustomMapper
 * 
 * @Description: 查询订单
 * @author XHChen
 * @date 2018年10月12日 下午2:26:05
 */
public interface OrdersCustomMapper {

	// 一对一查询订单,关联查询用户信息,resultType实现
	public List<OrdersCustom> findOrderCustomerResultType() throws Exception;

}

编写Junit Test Case测试类方法(后面测试只提供方法内容)

package cn.mybatis.xhchen.mapper;

import java.io.IOException;
import java.io.InputStream;
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.Before;
import org.junit.Test;

import cn.mybatis.xhchen.entity.Customer;
import cn.mybatis.xhchen.entity.Orders;
import cn.mybatis.xhchen.entity.OrdersCustom;

public class OrdersCustomMapperTest {

	// 创建会话工厂
	private SqlSessionFactory sqlSessionFactory;

	@Before
	/**
	 * 
	 * @Description: 加载mapper
	 * @param @throws IOException   
	 * @return void  
	 * @throws
	 * @author XHChen
	 * @date 2018年10月12日 下午2:40:23
	 */
	public void setUp() throws IOException {

		// 定义核心配置文件
		String resource = "SqlMapConfig.xml";

		// 获得核心配置文件流
		InputStream inputStream = Resources.getResourceAsStream(resource);

		// 创建会话工厂,加载配置文件流
		sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

	}

	@Test
	/**
	 * 
	 * @Description: 一对一查询订单,关联查询用户信息,ResultType实现
	 * @param @throws Exception   
	 * @return void  
	 * @throws
	 * @author XHChen
	 * @date 2018年10月12日 下午3:02:42
	 */
	public void testfindOrderCustomerResultType() throws Exception {

		// 开启sqlSession
		SqlSession sqlSession = sqlSessionFactory.openSession();

		// 动态代理
		OrdersCustomMapper ordersCustomMapper = sqlSession.getMapper(OrdersCustomMapper.class);

		List<OrdersCustom> list = ordersCustomMapper.findOrderCustomerResultType();

		// 遍历结果
		for (OrdersCustom ordersCustom : list) {
			System.out.println(ordersCustom);
		}
		System.out.println(list.size());

		sqlSession.close();

	}

}

 

2.resultMap的封装方法查询

如果对查询结果有特殊的要求,使用 resultMap 可以完成将关联查询映射 pojo 的属性中.

/config/mapper下创建sql编写文件ordersMapper.xml 编写sql语句

注意:<select>标签中的resultMap与<resultMap>标签中的id保持一致

        <resultMap type="cn.mybatis.xhchen.entity.Orders" id="OrdersCustomerResultMap">
		<!-- 配置映射的订单信息 -->
		<!-- id:查询列中的唯一标识,订单信息中的唯一标识 column:订单信息的唯一标识 列 property:订单信息的唯一标识列所映射到orders中的那个属性 -->
		<id column="id" property="id" />
		<result column="user_id" property="user_id" />
		<result column="number" property="number" />
		<result column="createtime" property="createtime" />
		<result column="note" property="note" />

		<!-- 配置映射的关联用户信息 -->
		<!--association:用于映射关联查询单个对象的信息 property:要将关联查询的用户信息映射到Orders中那个属性 -->

		<association property="customer" javaType="cn.mybatis.xhchen.entity.Customer">
			<!-- id:关联查询用户的唯一标识 column:指定唯一标识用户信息的列 property:映射到user的那个属性 -->
			<id column="id" property="id" />
			<result column="username" property="username" />
			<result column="sex" property="sex" />
			<result column="address" property="address" />

		</association>
	</resultMap>

	<!-- 查询订单,关联查询用户信息,使用resultMap实现 -->
	<select id="findOrderCustomerResultMap" resultMap="OrdersCustomerResultMap">
		SELECT
			orders.*,
			customer.username,
			customer.sex,
			customer.address
		FROM
			orders,
			customer
		WHERE 
			orders.user_id=customer.id

	</select>

cn.mybatis.xhchen.mapper下编写OrdersCustomMapper.java接口方法

// 一对一查询订单,关联查询用户信息,ResultMap实现
public List<Orders> findOrderCustomerResultMap() throws Exception;

编写Junit Test Case测试类方法

        @Test
	/**
	 * 
	 * @Description: 一对一查询订单,关联查询用户信息,ResultMap实现
	 * @param @throws Exception
	 * @return void
	 * @throws
	 * @author XHChen
	 * @date 2018年10月12日 下午3:22:30
	 */
	public void testfindOrderCustomerResultMap() throws Exception {

		// 开启sqlSession
		SqlSession sqlSession = sqlSessionFactory.openSession();

		// 动态代理
		OrdersCustomMapper ordersCustomMapper = sqlSession.getMapper(OrdersCustomMapper.class);

		List<Orders> list = ordersCustomMapper.findOrderCustomerResultMap();

		// 遍历结果
		for (Orders orders : list) {
			System.out.println(orders);
		}
		System.out.println(list.size());

		sqlSession.close();

	}

 

一对多查询

使用 association将关联查询信息映射到一个pojo对象中 和 collection将关联查询信息映射到一个list集合中 完成一对多高级映射

项目用到的需求:查询订单关联查询用户及订单明细

映射思路

在Orders.java中添加订单明细字段private List<OrderDetail> orderDetail;并生成getter/setter。最终会将订单信息映射到 orders 中,订单所对应的订单明细映射到 orders 中的 orderDetails 属性中。

 

cn.mybatis.xhchen.entity下创建订单明细类OrdersDetail.java

package cn.mybatis.xhchen.entity;

/**
 * 
 * ClassName: OrderDetail
 * 
 * @Description: 订单明细
 * @author XHChen
 * @date 2018年10月12日 下午4:30:50
 */
public class OrderDetail {

	private Integer id; // 明细主键id

	private Integer items_id; // 明细项目

	private Integer items_num; // 明细编号

	private Integer orders_id; // 订单id

	private Items items; // 商品信息

	public Items getItems() {
		return items;
	}

	public void setItems(Items items) {
		this.items = items;
	}

	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public Integer getItems_id() {
		return items_id;
	}

	public void setItems_id(Integer items_id) {
		this.items_id = items_id;
	}

	public Integer getItems_num() {
		return items_num;
	}

	public void setItems_num(Integer items_num) {
		this.items_num = items_num;
	}

	public Integer getOrders_id() {
		return orders_id;
	}

	public void setOrders_id(Integer orders_id) {
		this.orders_id = orders_id;
	}

	@Override
	public String toString() {
		return "OrderDetail [id=" + id + ", items_id=" + items_id
				+ ", items_num=" + items_num + ", orders_id=" + orders_id
				+ ", items=" + items + "]";
	}

}

/config/mapper下创建sql编写文件ordersMapper.xml 编写sql语句

注意:<select>标签中的resultMap与<resultMap>标签中的id保持一致

        <!-- 一对多查询 -->
	<resultMap type="cn.mybatis.xhchen.entity.Orders" id="OrdersAndOrderdetailResultMap" extends="OrdersCustomerResultMap">
		<!-- 继承 OrdersCustomerResultMap-->
		<!-- 配置映射的订单信息 -->
		<!-- 配置映射的关联用户信息 -->
		
		<!-- 关联订单明细信息 
   			一个订单关联查询出了多条订单明细,要使用collection映射
   			collection:对关联查询到的多条记录映射到集合中
    		property:将关联查询到的多条记录映射到orders类的那个属性
    		ofType:指定映射的集合属性中pojo的类型
  		-->
  		<collection property="orderDetail" ofType="cn.mybatis.xhchen.entity.OrderDetail">
  			<!-- id:唯一标识
       			property:要将订单明细的唯一标识映射到com.mybatis.entity.OrderDetail的那个属性
    		-->
  			
  			<id column="id" property="id"/>
  			<result column="items_id" property="items_id"/>
  			<result column="items_num" property="items_num"/>
  			<result column="orders_id" property="orders_id"/>
  		
  		</collection>
	</resultMap>
	
	<!-- 查询订单关联查询用户及订单明细,使用resultMap实现  -->
	<select id="findOrdersAndOrderdetailResultMap" resultMap="OrdersAndOrderdetailResultMap">
		SELECT orders.*,
			customer.username,
			customer.sex,
			customer.address,
			orderdetail.id as orderdetail_id,
			orderdetail.items_id,
			orderdetail.items_num,
			orderdetail.orders_id
		FROM
			orders,
			customer,
			orderdetail
		WHERE 
			orders.user_id = customer.id AND orderdetail.orders_id = orders.id

	</select>

cn.mybatis.xhchen.mapper下编写OrdersCustomMapper.java接口方法

// 一对多查询订单关联查询用户及订单明细,使用resultMap实现
public List<Orders> findOrdersAndOrderdetailResultMap() throws Exception;

编写Junit Test Case测试类方法

        @Test
	/**
	 * 
	 * @Description: 一对多查询订单关联查询用户及订单明细,使用resultMap实现
	 * @param    
	 * @return void  
	 * @throws
	 * @author XHChen
	 * @date 2018年10月12日 下午5:17:32
	 */
	public void findOrdersAndOrderdetailResultMap() throws Exception {
		
		// 开启sqlSession
		SqlSession sqlSession = sqlSessionFactory.openSession();

		// 动态代理
		OrdersCustomMapper ordersCustomMapper = sqlSession.getMapper(OrdersCustomMapper.class);

		List<Orders> list = ordersCustomMapper.findOrdersAndOrderdetailResultMap();
		
		// 遍历
		for (Orders orders : list) {
			System.out.println(orders);
		}
		System.out.println(list.size());
		
		sqlSession.close();
		
	}

 

多对多查询

使用 association将关联查询信息映射到一个pojo对象中 和 collection将关联查询信息映射到一个list集合中 完成一对多高级映射

项目用到的需求:查询用户以及用户购买的商品信息

映射思路

将用户所有信息映射到Customer中。

在Customer中添加订单列表属性private List<Orders> orderslist;,将创建的订单映射到orderslist;

在Orders中添加订单明细属性private List<OrderDetail> orderDetail;,将创建的订单明细映射到orderDetail;

在OrdersDetail中添加商品明细属性private Items items;,将创建的商品信息映射到items。

 

在/config/mapper下创建sql编写文件ordersMapper.xml 编写sql语句

注意:<select>标签中的resultMap与<resultMap>标签中的id保持一致

        <!-- 多对多查询 -->
	<resultMap type="cn.mybatis.xhchen.entity.Customer" id="CustomerAndOrderdetailResultMap">
		<!-- 用户信息 -->
		<id column="id" property="id" />
		<result column="username" property="username" />
		<result column="sex" property="sex" />
		<result column="address" property="address" />
		
		<!-- 订单信息 -->
		<collection property="orderslist" ofType="cn.mybatis.xhchen.entity.Orders">
			<id column="id" property="id" />
			<result column="user_id" property="user_id" />
			<result column="number" property="number" />
			<result column="createtime" property="createtime" />
			<result column="note" property="note" />
		
			<!-- 订单明细信 -->
	  		<collection property="orderDetail" ofType="cn.mybatis.xhchen.entity.OrderDetail">
	  			<id column="id" property="id"/>
	  			<result column="items_id" property="items_id"/>
	  			<result column="items_num" property="items_num"/>
	  			<result column="orders_id" property="orders_id"/>
	  			
	  			<!-- 商品信息 -->
	  			<association property="items" javaType="cn.mybatis.xhchen.entity.Items">
	  				<id column="id" property="id"/>
	  				<result column="items_name" property="items_name"/>
	  				<result column="items_detail" property="items_detail"/>
	  				<result column="items_price" property="items_price"/>
	  			</association>
	  		
	  		</collection>
  		</collection>
	</resultMap>
	
	<!-- 查询用户以及用户购买的商品信息 -->
	<select id="findCustomerAndOrderdetailResultMap" resultMap="CustomerAndOrderdetailResultMap">
		SELECT 
			orders.*,
		    customer.username,
		    customer.sex,
		    customer.address,
			orderdetail.id as orderdetail_id,
		    orderdetail.items_id,
		    orderdetail.items_num,
		    orderdetail.orders_id,
		    items.id as items_id,
		    items.items_name,
		    items.items_detail,
		    items.items_price	
	  	FROM
		    orders,
		    customer,
		    orderdetail,
		    items
	  	WHERE 
	  	    orders.user_id = customer.id AND orderdetail.orders_id = orders.id AND orderdetail.items_id = items.id
	
	</select>

在cn.mybatis.xhchen.mapper下编写OrdersCustomMapper.java接口方法

// 多对多查询用户以及用户购买的商品信息
public List<Customer> findCustomerAndOrderdetailResultMap() throws Exception;

编写Junit Test Case测试类方法

        @Test
	/**
	 * 
	 * @Description: 多对多查询用户以及用户购买的商品信息
	 * @param    
	 * @return void  
	 * @throws
	 * @author XHChen
	 * @date 2018年10月14日 上午10:52:34
	 */
	public void testfindCustomerAndOrderdetailResultMap() throws Exception {
		
		// 开启sqlSession
		SqlSession sqlSession = sqlSessionFactory.openSession();
		
		// 加载动态代理
		OrdersCustomMapper ordersCustomMapper = sqlSession.getMapper(OrdersCustomMapper.class);
		
		// 查询操作
		// 调用mapper方法
		List<Customer> list = ordersCustomMapper.findCustomerAndOrderdetailResultMap();
		
		// 遍历结果
		for (Customer customer : list) {
			System.out.println(customer);
		}
		System.out.println(list.size());
		
		sqlSession.close();
	}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值