以前的博客在MyBatis第三章节中介绍了多表查询多对1、一对多的状况,这里再对一对1、多堆多的状况作一下说明,也算是将MyBatis这部分的知识作一个补充和完整收尾的工做。java
这里基于一个简单的用户购买商品订单表的案例来进行说明一对一查询的模型:git
用户表user和订单表的关系为:一个用户有多个订单,一个订单只从属于一个用户。github
一对一查询的需求:查询一个订单,与此同时查询出该订单所属的用户:sql
对应数据库中表的设计:数据库
orders订单表:mybatis
user用户表:app
对应建立实体类:dom
Order类:函数
public class Order { private int id; private String orderTime; private int total; private User user; //一个订单从属于一个用户,针对于订单与用户这里是一对一的关系 }
User类:ui
public class User { private int id; private String username; private String password; private Date birthday; }
对应OrderMapper接口及xml中查询sql封装,须要注意的是使用Date_Format函数进行格式封装输出到对应实体order类,
能够将Date类型的ordertime进行标准格式化输出:
public interface OrderMapper { //查询出全部订单,并一并查询出订单对应的用户 List<Order> findAll(); }
<resultMap id="orderMap" type="order"> <id column="oid" property="id"></id> <result column="ordertime" property="orderTime"></result> <result column="total" property="total"></result> <result column="uid" property="user.id"></result> <result column="username" property="user.username"></result> <result column="password" property="user.password"></result> <result column="birthday" property="user.birthday"></result> </resultMap> <select id="findAll" resultMap="orderMap"> SELECT o.id oid, DATE_FORMAT(o.ordertime, '%Y-%m-%d %H:%i:%S') ordertime, o.total, u.id uid, u.username, u.password, u.birthday FROM orders o JOIN USER u ON o.uid = u.id </select>
其中<resultMap>还能够配置成以下,使用<association>进行User类的单独封装映射,注意这里使用了别名简化配置,这里就再也不累述:
<resultMap id="orderMap" type="order"> <id column="oid" property="id"></id> <result column="ordertime" property="orderTime"></result> <result column="total" property="total"></result> <association property="user" javaType="user"> <id column="uid" property="id"></id> <result column="username" property="username"></result> <result column="password" property="password"></result> <result column="birthday" property="birthday"></result> </association> </resultMap>
多对多查询通常设立中间表来关联两张主表,常见的模型是用户User和对应的角色Role。
用户表User和角色表Role的关系为,一个用户有多个角色,一个角色被多个用户使用。
多对多基于查询需求来实现:查询用户表的同时查询出该用户对应的全部角色
数据库表的简单设计以下:
sys_user表(用户表):
sys_role表(角色表):
sys_user_role表(中间表)
对应实体类建立,主要是在用户domain中设计出多方角色的List<Role>属性:
User类:
public class User { private int id; private String username; private String password; private Date birthday; /** * 查询用户同时查询出它全部的角色 */ private List<Role> roleList; }
Role类:
public class Role { private int id; private String roleName; private String roleDesc; }
对应Mapper接口和xml中的sql封装以下:
public interface UserMapper { /** * 查询出全部用户及其对应的角色 * @return */ List<User> findAllUserRole(); }
<?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="com.fengye.mapper.UserMapper"> <resultMap id="userRoleMap" type="user"> <id column="id" property="id"></id> <result column="username" property="username"></result> <result column="password" property="password"></result> <result column="birthday" property="birthday"></result> <!--用户对应多个角色List使用collection: property是实体类对应的属性, ofType是List中每一个元素的类型 注意:使用ofType时,下面封装的property中不能使用role.属性; 注意区分一对一中type属性的封装恰好相反--> <collection property="roleList" ofType="role"> <id column="roleId" property="id"></id> <result column="roleName" property="roleName"></result> <result column="roleDesc" property="roleDesc"></result> </collection> </resultMap> <select id="findAllUserRole" resultMap="userRoleMap"> select * from sys_user u join sys_user_role ur on u.id = ur.userId join sys_role r on r.id = ur.roleId </select> </mapper>
其实基本上对应sql链接写好了,封装注意一下表与表链接的逻辑关系、从属性,链接标签条件的使用,基本上就是熟能生巧的问题了。
本节代码示例已上传至github地址:
https://github.com/devyf/MyBatisReview/tree/master/fengye_mybatis_multi