spring data jpa關聯查詢(一對一、一對多、多對多)


  在實際過往的項目中,常用的查詢操作有:1、單表查詢,2、一對一查詢(主表和詳情表)3、一對多查詢(一張主表,多張子表)4、多對多查詢(如權限控制,用戶、角色多對多)。做個總結,所以廢話不多說。

  使用idea構建springboot項目,引入依賴如下:

復制代碼
dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
    &lt;dependency&gt;
        &lt;groupId&gt;com.h2database&lt;/groupId&gt;
        &lt;artifactId&gt;h2&lt;/artifactId&gt;
        &lt;scope&gt;runtime&lt;/scope&gt;
    &lt;/dependency&gt;
    &lt;dependency&gt;
        &lt;groupId&gt;org.projectlombok&lt;/groupId&gt;
        &lt;artifactId&gt;lombok&lt;/artifactId&gt;
        &lt;optional&gt;<span style="color: #0000ff;">true</span>&lt;/optional&gt;
    &lt;/dependency&gt;
    &lt;dependency&gt;
        &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
        &lt;artifactId&gt;spring-boot-starter-test&lt;/artifactId&gt;
        &lt;scope&gt;test&lt;/scope&gt;
    &lt;/dependency&gt;
&lt;/dependencies&gt;</pre>
復制代碼

  使用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>");
    }

     </span><span style="color: #0000ff;">return</span> String.format("Book [id=%s, name=%s, number of pages=%s]"<span style="color: #000000;">, 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
</span><span style="color: #0000ff;">private</span><span style="color: #000000;"> Integer id;

@Column(name </span>= "NUMBER_OF_PAGES"<span style="color: #000000;">)
</span><span style="color: #0000ff;">private</span><span style="color: #000000;"> Integer numberOfPages;

@OneToOne(mappedBy </span>= "bookDetail"<span style="color: #000000;">)
</span><span style="color: #0000ff;">private</span><span style="color: #000000;"> Book book;

</span><span style="color: #0000ff;">public</span><span style="color: #000000;"> BookDetail() {
    </span><span style="color: #0000ff;">super</span><span style="color: #000000;">();
}

</span><span style="color: #0000ff;">public</span><span style="color: #000000;"> BookDetail(Integer numberOfPages) {
    </span><span style="color: #0000ff;">super</span><span style="color: #000000;">();
    </span><span style="color: #0000ff;">this</span>.numberOfPages =<span style="color: #000000;"> numberOfPages;
}

@Override
</span><span style="color: #0000ff;">public</span><span style="color: #000000;"> String toString() {
    </span><span style="color: #0000ff;">if</span> (<span style="color: #0000ff;">null</span> ==<span style="color: #000000;"> book) {
        </span><span style="color: #0000ff;">return</span> String.format("Book [id=%s, name=%s, number of pages=%s]", id, "&lt;EMPTY&gt;"<span style="color: #000000;">);
    }

    </span><span style="color: #0000ff;">return</span> String.format("Book [id=%s, name=%s, number of pages=%s]"<span style="color: #000000;">, 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
</span><span style="color: #0000ff;">private</span><span style="color: #000000;"> BookRepository bookRepository;

@Autowired
</span><span style="color: #0000ff;">private</span><span style="color: #000000;"> BookDetailRepository bookDetailRepository;

@Before
</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> init() {
    Book bookA </span>= <span style="color: #0000ff;">new</span> Book("Spring in Action", <span style="color: #0000ff;">new</span> BookDetail(208<span style="color: #000000;">));
    Book bookB </span>= <span style="color: #0000ff;">new</span> Book("Spring Data in Action", <span style="color: #0000ff;">new</span> BookDetail(235<span style="color: #000000;">));
    Book bookC </span>= <span style="color: #0000ff;">new</span> Book("Spring Boot in Action"<span style="color: #000000;">);
    bookRepository.saveAll(Arrays.asList(bookA, bookB, bookC));
}

@After
</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> clear() {
    bookRepository.deleteAll();
}

@Test
</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> find() {
    Book book </span>= bookRepository.findByName("Spring in Action"<span style="color: #000000;">);
    System.err.println(book.toString());
}

@Test
</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> save() {
    Book book </span>= <span style="color: #0000ff;">new</span> Book("springboot"<span style="color: #000000;">);
    BookDetail bookDetail </span>= <span style="color: #0000ff;">new</span> BookDetail(124<span style="color: #000000;">);
    book.setBookDetail(bookDetail);
    bookRepository.save(book);
}

@Test
</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> delete() {

    bookRepository.deleteById(</span>31<span style="color: #000000;">);
}
@Test
</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> findbook(){
    BookDetail bd </span>= bookDetailRepository.findByNumberOfPages(235<span style="color: #000000;">);
    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;

</span><span style="color: #0000ff;">private</span><span style="color: #000000;"> String name;

@ManyToOne
@JoinColumn(name</span>="publishId"<span style="color: #000000;">)
</span><span style="color: #0000ff;">private</span><span style="color: #000000;"> Publisher publisher;

@Override
</span><span style="color: #0000ff;">public</span><span style="color: #000000;"> String toString() {
    </span><span style="color: #0000ff;">return</span> "Book{" +
            "id=" + id +
            ", name='" + name + '\'' +
            ", publisher=" + publisher.getName() +
            '}'<span style="color: #000000;">;
}

</span><span style="color: #0000ff;">public</span><span style="color: #000000;"> Book(String name) {
    </span><span style="color: #0000ff;">this</span>.name =<span style="color: #000000;"> name;
}

</span><span style="color: #0000ff;">public</span><span style="color: #000000;"> 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
</span><span style="color: #0000ff;">private</span><span style="color: #000000;"> PublisherRepository publisherRepository;

@Autowired
</span><span style="color: #0000ff;">private</span><span style="color: #000000;"> BookRepository bookRepository;

@Before
</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> init() {

    Book book1 </span>= <span style="color: #0000ff;">new</span> Book("spring"<span style="color: #000000;">);
    Book book2 </span>= <span style="color: #0000ff;">new</span> Book("mvc"<span style="color: #000000;">);
    Book book3 </span>= <span style="color: #0000ff;">new</span> Book("mybatis"<span style="color: #000000;">);
    Publisher publisher </span>= <span style="color: #0000ff;">new</span> Publisher("zhonghua"<span style="color: #000000;">);
    Set</span>&lt;Book&gt; set = <span style="color: #0000ff;">new</span> HashSet&lt;Book&gt;<span style="color: #000000;">();
    set.add(book1);
    set.add(book2);
    set.add(book3);
    publisher.setBooks(set);
    publisherRepository.save(publisher);

}

@After
</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> clear() {
    publisherRepository.deleteAll();
}

@Test
</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> find() {
    Publisher publisher </span>= publisherRepository.findByName("zhonghua"<span style="color: #000000;">);
    System.out.println(publisher);
}

@Test
</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> find2() {
    Book book </span>= bookRepository.findByName("mvc"<span style="color: #000000;">);
    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
</span><span style="color: #0000ff;">private</span><span style="color: #000000;"> Integer id;

</span><span style="color: #0000ff;">private</span><span style="color: #000000;"> String name;

@ManyToMany(mappedBy </span>= "authors",fetch =<span style="color: #000000;"> FetchType.EAGER)
</span><span style="color: #0000ff;">private</span> Set&lt;Book&gt;<span style="color: #000000;"> books;

</span><span style="color: #0000ff;">public</span><span style="color: #000000;"> Author() {
    </span><span style="color: #0000ff;">super</span><span style="color: #000000;">();
}

</span><span style="color: #0000ff;">public</span><span style="color: #000000;"> Author(String name) {
    </span><span style="color: #0000ff;">super</span><span style="color: #000000;">();
    </span><span style="color: #0000ff;">this</span>.name =<span style="color: #000000;"> name;
}

@Override
</span><span style="color: #0000ff;">public</span><span style="color: #000000;"> String toString() {
    </span><span style="color: #0000ff;">return</span> "Author{" +
            "id=" + id +
            ", name='" + name + '\'' +
            ", books=" + books.size() +
            '}'<span style="color: #000000;">;
}

}

復制代碼
復制代碼
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
</span><span style="color: #0000ff;">private</span><span style="color: #000000;"> Integer id;

</span><span style="color: #0000ff;">private</span><span style="color: #000000;"> String name;

@ManyToMany(cascade </span>= CascadeType.ALL,fetch =<span style="color: #000000;"> FetchType.EAGER)
@JoinTable(name </span>= "BOOK_AUTHOR", joinColumns =<span style="color: #000000;"> {
        @JoinColumn(name </span>= "BOOK_ID", referencedColumnName = "ID")}, inverseJoinColumns =<span style="color: #000000;"> {
        @JoinColumn(name </span>= "AUTHOR_ID", referencedColumnName = "ID"<span style="color: #000000;">)})
</span><span style="color: #0000ff;">private</span> Set&lt;Author&gt;<span style="color: #000000;"> authors;

</span><span style="color: #0000ff;">public</span><span style="color: #000000;"> Book() {
    </span><span style="color: #0000ff;">super</span><span style="color: #000000;">();
}

</span><span style="color: #0000ff;">public</span><span style="color: #000000;"> Book(String name) {
    </span><span style="color: #0000ff;">super</span><span style="color: #000000;">();
    </span><span style="color: #0000ff;">this</span>.name =<span style="color: #000000;"> name;
    </span><span style="color: #0000ff;">this</span>.authors = <span style="color: #0000ff;">new</span> HashSet&lt;&gt;<span style="color: #000000;">();
}

</span><span style="color: #0000ff;">public</span> Book(String name, Set&lt;Author&gt;<span style="color: #000000;"> authors) {
    </span><span style="color: #0000ff;">super</span><span style="color: #000000;">();
    </span><span style="color: #0000ff;">this</span>.name =<span style="color: #000000;"> name;
    </span><span style="color: #0000ff;">this</span>.authors =<span style="color: #000000;"> authors;
}

@Override
</span><span style="color: #0000ff;">public</span><span style="color: #000000;"> String toString() {
    </span><span style="color: #0000ff;">return</span> "Book{" +
            "id=" + id +
            ", name='" + name + '\'' +
            ", authors=" + authors.size() +
            '}'<span style="color: #000000;">;
}

}

復制代碼
復制代碼
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</span>&lt;Author&gt;<span style="color: #000000;"> 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</span>&lt;Book&gt;<span style="color: #000000;"> findByNameContaining(String name);

}

復制代碼

  在調試過程中,注意實體類的tostring方法的重寫,避免相互引用;此外如果超過兩張表的關聯查詢,建議使用自定義sql,建立相應的pojo來接收查詢結果。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM