在实际过往的项目中,常用的查询操作有:1、单表查询,2、一对一查询(主表和详情表)3、一对多查询(一张主表,多张子表)4、多对多查询(如权限控制,用户、角色多对多)。做个总结,所以废话不多说。

  使用idea构建springboot项目,引入依赖如下:

dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency> <dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

  使用h2数据库做测试用,application.yml配置如下:

spring:
jpa:
generate-ddl: true
hibernate:
ddl-auto: update
properties:
hibenate:
format_sql: false
show-sql: true

  首先,一对一有好几种,这里举例的是常用的一对一双向外键关联(改造成单向很简单,在对应的实体类去掉要关联其它实体的属性即可),并且配置了级联删除和添加,相关类如下:

package io.powerx;

import lombok.*;

import javax.persistence.*;

/**
* Created by Administrator on 2018/8/15.
*/
@Getter
@Setter
@Entity
public class Book {
@Id
@GeneratedValue
private Integer id; private String name; @OneToOne(cascade = {CascadeType.PERSIST,CascadeType.REMOVE})
@JoinColumn(name="detailId",referencedColumnName = "id")
private BookDetail bookDetail; public Book(){
super();
}
public Book(String name){
super();
this.name =name;
} public Book(String name, BookDetail bookDetail) {
super();
this.name = name;
this.bookDetail = bookDetail;
}
@Override
public String toString() {
if (null == bookDetail) {
return String.format("Book [id=%s, name=%s, number of pages=%s]", id, name, "<EMPTY>");
} return String.format("Book [id=%s, name=%s, number of pages=%s]", id, name, bookDetail.getNumberOfPages());
}
}
package io.powerx;

import lombok.Getter;
import lombok.Setter; import javax.persistence.*; @Getter
@Setter
@Entity(name = "BOOK_DETAIL")
public class BookDetail { @Id
@GeneratedValue
private Integer id; @Column(name = "NUMBER_OF_PAGES")
private Integer numberOfPages; @OneToOne(mappedBy = "bookDetail")
private Book book; public BookDetail() {
super();
} public BookDetail(Integer numberOfPages) {
super();
this.numberOfPages = numberOfPages;
} @Override
public String toString() {
if (null == book) {
return String.format("Book [id=%s, name=%s, number of pages=%s]", id, "<EMPTY>");
} return String.format("Book [id=%s, name=%s, number of pages=%s]", id,book.getId(),book.getName());
}
}
package io.powerx;

import org.springframework.data.jpa.repository.JpaRepository;

/**
* Created by Administrator on 2018/8/15.
*/
public interface BookRepository extends JpaRepository<Book,Integer> {
Book findByName(String name);
}
package io.powerx;

import org.springframework.data.jpa.repository.JpaRepository;

/**
* Created by Administrator on 2018/8/15.
*/
public interface BookDetailRepository extends JpaRepository<BookDetail, Integer>{ BookDetail findByNumberOfPages(Integer numberOfPages);
}
package io.powerx;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner; import java.util.Arrays; import static org.junit.Assert.assertThat; @RunWith(SpringRunner.class)
@SpringBootTest
public class OnetooneApplicationTests { @Autowired
private BookRepository bookRepository; @Autowired
private BookDetailRepository bookDetailRepository; @Before
public void init() {
Book bookA = new Book("Spring in Action", new BookDetail(208));
Book bookB = new Book("Spring Data in Action", new BookDetail(235));
Book bookC = new Book("Spring Boot in Action");
bookRepository.saveAll(Arrays.asList(bookA, bookB, bookC));
} @After
public void clear() {
bookRepository.deleteAll();
} @Test
public void find() {
Book book = bookRepository.findByName("Spring in Action");
System.err.println(book.toString());
} @Test
public void save() {
Book book = new Book("springboot");
BookDetail bookDetail = new BookDetail(124);
book.setBookDetail(bookDetail);
bookRepository.save(book);
} @Test
public void delete() { bookRepository.deleteById(31);
}
@Test
public void findbook(){
BookDetail bd = bookDetailRepository.findByNumberOfPages(235);
System.err.println(bd.toString()); }
}

  一对多双向,相关类如下:

package io.powerx;

import lombok.Data;
import lombok.Getter;
import lombok.Setter; import javax.persistence.*; @Getter
@Setter
@Entity
public class Book {
@Id
@GeneratedValue
private Integer id; private String name; @ManyToOne
@JoinColumn(name="publishId")
private Publisher publisher; @Override
public String toString() {
return "Book{" +
"id=" + id +
", name='" + name + '\'' +
", publisher=" + publisher.getName() +
'}';
} public Book(String name) {
this.name = name;
} public Book() {
}
}
package io.powerx;

import lombok.Data;
import lombok.Getter;
import lombok.Setter; import javax.persistence.*;
import java.util.HashSet;
import java.util.Set; /**
* Created by Administrator on 2018/8/16.
*/
@Getter
@Setter
@Entity
public class Publisher {
@Id
@GeneratedValue
private Integer id; private String name; @OneToMany(cascade = CascadeType.ALL,fetch = FetchType.EAGER)
@JoinColumn(name="publishId",referencedColumnName = "id")
private Set<Book> books; public Publisher() {
super();
} public Publisher(String name) {
super();
this.name = name;
} @Override
public String toString() {
return "Publisher{" +
"id=" + id +
", name='" + name + '\'' +
", books=" + books.size() +
'}';
} }
package io.powerx;

import org.springframework.data.jpa.repository.JpaRepository;

/**
* Created by Administrator on 2018/8/16.
*/
public interface BookRepository extends JpaRepository<Book,Integer>{ Book findByName(String name); }
package io.powerx;

import org.springframework.data.jpa.repository.JpaRepository;

/**
* Created by Administrator on 2018/8/16.
*/
public interface PublisherRepository extends JpaRepository<Publisher,Integer> { Publisher findByName(String name);
}
package io.powerx;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner; import java.util.HashSet;
import java.util.Set; @RunWith(SpringRunner.class)
@SpringBootTest
public class OnetomanyApplicationTests { @Autowired
private PublisherRepository publisherRepository; @Autowired
private BookRepository bookRepository; @Before
public void init() { Book book1 = new Book("spring");
Book book2 = new Book("mvc");
Book book3 = new Book("mybatis");
Publisher publisher = new Publisher("zhonghua");
Set<Book> set = new HashSet<Book>();
set.add(book1);
set.add(book2);
set.add(book3);
publisher.setBooks(set);
publisherRepository.save(publisher); } @After
public void clear() {
publisherRepository.deleteAll();
} @Test
public void find() {
Publisher publisher = publisherRepository.findByName("zhonghua");
System.out.println(publisher);
} @Test
public void find2() {
Book book = bookRepository.findByName("mvc");
System.out.println(book);
}
}

  多对多双向,相关代码如下:

package io.powerx;

import lombok.Getter;
import lombok.Setter;
import lombok.ToString; import javax.persistence.*;
import java.util.Set; @Getter
@Setter
@Entity
public class Author { @Id
@GeneratedValue
private Integer id; private String name; @ManyToMany(mappedBy = "authors",fetch = FetchType.EAGER)
private Set<Book> books; public Author() {
super();
} public Author(String name) {
super();
this.name = name;
} @Override
public String toString() {
return "Author{" +
"id=" + id +
", name='" + name + '\'' +
", books=" + books.size() +
'}';
}
}
package io.powerx;

import lombok.Getter;
import lombok.Setter;
import lombok.ToString; import javax.persistence.*;
import java.util.HashSet;
import java.util.Set; @Getter
@Setter
@Entity
public class Book { @Id
@GeneratedValue
private Integer id; private String name; @ManyToMany(cascade = CascadeType.ALL,fetch = FetchType.EAGER)
@JoinTable(name = "BOOK_AUTHOR", joinColumns = {
@JoinColumn(name = "BOOK_ID", referencedColumnName = "ID")}, inverseJoinColumns = {
@JoinColumn(name = "AUTHOR_ID", referencedColumnName = "ID")})
private Set<Author> authors; public Book() {
super();
} public Book(String name) {
super();
this.name = name;
this.authors = new HashSet<>();
} public Book(String name, Set<Author> authors) {
super();
this.name = name;
this.authors = authors;
} @Override
public String toString() {
return "Book{" +
"id=" + id +
", name='" + name + '\'' +
", authors=" + authors.size() +
'}';
}
}
package io.powerx;

import org.springframework.data.jpa.repository.JpaRepository;

import java.util.List;

public interface AuthorRepository extends JpaRepository<Author, Integer> {

    Author findByName(String name);

    List<Author> findByNameContaining(String name);

}
package io.powerx;

import org.springframework.data.jpa.repository.JpaRepository;

import java.util.List;

public interface BookRepository extends JpaRepository<Book, Integer> {

    Book findByName(String name);

    List<Book> findByNameContaining(String name);

}

  在调试过程中,注意实体类的tostring方法的重写,避免相互引用;此外如果超过两张表的关联查询,建议使用自定义sql,建立相应的pojo来接收查询结果。

spring data jpa关联查询(一对一、一对多、多对多)的更多相关文章

  1. spring data jpa 分页查询

    https://www.cnblogs.com/hdwang/p/7843405.html spring data jpa 分页查询   法一(本地sql查询,注意表名啥的都用数据库中的名称,适用于特 ...

  2. spring data JPA entityManager查询 并将查询到的值转为实体对象

    spring data JPA entityManager查询 并将查询到的值转为实体对象 . https://blog.csdn.net/qq_34791233/article/details/81 ...

  3. 【Spring Data 系列学习】Spring Data JPA 基础查询

    [Spring Data 系列学习]Spring Data JPA 基础查询 前面的章节简单讲解了 了解 Spring Data JPA . Jpa 和 Hibernate,本章节开始通过案例上手 S ...

  4. Spring Boot 入门系列(二十七)使用Spring Data JPA 自定义查询如此简单,完全不需要写SQL!

    前面讲了Spring Boot 整合Spring Boot JPA,实现JPA 的增.删.改.查的功能.JPA使用非常简单,只需继承JpaRepository ,无需任何数据访问层和sql语句即可实现 ...

  5. springboot集成Spring Data JPA数据查询

    1.JPA介绍 JPA(Java Persistence API)是Sun官方提出的Java持久化规范.它为Java开发人员提供了一种对象/关联映射工具来管理Java应用中的关系数据.它的出现主要是为 ...

  6. Spring Data JPA 简单查询--接口方法

    一.接口方法整理速查 下表针对于简单查询,即JpaRepository接口(继承了CrudRepository接口.PagingAndSortingRepository接口)中的可访问方法进行整理.( ...

  7. Spring Data JPA 实例查询

    一.相关接口方法     在继承JpaRepository接口后,自动拥有了按"实例"进行查询的诸多方法.这些方法主要在两个接口中定义,一是QueryByExampleExecut ...

  8. springboot整合spring data jpa 动态查询

    Spring Data JPA虽然大大的简化了持久层的开发,但是在实际开发中,很多地方都需要高级动态查询,在实现动态查询时我们需要用到Criteria API,主要是以下三个: 1.Criteria ...

  9. Spring Data JPA 条件查询的关键字

    Spring Data JPA 为此提供了一些表达条件查询的关键字,大致如下: And --- 等价于 SQL 中的 and 关键字,比如 findByUsernameAndPassword(Stri ...

随机推荐

  1. Leaflet入门:添加点线面并导入GeoJSON数据|Tutorial of Leaflet: Adding Points, Lines, Polygons and Import GeoJSON File

    Web GIS系列: 1.搭建简易Web GIS网站:使用GeoServer+PostgreSQL+PostGIS+OpenLayers3 2.使用GeoServer+QGIS发布WMTS服务 3.使 ...

  2. jmeter - 命令行方式运行

    命令格式: jmeter -n -t <testplan filename> -l <listener filename> 参数说明: -n 非 GUI 模式 -> 在非 ...

  3. 状压DP学习笔记

    有的时候,我们会发现一些问题的状态很难直接用几个数表示,这个时候我们就会用到状压dp啦~~. 状压就是状态压缩,就是讲原本复杂难以描述的状态用一个数或者几个数来表示qwq.状态压缩是一个很常用的技巧, ...

  4. ATX 免越狱调试IOS和Android

    利用ATX配合WDA进行图形识别+自动化测试 通过使用AutomatorX,配合WebDriverAgent,可以实现在非越狱的IOS设备上更简单的进行自动化测试.同样,Android设备一样受到支持 ...

  5. java 实验3 继承+多态

    实验3  继承与多态 **类可以实现多个接口 但只有单继承!** 1.继承 1).继承语法  class 子类名 extends 父类{    } 2).构造函数(通过source即可得到) 注意: ...

  6. input获取、失去焦点对输入内容做验证

    获取焦点 # 重新获取焦掉后,会将指定标签中的css样式删除,这里为标记错误的css样式(将文本框标红) $("form input").focus(function () { $ ...

  7. Your branch is ahead of 'origin/master' by 1 commit.

    git reset HEAD^ --soft git reset HEAD^ --hard --soft 表示保留当前commit,重新commit --hard 表示丢弃当前add,重新add.co ...

  8. 多张表进行关联查询---->删除某个数据的时候出现还有子记录的提示

    多张表进行关联查询的时候,当某张表里面的一个字段在另外一张表有定义,就相当于一张表是另外一张表的子表:比如现在开发所遇到的一个问题: 这个是在删除sys_user表的里面的数据的时候出现的问题,因为s ...

  9. short s1 = 1; s1 = s1 + 1;有什么错? short s1 = 1; s1 += 1;有什么错?

    对于 short s1 = 1; s1 = s1 + 1;由于 s1+1运算时会自动提升表达式的类型,所以结果是 int型,再赋值给 short 类型 s1时, 编译器将报告需要强制转换类型的错误.对 ...

  10. 1.jQuery入口函数

    <!--注意,如果需要对ie67兼容,我们可以使用原生低版本的jquery 比如说jquery-1.12.4.js--> <!DOCTYPE html> <html la ...