java jpa自身关联查询_Spring Hibernate JPA 联表查询 复杂查询
关系类型Owning-SideInverse-Side
one-to-one
@OneToOne
@OneToOne(mappedBy="othersideName")
one-to-many / many-to-one
@ManyToOne
@OneToMany(mappedBy="xxx")
many-to-many
@ManyToMany
@ManyToMany(mappedBy ="xxx")
其中 many-to-many关系的owning-side可以使用@JoinTable声明自定义关联表,比如Book和Author之间的关联表:
@JoinTable(name = "BOOKAUTHOR", joinColumns = { @JoinColumn(name = "BOOKID", referencedColumnName = "id") }, inverseJoinColumns = { @JoinColumn(name = "AUTHORID", referencedColumnName = "id") })
关联关系还可以定制延迟加载和级联操作的行为(owning-side和inverse-side可以分别设置):
通过设置fetch=FetchType.LAZY 或 fetch=FetchType.EAGER来决定关联对象是延迟加载或立即加载。
通过设置cascade={options}可以设置级联操作的行为,其中options可以是以下组合:
CascadeType.MERGE 级联更新
CascadeType.PERSIST 级联保存
CascadeType.REFRESH 级联刷新
CascadeType.REMOVE 级联删除
CascadeType.ALL 级联上述4种操作
4、事件及监听
通过在实体的方法上标注@PrePersist,@PostPersist等声明即可在事件发生时触发这些方法。
四、JPA应用
1、Dependencies
org.springframework.data
spring-data-jpa
2、JPA提供的接口
主要来看看Spring Data JPA提供的接口,也是Spring Data JPA的核心概念:
1):Repository:最顶层的接口,是一个空的接口,目的是为了统一所有Repository的类型,且能让组件扫描的时候自动识别。
2):CrudRepository :是Repository的子接口,提供CRUD的功能
public interface CrudRepositoryextends Repository {
S save(S entity);
T findOne(ID primaryKey);
Iterable findAll();
Long count();
void delete(T entity);
boolean exists(ID primaryKey);
// … more functionality omitted
}
3):PagingAndSortingRepository:是CrudRepository的子接口,添加分页和排序的功能
public interface PagingAndSortingRepository extends CrudRepository {
Iterable findAll(Sort sort);
Page findAll(Pageable pageable);
}
4):JpaRepository:是PagingAndSortingRepository的子接口,增加了一些实用的功能,比如:批量操作等。
5):JpaSpecificationExecutor:用来做负责查询的接口
public interface JpaSpecificationExecutor{
T findOne(Specification spec);
List findAll(Specification spec);
Page findAll(Specification spec, Pageable pageable);
List findAll(Specification spec, Sort sort);
long count(Specification spec);
}
6):Specification:是Spring Data JPA提供的一个查询规范,要做复杂的查询,只需围绕这个规范来设置查询条件即可
3、查询语言
3.1 根据名称判别
And
findByLastnameAndFirstname
… where x.lastname = ?1 and x.firstname = ?2
Or
findByLastnameOrFirstname
… where x.lastname = ?1 or x.firstname = ?2
Is,Equals
findByFirstname,findByFirstnameIs,findByFirstnameEquals
… where x.firstname = ?1
Between
findByStartDateBetween
… where x.startDate between ?1 and ?2
LessThan
findByAgeLessThan
… where x.age < ?1
LessThanEqual
findByAgeLessThanEqual
… where x.age ⇐ ?1
GreaterThan
findByAgeGreaterThan
… where x.age > ?1
GreaterThanEqual
findByAgeGreaterThanEqual
… where x.age >= ?1
After
findByStartDateAfter
… where x.startDate > ?1
Before
findByStartDateBefore
… where x.startDate < ?1
IsNull
findByAgeIsNull
… where x.age is null
IsNotNull,NotNull
findByAge(Is)NotNull
… where x.age not null
Like
findByFirstnameLike
… where x.firstname like ?1
NotLike
findByFirstnameNotLike
… where x.firstname not like ?1
StartingWith
findByFirstnameStartingWith
… where x.firstname like ?1(parameter bound with appended %)
EndingWith
findByFirstnameEndingWith
… where x.firstname like ?1(parameter bound with prepended %)
Containing
findByFirstnameContaining
… where x.firstname like ?1(parameter bound wrapped in%)
OrderBy
findByAgeOrderByLastnameDesc
… where x.age = ?1 order by x.lastname desc
Not
findByLastnameNot
… where x.lastname <> ?1
In
findByAgeIn(Collection ages)
… where x.age in ?1
NotIn
findByAgeNotIn(Collection age)
… where x.age not in ?1
True
findByActiveTrue()
… where x.active = true
False
findByActiveFalse()
… where x.active = false
IgnoreCase
findByFirstnameIgnoreCase
… where UPPER(x.firstame) = UPPER(?1)
KeywordSampleJPQL snippet
3.2 @Query
public interface UserRepository extends JpaRepository {
//Declare query at the query method using @Query
@Query("select u from User u where u.emailAddress = ?1")
User findByEmailAddress(String emailAddress);
//Advanced like-expressions in @Query
@Query("select u from User u where u.firstname like %?1")
List findByFirstnameEndsWith(String firstname);
//Declare a native query at the query method using @Query
@Query(value = "SELECT * FROM USERS WHERE EMAIL_ADDRESS = ?1", nativeQuery = true)
User findByEmailAddress(String emailAddress);
//Declare native count queries for pagination at the query method using @Query
@Query(value = "SELECT * FROM USERS WHERE LASTNAME = ?1",countQuery = "SELECT count(*) FROM USERS WHERE LASTNAME = ?1",nativeQuery = true)
Page findByLastname(String lastname, Pageable pageable);
//Declaring manipulating queries
@Modifying
@Query("update User u set u.firstname = ?1 where u.lastname = ?2")
int setFixedFirstnameFor(String firstname, String lastname);
}
3.3 复杂查询 JpaSpecificationExecutor
Criteria 查询:是一种类型安全和更面向对象的查询
这个接口基本是围绕着Specification接口来定义的, Specification接口中只定义了如下一个方法:
Predicate toPredicate(Root root, CriteriaQuery> query, CriteriaBuilder cb);
Criteria查询
基本对象的构建
1:通过EntityManager的getCriteriaBuilder或EntityManagerFactory的getCriteriaBuilder方法可以得到CriteriaBuilder对象
2:通过调用CriteriaBuilder的createQuery或createTupleQuery方法可以获得CriteriaQuery的实例
3:通过调用CriteriaQuery的from方法可以获得Root实例
过滤条件
1:过滤条件会被应用到SQL语句的FROM子句中。在criteria 查询中,查询条件通过Predicate或Expression实例应用到CriteriaQuery对象上。
2:这些条件使用 CriteriaQuery .where 方法应用到CriteriaQuery 对象上
3:CriteriaBuilder也作为Predicate实例的工厂,通过调用CriteriaBuilder 的条件方法( equal,notEqual, gt, ge,lt, le,between,like等)创建Predicate对象。
4:复合的Predicate 语句可以使用CriteriaBuilder的and, or andnot 方法构建
实例:
ImTeacher.java
@Entity
@Table(name = "im_teacher")
public class ImTeacher implements Serializable{
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue
@Column(name = "id")
private int id;
@Column(name = "teacher_id")
private int teacherId;
@Column(name = "name")
private String name = "";
@Column(name = "age")
private int age;
@Column(name = "sex")
private String sex = "";
...
}
ImTeacherDao.java
public interface ImTeacherDao extends PagingAndSortingRepository,JpaSpecificationExecutor{
...
}
@Service
public class ImTeacherDaoService {
@Autowired
ImTeacherDao imTeacherDao;
/**
* 复杂查询测试
* @param page
*/
public Page findBySepc(int page, int size){
PageRequest pageReq = this.buildPageRequest(page, size);
Page imTeachers = this.imTeacherDao.findAll(new MySpec(), pageReq);
return imTeachers;
}
/**
* 建立分页排序请求
*/
private PageRequest buildPageRequest(int page, int size) {
Sort sort = new Sort(Direction.DESC,"age");
return new PageRequest(page,size, sort);
}
private class MySpec implements Specification{
@Override
public Predicate toPredicate(Root root, CriteriaQuery> query, CriteriaBuilder cb) {
//1.混合条件查询
Path exp1 = root.get("name");
Path exp2 = root.get("age");
query.where(cb.like(exp1, "%王%"),cb.equal(exp2, "45"));
//2.多表查询
/*Join join = root.join("imStudent", JoinType.INNER);
Path exp3 = join.get("name");
return cb.like(exp3, "%jy%");*/
return null;
}
}
}
3.4 分页
上个实例的发杂查询已经带有分页,若实例的DAO接口有继承PagingAndSortingRepository接口,则可以直接调用
Page impeacher = imTeacherDao.findAll(new PageRequest(1,20));
3.5 联表查询
方法:
法一:直接用Query语句或者上节复杂的连接查询,查出两张或多张表的数据。
法二:映射,接下来将详细介绍。
1)ImStudent.java
@Entity
@Table(name = "im_student")
public class ImStudent {
@Id
@GeneratedValue
@Column(name = "id")
private int id;
@Column(name = "student_id")
private int studentId;
@Column(name = "name")
private String name = "";
@Column(name = "age")
private int age;
@Column(name = "sex")
private String sex = "";
@Column(name = "teacher_id")
private int teacherId;
@ManyToOne(cascade={CascadeType.MERGE,CascadeType.REFRESH})
@JoinColumn(name="teacher_id", referencedColumnName="id", insertable=false, updatable=false)
private ImTeacher imTeacher;
...
}
2)在ImTeacher.java中添加
@OneToMany(mappedBy="imTeacher",cascade=CascadeType.ALL,fetch=FetchType.LAZY)
private Set imStudent = new HashSet();
...
3)根据学生名字查出其老师信息
@Query("SELECT teacher FROM ImTeacher teacher JOIN teacher.imStudent student WHERE student.name=:name")
ImTeacher findByStuName(@Param("name") String name);
根据老师名字查出其学生列表
@Query("SELECT student FROM ImStudent student JOIN student.imTeacher teacher WHERE teacher.name = :name")
Set findByStudByTeaName(@Param("name") String name);
四、总结
1、Hibernate的DAO层开发比较简单,对于刚接触ORM的人来说,能够简化开发工程,提高开发速度。
2、Hibernate对对象的维护和缓存做的很好,对增删改查的对象的维护要方便。
3、Hibernate数据库移植性比较好。
4、Hibernate功能强大,如果对其熟悉,对其进行一定的封装,那么项目的整个持久层代码会比较简单。
java jpa自身关联查询_Spring Hibernate JPA 联表查询 复杂查询相关推荐
- java sql 联表查询系统_Spring Hibernate JPA 联表查询 复杂查询(转)
关系类型Owning-SideInverse-Side one-to-one @OneToOne @OneToOne(mappedBy="othersideName") one-t ...
- MYSQL数据库字段关联_MySQL数据库基础——操作关系表、连接查询
MySQL数据库基础入门--day11 一.操作关联表 1.关联关系: 关联关系有:多对一.多对多和一对多. 一对一关联关系可以应用在以下几方面: (1)分割具有很多列的表 (2)由于安全原因而隔离表 ...
- mysql查询3个表_mysql如何实现多表查询,三个数据表的联合查询?
在mysql查询语句中,为了实现查询到某些信息,我们会用到多表的联合查询.那么如何去实现三表的联合查询呢?下面我给大家举一个例子,现在 我这里有三个表,一个是文件表wenjian,一个是管理角色表ad ...
- mysql 连表查询_mysql数据库之联表查询
表准备: 这次我们用到5张表: class表: student表: score表: course表: teacher表: 表结构模型: 我们针对以下需求分析联表查询: 1.查询所有的课程的名称以及对应 ...
- php tp5的联表查询,Thinkphp使用join联表查询的方法
本篇文章介绍了Thinkphp使用join联表查询的方法,具有一定的参考价值,希望对各位学习thinkphp的朋友有帮助! Thinkphp使用join联表查询的方法 多表联查:$user = M(' ...
- 在每个运行中运行多个查询_Spring Data JPA的运行原理及几种查询方式
Spring Data JPA的运行原理: @PersistenceContext(name="entityManagerFactory") private EntityManag ...
- jpa分页查询_spring data jpa 居然提供了这么多查询方式!
spring data jpa提供了多种查询方式,如下: 方法名称查询 继承Repository接口 测试代码 方法名称中支持的关键字(官方文档提供) 使用JPA命名查询 在User实体中定义jpql ...
- java多对多关联数据操作,hibernate实施多对多关联查询时,关联表数据被删除
hibernate执行多对多关联查询时,关联表数据被删除 本帖最后由 binbb521 于 2012-12-04 11:48:29 编辑 S2SH框架开发的网站,执行两个多对多关系的表查询时,关联两个 ...
- jpa调用mysql函数_Spring data jpa 调用存储过程处理返回参数及结果集(示例代码)
一.环境 1.此随笔内容基于spring boot整合的spring data jpa项目, 2.数据库为mysql 5.7.9版本 二.内容 1. 新建存储过程 pro_query_object B ...
最新文章
- 每日一皮:史上最直观的单向循环链表,还不懂算我输!
- AMD正式公布第七代桌面级APU AM4新接口
- HyperLedger Fabric 错误记录
- android 动态添加删除控件,求教Android,动态添加到控件能动态删除吗?
- 为敏感信息设置安全屏障
- cd返回上一 git_如何使用Git实现自动化部署你的项目
- 如何开启mysql计划事件
- oracle批量把小写转换成大写,oracle数据库批量将表名小写转大写
- c语言 函数 收集,c语言库函数大全--资料收集+
- vRealize-Operations-Manager-Appliance-8.2.0 VROPS 8.2安装部署
- impala里面断言的用法
- python 图形库有哪些_Python基本图形绘制库——turtle
- Attach and Detach in VC
- 好用的在线ide------ideone
- opencv之伪彩变换
- .Net平台下的B/S开发框架
- matlab矩阵 代表什么,matlab中矩阵AB是什么意思
- 什么是JWT?详细讲解
- 还在相信男女之间真的有纯友谊?太傻太天真!
- javascript代码前端debug调试方法
热门文章
- docker离线安装oracle11g,docker 离线环境安装oracle
- TMS320F280049C 学习笔记3 可配置逻辑块 Configurable Logic Block (CLB) 技术手册
- 线性时间选择【递归分治法】
- 又逢六月毕业季!老学长聊一聊和导师相处的那些事儿~
- BeanUtils和BeanCopier
- 如何用最快速高效的算法来给一堆袜子配对?
- eclipse查看代码git历史_Eclipse中GIT历史版本比较和回退
- java 管理系统_java角色登录管理系统
- Python GUI编程(Tkinter)——窗口
- pr怎么做手机竖屏视频