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>