关系类型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 联表查询 复杂查询相关推荐

  1. java sql 联表查询系统_Spring Hibernate JPA 联表查询 复杂查询(转)

    关系类型Owning-SideInverse-Side one-to-one @OneToOne @OneToOne(mappedBy="othersideName") one-t ...

  2. MYSQL数据库字段关联_MySQL数据库基础——操作关系表、连接查询

    MySQL数据库基础入门--day11 一.操作关联表 1.关联关系: 关联关系有:多对一.多对多和一对多. 一对一关联关系可以应用在以下几方面: (1)分割具有很多列的表 (2)由于安全原因而隔离表 ...

  3. mysql查询3个表_mysql如何实现多表查询,三个数据表的联合查询?

    在mysql查询语句中,为了实现查询到某些信息,我们会用到多表的联合查询.那么如何去实现三表的联合查询呢?下面我给大家举一个例子,现在 我这里有三个表,一个是文件表wenjian,一个是管理角色表ad ...

  4. mysql 连表查询_mysql数据库之联表查询

    表准备: 这次我们用到5张表: class表: student表: score表: course表: teacher表: 表结构模型: 我们针对以下需求分析联表查询: 1.查询所有的课程的名称以及对应 ...

  5. php tp5的联表查询,Thinkphp使用join联表查询的方法

    本篇文章介绍了Thinkphp使用join联表查询的方法,具有一定的参考价值,希望对各位学习thinkphp的朋友有帮助! Thinkphp使用join联表查询的方法 多表联查:$user = M(' ...

  6. 在每个运行中运行多个查询_Spring Data JPA的运行原理及几种查询方式

    Spring Data JPA的运行原理: @PersistenceContext(name="entityManagerFactory") private EntityManag ...

  7. jpa分页查询_spring data jpa 居然提供了这么多查询方式!

    spring data jpa提供了多种查询方式,如下: 方法名称查询 继承Repository接口 测试代码 方法名称中支持的关键字(官方文档提供) 使用JPA命名查询 在User实体中定义jpql ...

  8. java多对多关联数据操作,hibernate实施多对多关联查询时,关联表数据被删除

    hibernate执行多对多关联查询时,关联表数据被删除 本帖最后由 binbb521 于 2012-12-04 11:48:29 编辑 S2SH框架开发的网站,执行两个多对多关系的表查询时,关联两个 ...

  9. jpa调用mysql函数_Spring data jpa 调用存储过程处理返回参数及结果集(示例代码)

    一.环境 1.此随笔内容基于spring boot整合的spring data jpa项目, 2.数据库为mysql 5.7.9版本 二.内容 1. 新建存储过程 pro_query_object B ...

最新文章

  1. Python之配置日志模块logging
  2. python逆转字符串封装_Python 实现文本操作之逆转字符串
  3. 网站如何布局才能更利于提升用户体验?
  4. 头条python面试题_大意了,这几道Python面试题没有答对,Python面试题精选
  5. 一行Java代码判断文件夹是否存在,不存在则新建
  6. 浅谈Nginx负载均衡与F5(硬件)的区别
  7. micropython esp32手册_使用ESP32控制板(二):燒錄MicroPython韌體
  8. ios重签名iReSign
  9. 最详细的讲解 JS 原型与原型链
  10. “约见”面试官系列之常见面试题之第九十二篇之created和mounted区别(建议收藏)
  11. 【C语言】字符数组,碎碎念
  12. linux合并第一列相同的行,linux – 合并重复的行并在最后添加“N / A...
  13. 玩游戏该怎么选择硬盘
  14. 公交/地铁出行测试点
  15. 【工具分享】批量查询公网IP地址
  16. 百度云 java私塾_JAVA私塾-百度云
  17. macOS下安装ENVI
  18. linux etcfstab文件,Linux中/etc/fstab文件详解
  19. Unity 简单RPG对话系统——龙之谷2的NPC对话系统
  20. 架构必知:MySQL 如何实现 ACID ?

热门文章

  1. 小程序wxcharts绘制曲线图
  2. python变量使用前必须声明_python变量不需要声明吗
  3. C++之阻塞和非阻塞区别
  4. 美图多款应用变现难,美图手机撑半边天,潜在危险大
  5. 【Python数据科学】基础函数
  6. Pyhton 描述 归并排序算法详解 时间复杂度,空间复杂度分析
  7. 兄弟3150cdn灯亮error_兄弟2240d打印机drum和error灯同时亮该怎么解决?
  8. ant-design中 ProTable隐藏查询重置、设置或某一搜索框
  9. position:ablosute和position:relative的简单理解
  10. javaScript中超过int的最大范围