springboot-data-jpa注解实现一对多查询
2017-12-29 15:16
417 查看
需求:
根据用户id一次查询出用户信息及其所有订单信息
1. pom.xml中引入依赖
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.8.RELEASE</version>
</parent>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
2. 实体类(最小化配置)
//User
@Entity
@Table(name="t_user")
public class User {
@Id
@GeneratedValue
private int id;
private String name;
//指定User对象在Order中的关联属性
@OneToMany(mappedBy="user")
private Set<Order> orders = new HashSet<Order>();
......省略getter、setter
}
//Order
@Entity
@Table(name="t_order")
public class Order {
@Id
@GeneratedValue
private int id;
private String description;
@ManyToOne(targetEntity=User.class)
@JoinColumn(name="user_id")//默认即为:user_id,也可自定义
private User user;
......省略getter、setter
}
3. UserRepository
@Repository
public class UserRepository {
@PersistenceContext
private EntityManager em;
/**
* 根据用户id查询用户信息及订单信息
* @param id
* @return
*/
public List test(int userId){
//hql
String hql = "select DISTINCT(u) from User u inner join u.orders on u.id="+userId;
//结果集封装为List集合,该集合中包含n个User对象
return em.createQuery(hql).getResultList();
}
}
Hibernate懒加载机制:
懒加载,又叫延迟加载。它是Hibernate为提高程序执行效率而提供的一种机制,即只有真正使用该对象的数据时才会创建。
Hibernate中主要是通过代理(proxy)机制来实现延迟加载。它的具体过程:Hibernate丛数据库获取某一个对象数据时、获取某一个对象的集合属性值时,或获取某一个对象所关联的另一个对象时,由于没有使用该对象的数据,hibernate并不是数据库加载真正的数据,而只是为该对象创建一个代理对象来代表这个对象,这个对象上的所有属性都是默认值;只有在真正需要使用该对象的数据时才创建这个真实对象,真正从数据库中加载它的数据,这样在某些情况下,就可以提高查询效率。
一.Hibernate中默认采用延迟加载的情况主要有以下几种:
1.当调用session上的load()加载一个实体时,会采用延迟加载。
2.当session加载某个实体时,会对这个实体中的集合属性值采用延迟加载
3.当session加载某个实体时,会对这个实体所有单端关联的另一个实体对象采用延迟加载。
二.关闭延迟加载
延迟加载确实会给程序的查询效率带来好处,但有时明确知道数据需要立即加载,如果Hibernate先默认使用延迟加载,而后又必须去数据库加载,反而会降低效率
1.加载单个实体,如果不需要延迟加载,就可以使用session的get()方法。
2.当session加载某个实体时,不需要对这个实体中的集合属性值延迟加载,而是要立即加载。这是可以在映射文件中这个集合的配置元素(set bag list)添加属性lazy=false;
3.当session加载某个实体时,不需要对这个实体所单端关联的另一个实体对象延迟加载,就可以在影射文件中针对这个单端关联的配置元素(<one-to-one><many-to-one>)添加lazy=false;
三.抓取策略
通过asm和cglib二个包实现;Domain是非final的。
1.session.load懒加载。
2.one-to-one(元素)懒加载:
必需同时满足下面三个条件时才能实现懒加载
(主表不能有constrained=true,所以主表没有懒加载)
lazy!=false 2)constrained=true3)fetch=select
3.one-to-many (元素)懒加载:1)lazy!=false 2)fetch=select
4.many-to-one (元素) :1)lazy!=false 2)fetch=select
5.many-to-many (元素) :1)lazy!=false 2)fetch=select
6.能够懒加载的对象都是被改写过的代理对象,当相关联的session没有关闭时,访问这些懒加载对象(代理对象)的属性(getId和getClass除外)hibernate会初始化这些代理,或用Hibernate.initialize(proxy)来初始化代理对象;当相关联的session关闭后,再访问懒加载的对象将出现异常。
上例中:
String hql = "select DISTINCT(u) from User u inner join u.orders on u.id="+userId;
在执行时,hibernate会生成2条sql语句:
sql语句1-----只查询User的基本属性,eg:id、name等:
select distinct
user0_.id as id1_1_,
user0_.name as name2_1_
from t_user user0_ inner join t_order orders1_
on user0_.id=orders1_.user_id and (user0_.id=2)
sql语句2----使用Set<Order>集合时生成:
select
orders0_.user_id as user_id3_0_0_,
orders0_.id as id1_0_0_,
orders0_.id as id1_0_1_,
orders0_.description as descript2_0_1_,
orders0_.user_id as user_id3_0_1_
from t_order orders0_
where
orders0_.user_id=?
若使用下述hql语句,则只会生成1条sql语句:
select DISTINCT(u) from User u inner join fetch u.orders
生成sql语句为:
select distinct
user0_.id as id1_1_0_,
orders1_.id as id1_0_1_,
user0_.name as name2_1_0_,
orders1_.description as descript2_0_1_,
orders1_.user_id as user_id3_0_1_,
orders1_.user_id as user_id3_0_0__,
orders1_.id as id1_0_0__
from
t_user user0_ inner join t_order orders1_
on user0_.id=orders1_.user_id
根据用户id一次查询出用户信息及其所有订单信息
1. pom.xml中引入依赖
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.8.RELEASE</version>
</parent>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
2. 实体类(最小化配置)
//User
@Entity
@Table(name="t_user")
public class User {
@Id
@GeneratedValue
private int id;
private String name;
//指定User对象在Order中的关联属性
@OneToMany(mappedBy="user")
private Set<Order> orders = new HashSet<Order>();
......省略getter、setter
}
//Order
@Entity
@Table(name="t_order")
public class Order {
@Id
@GeneratedValue
private int id;
private String description;
@ManyToOne(targetEntity=User.class)
@JoinColumn(name="user_id")//默认即为:user_id,也可自定义
private User user;
......省略getter、setter
}
3. UserRepository
@Repository
public class UserRepository {
@PersistenceContext
private EntityManager em;
/**
* 根据用户id查询用户信息及订单信息
* @param id
* @return
*/
public List test(int userId){
//hql
String hql = "select DISTINCT(u) from User u inner join u.orders on u.id="+userId;
//结果集封装为List集合,该集合中包含n个User对象
return em.createQuery(hql).getResultList();
}
}
Hibernate懒加载机制:
懒加载,又叫延迟加载。它是Hibernate为提高程序执行效率而提供的一种机制,即只有真正使用该对象的数据时才会创建。
Hibernate中主要是通过代理(proxy)机制来实现延迟加载。它的具体过程:Hibernate丛数据库获取某一个对象数据时、获取某一个对象的集合属性值时,或获取某一个对象所关联的另一个对象时,由于没有使用该对象的数据,hibernate并不是数据库加载真正的数据,而只是为该对象创建一个代理对象来代表这个对象,这个对象上的所有属性都是默认值;只有在真正需要使用该对象的数据时才创建这个真实对象,真正从数据库中加载它的数据,这样在某些情况下,就可以提高查询效率。
一.Hibernate中默认采用延迟加载的情况主要有以下几种:
1.当调用session上的load()加载一个实体时,会采用延迟加载。
2.当session加载某个实体时,会对这个实体中的集合属性值采用延迟加载
3.当session加载某个实体时,会对这个实体所有单端关联的另一个实体对象采用延迟加载。
二.关闭延迟加载
延迟加载确实会给程序的查询效率带来好处,但有时明确知道数据需要立即加载,如果Hibernate先默认使用延迟加载,而后又必须去数据库加载,反而会降低效率
1.加载单个实体,如果不需要延迟加载,就可以使用session的get()方法。
2.当session加载某个实体时,不需要对这个实体中的集合属性值延迟加载,而是要立即加载。这是可以在映射文件中这个集合的配置元素(set bag list)添加属性lazy=false;
3.当session加载某个实体时,不需要对这个实体所单端关联的另一个实体对象延迟加载,就可以在影射文件中针对这个单端关联的配置元素(<one-to-one><many-to-one>)添加lazy=false;
三.抓取策略
通过asm和cglib二个包实现;Domain是非final的。
1.session.load懒加载。
2.one-to-one(元素)懒加载:
必需同时满足下面三个条件时才能实现懒加载
(主表不能有constrained=true,所以主表没有懒加载)
lazy!=false 2)constrained=true3)fetch=select
3.one-to-many (元素)懒加载:1)lazy!=false 2)fetch=select
4.many-to-one (元素) :1)lazy!=false 2)fetch=select
5.many-to-many (元素) :1)lazy!=false 2)fetch=select
6.能够懒加载的对象都是被改写过的代理对象,当相关联的session没有关闭时,访问这些懒加载对象(代理对象)的属性(getId和getClass除外)hibernate会初始化这些代理,或用Hibernate.initialize(proxy)来初始化代理对象;当相关联的session关闭后,再访问懒加载的对象将出现异常。
上例中:
String hql = "select DISTINCT(u) from User u inner join u.orders on u.id="+userId;
在执行时,hibernate会生成2条sql语句:
sql语句1-----只查询User的基本属性,eg:id、name等:
select distinct
user0_.id as id1_1_,
user0_.name as name2_1_
from t_user user0_ inner join t_order orders1_
on user0_.id=orders1_.user_id and (user0_.id=2)
sql语句2----使用Set<Order>集合时生成:
select
orders0_.user_id as user_id3_0_0_,
orders0_.id as id1_0_0_,
orders0_.id as id1_0_1_,
orders0_.description as descript2_0_1_,
orders0_.user_id as user_id3_0_1_
from t_order orders0_
where
orders0_.user_id=?
若使用下述hql语句,则只会生成1条sql语句:
select DISTINCT(u) from User u inner join fetch u.orders
生成sql语句为:
select distinct
user0_.id as id1_1_0_,
orders1_.id as id1_0_1_,
user0_.name as name2_1_0_,
orders1_.description as descript2_0_1_,
orders1_.user_id as user_id3_0_1_,
orders1_.user_id as user_id3_0_0__,
orders1_.id as id1_0_0__
from
t_user user0_ inner join t_order orders1_
on user0_.id=orders1_.user_id
相关文章推荐
- 【spring data jpa】带有条件的查询后分页和不带条件查询后分页实现
- 在Spring Boot中使用Spring-data-jpa实现分页查询
- 【java】spring-data-jpa 集成hibernate实现多条件分页查询
- 在Spring Boot中使用Spring-data-jpa实现分页查询
- SpringMVC+Spring Data JPA +Bootstrap 分页实现和模糊查询分页
- Spring boot data JPA 自定义JPQL语句,以及PagingAndSortingRepository接口实现分页查询
- 在Spring Boot中使用Spring-data-jpa实现分页查询
- 【spring data jpa】带有条件的查询后分页和不带条件查询后分页实现
- Spring MVC结合Spring Data JPA实现按条件查询和分页
- Spring data JPA使用Specification实现动态查询例子
- spring data jpa实现分页查询功能
- 【spring data jpa】带有条件的查询后分页和不带条件查询后分页实现
- SpringBoot中使用Spring Data Jpa 实现简单的动态查询的两种方法
- springdata jpa使用Example快速实现动态查询
- Spring Data JPA 实现多表关联查询
- SpringBoot中使用Spring Data Jpa 实现简单的动态查询的两种方法
- 在Spring Boot中使用Spring-data-jpa实现分页查询
- Spring Data Jpa 查询操作的基本实现(Spring Data Jpa 2)
- SpringData JPA 实现动态条件查询
- 在Spring Boot中使用Spring-data-jpa实现分页查询