MyBatis 是一个优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。对于一对多查询,MyBatis 提供了很好的支持。
原理
MyBatis是一种Java持久层框架,它封装了JDBC操作,大大简化了数据库操作的复杂性。MyBatis一对一和一对多查询的原理主要基于SQL的关联查询。
一对多查询通常指一个表中的记录与另一个表中的多条记录相关联。例如,一个班级有多个学生,一个学生与一个班级相关联。在这种情况下,我们可以使用MyBatis进行一对多查询。
MyBatis的一对多查询原理如下:
配置映射文件:在MyBatis的映射文件中,我们需要配置一对多查询的SQL语句。通常,这个SQL语句是一个JOIN查询,它连接了两个表,并使用外键关联它们。
执行查询:当调用MyBatis的Mapper接口的方法执行查询时,MyBatis会找到相应的SQL语句并执行它。
结果映射:MyBatis将查询结果映射到Java对象。对于一对多关系,通常使用一个Java对象来表示“一”的一方,并使用一个List或Set来存储“多”的一方。
延迟加载:MyBatis支持延迟加载,这意味着当查询“一”的一方时,它不会立即加载“多”的一方。只有当真正需要访问“多”的一方时,MyBatis才会执行相应的查询。
缓存:MyBatis还可以使用缓存来优化一对多查询。如果多次执行相同的查询,MyBatis可以从缓存中获取结果,而不是每次都执行SQL查询。
结果集自动映射:MyBatis支持将查询结果集自动映射到Java对象。通过配置映射文件,可以指定如何将结果集的列映射到Java对象的属性。
总之,MyBatis的一对多查询原理主要基于SQL的关联查询和Java对象的映射。通过配置映射文件和执行查询,MyBatis可以将查询结果映射到Java对象,并支持延迟加载、缓存和结果集自动映射等优化。
思路
思路
在写代码的时候经常有这种需求,一个订单对应多个商品,需要对订单以及商品进行分页模糊搜索,
在首页展示多个满足要求的订单,并且同时展示出订单中的商品信息,
此时需要返回一个list,并且list中对象是一对多的关系,就是对1对多种的多进行分页.这个时候的思路.
我们以一为主表,多为副表进行分析
1.实现:使用mybatis的一对多,就是resultMap中的collections进行数据的接收.
2.思路:
分页主要是多主表进行分页
将主表(一)和副表(多)进行连表查询,组合成一个临时表.
临时表中进行条件筛选,选出符合条件的条目.
使用主表的id进行分组,找出满足条件的主表条目.
使用mybatis中的collection使用id进行一对多查询.
探索
假设我们有一个 User 对象,每个 User 有多个 Order 对象,这是一个典型的一对多关系。
首先,我们需要创建数据库表格和相应的 Java 对象。
User 表:
CREATE TABLE `user` (
`id` INT PRIMARY KEY,
`name` VARCHAR(255),
`email` VARCHAR(255)
);
Order 表:
CREATE TABLE `order` (
`id` INT PRIMARY KEY,
`userId` INT,
`orderName` VARCHAR(255),
FOREIGN KEY (userId) REFERENCES user(id)
);
然后,我们需要创建相应的 Java 对象。
User.java
public class User {
private int id;
private String name;
private String email;
private List<Order> orders;
// getters and setters
}
Order.java
public class Order {
private int id;
private int userId;
private String orderName;
// getters and setters
}
然后,我们需要创建 MyBatis 的映射文件,用于映射数据库表格到 Java 对象。这里是一对多查询的例子:
UserMapper.xml
<select id="getUserWithOrders" resultMap="userWithOrders">
SELECT * FROM user LEFT JOIN order ON user.id = order.userId
</select>
<resultMap id="userWithOrders" type="User">
<id property="id" column="id"/>
<result property="name" column="name"/>
<result property="email" column="email"/>
<collection property="orders" ofType="Order">
<id property="id" column="id"/>
<result property="userId" column="userId"/>
<result property="orderName" column="orderName"/>
</collection>
</resultMap>
在上述的 标签中,我们执行了一个 SQL 查询,该查询将 user 表和 order 表进行了左连接,并将结果映射到 User 对象。在 标签中,我们定义了如何将查询结果映射到 User 对象的各个属性以及 Order 集合。
最后,我们可以在 MyBatis 的映射接口中引用这个映射文件:
UserMapper.java
public interface UserMapper {
User getUserWithOrders();
}
实战
单表
实体
/**
* 雪花id
*/
private String id;
/**
* 部门或人员id
*/
private String uniqId;
/**
* 部门或人员名称
*/
private String uniqName;
/**
* 角色id
*/
private String roleId;
/**
* 角色名称
*/
private String roleName;
/**
* 用户idList
*/
private List<String> userIdList;
/**
* 类型,dept:部门,user:人员
*/
private String type;
/**
* 创建时间
*/
private Date createTime;
/**
* 创建人
*/
private String createUser;
返回map
<resultMap id="userIdMap" type="com.croot.rims.entity.DataPermissionVo">
<id column="id" jdbcType="VARCHAR" property="id" />
<result column="uniqId" jdbcType="VARCHAR" property="uniqId" />
<result column="roleId" jdbcType="VARCHAR" property="roleId" />
<result column="type" jdbcType="VARCHAR" property="type" />
<result column="createTime" jdbcType="TIMESTAMP" property="createTime" />
<result column="createUser" jdbcType="VARCHAR" property="createUser" />
<collection property="userIdList" ofType="java.lang.String">
<id column="userId"/>
</collection>
</resultMap>
sql
<select id="selectiveMore" parameterType="java.lang.String" resultMap="userIdMap">
select
<include refid="Base_Column_List" />
from data_permission
</select>