JAVAEE框架技术之9-myBatis高级查询技术文档
Posted teayear
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JAVAEE框架技术之9-myBatis高级查询技术文档相关的知识,希望对你有一定的参考价值。
高级查询
Mybatis作为一个ORM框架,也对sql的高级查询作了支持,下面我来学习mybatis中的一对一,一对多, 多对多
案例说明
此案例中的业务关系是用户,订单,订单详情,商品之间的关系,其中
一个订单属性于一个人
一个订单可以有多个订单详情
一个订单详情中包含一个商品信息
它们的关系是:
订单和人是一对一关系
订单和订单详情是一对多的关系
订单和商品是多对多的关系
表分析
导入课程资料中的数据库及实体类
业务需求
一对一查询: 查询订单,并且查询出下单人信息。
一对多查询:查询订单,查询出下单人信息并且查询出订单详情。
多对多查询:查询订单,查询出下单人信息并且查询出订单详情中的商品数据。
一对一查询
需求:查询订单,并且查询出下单人信息
sql分析
-- 查询订单,并且查询出下单人的信息
SELECT
*
FROM
tb_user as u
left join tb_order AS o ON u.id = o.user_id
WHERE
o.order_number = 20200921001
代码实现
@Data
public class Order
private Integer id;
private Long userId;
private String orderNumber;
//添加User对象
private User user;
public interface UserMapper
/**
* 一对一:查询订单,并且查询出下单人信息
* @param orderNumber
* @return
*/
public Order oneToOne(@Param("orderNumber") String orderNumber);
<!--一对一-->
<resultMap id="oneToOneResultMap" type="Order" autoMapping="true">
<!--order的id-->
<id property="id" column="id"/>
<!--一对一映射
association: 一对一映射
property: 表示子对象的属性名
javaType: 指定子对象的类型
autoMapping: 完成子对象属性自动映射
-->
<association property="user" javaType="User" autoMapping="true">
<!--user的id-->
<id property="id" column="id"/>
<result property="userName" column="user_name"/>
</association>
</resultMap>
<!--一对一:查询订单,并且查询出下单人信息-->
<select id="oneToOne" resultMap="oneToOneResultMap">
SELECT * FROM
tb_user as u left join tb_order as o on u.id = o.user_id
WHERE
o.order_number = #orderNumber
</select>
public class UserDaoTest
private UserMapper userMapper;
private SqlSession sqlSession;
SqlSessionFactory sqlSessionFactory;
@Before
public void setUp() throws Exception
//指定核心配置文件的位置
String resource = "mybatis-config.xml";
//加载核心配置文件
InputStream inputStream = Resources.getResourceAsStream(resource);
//构建sqlSessionFactory对象
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//获取SqlSession对象,SqlSession可以操作crud
sqlSession = sqlSessionFactory.openSession();
//动态代理
userMapper = sqlSession.getMapper(UserMapper.class);
//一对一查询
@Test
public void oneToOne()
Order order = this.userMapper.oneToOne("20200921001");
System.out.println(order);
一对多查询
**一对多查询:**查询订单,查询出下单人信息并且查询出订单详情
sql分析
-- 查询订单,查询出下单人信息并且查询出订单详情。
SELECT
o.id as o_id,
u.id as u_id,
d.id as d_id,
u.user_name,
o.order_number,
d.total_price
FROM
tb_order AS o
left join tb_user AS u ON o.user_id = u.id
left join tb_orderdetail as d on d.order_id = o.id
WHERE
o.order_number = 20200921001;
代码实现
/**
* 订单表
*/
@Data
public class Order
private Integer id;
private Long userId;
private String orderNumber;
//一对一:添加User对象
private User user;
//一对多:添加Orderdetail
private List<Orderdetail> orderdetails;
/**
* 一对多:查询订单,查询出下单人信息并且查询出订单详情
* @param orderNumber
* @return
*/
public Order oneToMany(@Param("orderNumber") String orderNumber);
<!--一对多-->
<resultMap id="oneToManyResultMap" type="Order" autoMapping="true">
<!--映射order本身-->
<id property="id" column="o_id"/>
<!--映射user子对象-->
<association property="user" javaType="User" autoMapping="true">
<id property="id" column="u_id"/>
</association>
<!--映射Orderdetail-->
<collection property="orderdetails" javaType="List" ofType="Orderdetail" autoMapping="true">
<id property="id" column="d_id"/>
</collection>
</resultMap>
<!--一对多:查询订单,查询出下单人信息并且查询出订单详情-->
<select id="oneToMany" resultMap="oneToManyResultMap">
SELECT
o.id as o_id,
u.id as u_id,
d.id as d_id,
u.user_name,
o.order_number,
d.total_price
FROM
tb_order AS o
left join tb_user AS u ON o.user_id = u.id
left join tb_orderdetail as d on d.order_id = o.id
WHERE
o.order_number = #orderNumber;
</select>
//一对多
@Test
public void oneToMany()
Order order = this.userMapper.oneToMany("20200921001");
System.out.println(order);
多对多查询
**多对多查询:**查询订单,查询出下单人信息并且查询出订单详情中的商品数据
定单和商品表 是多对多的对应关系
sql分析
-- 查询订单,查询出下单人信息并且查询出订单详情中的商品数据。
SELECT
o.id as o_id,
u.id as u_id,
d.id as d_id,
i.id as i_id,
u.user_name,
o.order_number,
d.total_price,
i.item_name
FROM
tb_order AS o
left join tb_user AS u ON o.user_id = u.id
left join tb_orderdetail as d on d.order_id = o.id
left join tb_item as i on d.item_id = i.id
WHERE
o.order_number = 20200921001
代码实现
@Data
public class Orderdetail
private Integer id;
private Double totalPrice;
private Integer status;
/*商品信息*/
private Item item;
/**
* 多对多查询:查询订单,查询出下单人信息并且查询出订单详情中的商品数据。
* @param orderNumber
* @return
*/
public Order manyToMany(@Param("orderNumber") String orderNumber);
<!--多对多-->
<resultMap id="manyToManyResultMap" type="Order" autoMapping="true">
<!--映射order本身-->
<id property="id" column="o_id"/>
<!--映射user子对象-->
<association property="user" javaType="User" autoMapping="true">
<id property="id" column="u_id"/>
</association>
<!--映射Orderdetail-->
<collection property="orderdetails" javaType="List" ofType="Orderdetail" autoMapping="true">
<id property="id" column="d_id"/>
<!--映射item子对象-->
<association property="item" javaType="Item" autoMapping="true">
<id property="id" column="i_id"/>
</association>
</collection>
</resultMap>
<!--多对多查询:查询订单,查询出下单人信息并且查询出订单详情中的商品数据。-->
<select id="manyToMany" resultMap="manyToManyResultMap">
SELECT
o.id as o_id,
u.id as u_id,
d.id as d_id,
i.id as i_id,
u.user_name,
o.order_number,
d.total_price,
i.item_name
FROM
tb_order AS o
left join tb_user AS u ON o.user_id = u.id
left join tb_orderdetail as d on d.order_id = o.id
left join tb_item as i on d.item_id = i.id
WHERE
o.order_number = #orderNumber
</select>
//多对多
@Test
public void manyToMany()
Order order = this.userMapper.manyToMany("20200921001");
System.out.println(order);
ResultMap的继承
回顾以上多表映射中resultMap映射中其实有 一对一,一对多,多对多中都有一对一对映射很重复的,每一次都需要写,不好,其实我们可以把相同的一对一映射进行抽取,然后再继承过来。
代码实现
分页插件
PageHelper分页插件
Mybatis的plugin实现原理
添加依赖
<!--分页-->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>3.7.5</version>
</dependency>
<dependency>
<groupId>com.github.jsqlparser</groupId>
<artifactId>jsqlparser</artifactId>
<version>0.9.1</version>
</dependency>
配置插件
<!--分页插件-->
<plugins>
<!-- com.github.pagehelper为PageHelper类所在包名 -->
<plugin interceptor="com.github.pagehelper.PageHelper">
<!--数据库方言-->
<property name="dialect" value="mysql"/>
<!-- 设置为true时,使用RowBounds分页会进行count查询 -->
<property name="rowBoundsWithCount" value="true"/>
</plugin>
</plugins>
5.x后续方案
<plugin interceptor="com.github.pagehelper.PageInterceptor">
<property name="helperDialect" value="mysql"/>
<property name="reasonable" value="true"/>
</plugin>
实现分页
/**
* 分页查询
* @return
*/
public List<User> queryAll();
<!--分页查询-->
<select id="queryAll" resultType="User">
select * from tb_user
</select>
//分页查询
@Test
public void queryAll()
//实现分页 参数1:当前页(从1开始) 参数2:显示多少条
PageHelper.startPage(2, 2);
//你只管查询所有,如何分页交给 PageHelper.startPage(2, 2);完成
List<User> users = this.userMapper.queryAll();
for (User user : users)
System.out.println(user);
//获取更多的分页信息
PageInfo<User> pageInfo = new PageInfo<User>(users);
System.out.println("当前页:" + pageInfo.getPageNum());
System.out.println("当前页显示的条数:" + pageInfo.getPageSize());
System.out.println("总页码:" + pageInfo.getPages());
System.out.println("最后一页:" + pageInfo.getLastPage());
System.out.println("分页相关的信息:" + pageInfo.getList());
System.out.println("分页总条数:" + pageInfo.getTotal());
懒加载(延迟加载)
思考问题?
一对多:我们查询用户时,要不要把关联的订单查询出来
多对一:我们查询订单时,要不要把关联的用户查询出来
什么是懒加载?
就是在需要它的时候才加载,不需要的话就不加载
使用场景
一对多,多对多 通常采用延迟加载
一对一,多对一 通常采用立即加载
配置懒加载
<settings>
<!-- lazyLoadingEnabled:延迟加载启动,默认是false 相当于是否开启延迟加载 -->
<setting name="lazyLoadingEnabled" value="true" />
<!--aggressiveLazyLoading:积极的懒加载,falsed话按需加载,默认是true -->
<setting name="aggressiveLazyLoading" value="false"></setting>
</settings>
一对多 collection延迟加载
一对多:我们查询用户时,要不要把关联的订单查询出来
@Data
public class User
private Long id;
private String userName;
private String password;
private String name;
private Integer age;
private Integer sex;
private Date birthday;
private Date created;
private Date updated;
/*在一方添加多方对象*/
private List<Order> orders;
public List<User> queryAllUser(Integer id);
public Order queryOrderById(Integer id);
<resultMap id="userByIdMap" type="User" autoMapping="true">
<!--一对多,延迟加载-->
<collection property="orders" column="id" select="cn.yanqi.mapper.UserMapper.queryOrderById" ofType="Order" autoMapping="true"/>
</resultMap>
<select id="queryAllUser" resultMap="userByIdMap">
select * from tb_user where id = #id
</select>
<select id="queryOrderById" resultType="Order">
select * from tb_order where id = #id
</select>
JAVAEE框架技术之9-myBatis高级查询技术文档
JAVAEE框架数据库技术之12_oracle常用函数和高级查询子查询