使用gradle + idea 構建 spring boot + Spring Data JPA,學習spring data jpa語法


Spring Data JPA 是 Spring 基於 ORM 框架、JPA 規范的基礎上封裝的一套JPA應用框架,可使開發者用極簡的代碼即可實現對數據庫的訪問和操作。它提供了包括增刪改查等在內的常用功能,且易於擴展!學習並使用 Spring Data JPA 可以極大提高開發效率!

SpringData Jpa 極大簡化了數據庫訪問層代碼。 如何簡化的呢? 使用了SpringDataJpa,我們的dao層中只需要寫接口,就自動具有了增刪改查、分頁查詢等方法

從下圖可以看出,Spring Data JPA是Spring提供的一套對JPA操作更加高級的封裝,是在JPA規范下的專門用來進行數據持久化的解決方案

我們這里使用idea + gradle構建項目,使用spring boot + spring data jpa

 

接下來看一下spring Data JPA的一些注解;

@Entity 標注用於實體類聲明語句之前,指出該Java 類為實體類,將映射到指定的數據庫表。如聲明一個實體類 Customer,它將映射到數據庫中的 customer 表上。

@Table 當實體類與其映射的數據庫表名不同名時需要使用 @Table 標注說明,該標注與 @Entity 標注並列使用,置於實體類聲明語句之前,可寫於單獨語句行,也可與聲明語句同行。@Table 標注的常用選項是 name,用於指明數據庫的表名,catalog屬性用於指定數據庫實例名,shema作用與catalog一樣,uniqueContraints選項用於設置約束條件

@Id 標注用於聲明一個實體類的屬性映射為數據庫的主鍵列。該屬性通常置於屬性聲明語句之前,可與聲明語句同行,也可寫在單獨行上。

@GeneratedValue 用於標注主鍵的生成策略,通過 strategy 屬性指定。默認情況下,JPA 自動選擇一個最適合底層數據庫的主鍵生成策略:SqlServer 對應 identity,MySQL 對應 auto increment。 在 javax.persistence.GenerationType 中定義了以下幾種可供選擇的策略:

IDENTITY:采用數據庫 ID自增長的方式來自增主鍵字段,Oracle 不支持這種方式;適用於MySQL和SQLServer AUTO:JPA自動選擇合適的策略,是默認選項, 會自動生成一個序列表,通用性比較強。但是MySQL有自增,所以用的比較少 SEQUENCE(序列,適用於Oracle數據庫):通過序列產生主鍵,通過 @SequenceGenerator注解指定序列名,MySql 不支持這種方式 TABLE:通過表產生主鍵,框架借由表模擬序列產生主鍵,使用該策略可以使應用更易於數據庫移植。

@Column 當實體的屬性與其映射的數據庫表的列不同名時需要使用@Column 標注說明,該屬性通常置於實體的屬性聲明語句之前,還可與 @Id 標注一起使用。

  • @Column 標注的常用屬性是 name,用於設置映射數據庫表的列名。此外,該標注還包含其它多個屬性,如:unique 、nullable、length 等。

  • @Column 標注的 columnDefinition 屬性: 表示該字段在數據庫中的實際類型.通常 ORM 框架可以根據屬性類型自動判斷數據庫中字段的類型,但是對於Date類型仍無法確定數據庫中字段類型究竟是DATE,TIME還是TIMESTAMP.此外,String的默認映射類型為VARCHAR, 如果要將 String 類型映射到特定數據庫的 BLOB 或TEXT 字段類型.

@Column標注也可置於屬性的getter方法之前

@Basic 表示一個簡單的屬性到數據庫表的字段的映射,對於沒有任何標注的 getXxxx() 方法,默認即為

@Basic fetch: 表示該屬性的讀取策略,有 EAGER 和 LAZY 兩種,分別表示主支抓取和延遲加載,默認為 EAGER.

optional:表示該屬性是否允許為null, 默認為true

@Transient 表示該屬性並非一個到數據庫表的字段的映射,ORM框架將忽略該屬性. 如果一個屬性並非數據庫表的字段映射,就務必將其標示為@Transient,否則,ORM框架默認其注解為@Basic

@Temporal 在核心的 Java API 中並沒有定義 Date 類型的精度(temporal precision).而在數據庫中,表示 Date 類型的數據有 DATE, TIME, 和 TIMESTAMP 三種精度(即單純的日期,時間,或者兩者 兼備). 在進行屬性映射時可使用@Temporal注解來調整精度。

項目構建直接使用idea + gradle構建項目

build.gradle文件

plugins {
    id 'org.springframework.boot' version '2.2.5.RELEASE'
    id 'io.spring.dependency-management' version '1.0.9.RELEASE'
    id 'java'
}

group = 'com.yang'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '13'

repositories {
    maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' }
    maven{ url 'http://maven.aliyun.com/nexus/content/repositories/jcenter'}
    mavenCentral()
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
    compile('mysql:mysql-connector-java')
    compile('org.springframework.boot:spring-boot-starter-web')
    testImplementation('org.springframework.boot:spring-boot-starter-test') {
        exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
    }
}

test {
    useJUnitPlatform()
}

 

首先看一下application.yml

spring:
  datasource:
    # mysql 8.0+ 需要使用帶cj的驅動
    driverClassName: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/jpa?useUnicode=true&characterEncoding=utf8
    username: root
    password: mysql

  jpa:
    hibernate:
      # 這個就是更新表,如果字段變化就更新,沒有就不更新,create 就是不管什么情況都會刪除原來的表並新建
      ddlAuto: update
    showSql: true
server:
  port: 8090

 

package com.yang.demo.entity;

import javax.persistence.*;
import java.util.Date;

/**
 * User表
 */
@Entity
@Table(name = "user")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)  // 設置自增
    private Long id;

    // 映射字段如果跟數據庫一致可以不用寫
    private String username;

    // name 指定與數據庫中字段的映射關系,unique是否唯一,nullable是否可為空, 可以指定長度,string默認字符串長度是255
    // columnDefinition 指定類型 String映射到數據庫中字段就是varchar
    @Column(name = "u_sex", unique = false, nullable = true, length = 20, columnDefinition = "text")
    private String sex;

    // 時間精確到天,默認格式是datetime,時間精確到秒,也可以修改為時間戳
    @Temporal(TemporalType.DATE)
    private Date createTime;

    // 這個字段就是不與數據庫進行映射
    @Transient
    private String noUse;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public Date getCreateTime() {
        return createTime;
    }

    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }

    public String getNoUse() {
        return noUse;
    }

    public void setNoUse(String noUse) {
        this.noUse = noUse;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", sex='" + sex + '\'' +
                ", createTime=" + createTime +
                ", noUse='" + noUse + '\'' +
                '}';
    }
}

 

接下來,看一下這些實現方法,首先,spring data jpa 已經為我們封裝好sql,我們只需要在dao層繼承接口,就可以進行使用

package com.yang.demo.dao;

import com.yang.demo.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;

public interface UserDao extends JpaRepository<User, Long>, JpaSpecificationExecutor<User> {
}
JpaRepository中,User是實體類,Long是主鍵ID的類型,我們首先看一下JpaRepository的繼承關系圖,接下來看一下這些接口,並測試一下。

 

 

@NoRepositoryBean
public interface JpaRepository<T, ID> extends PagingAndSortingRepository<T, ID>, QueryByExampleExecutor<T> {

    /*
     *  獲取所有
     */
    @Override
    List<T> findAll();

    /*
     * 獲取所有,可以進行排序
     */
    @Override
    List<T> findAll(Sort sort);

    /*
     * 獲取所有傳入ID的對象
     */
    @Override
    List<T> findAllById(Iterable<ID> ids);

    /*
     * 保存所有
     */
    @Override
    <S extends T> List<S> saveAll(Iterable<S> entities);

    /**
     * 刷新
     */
    void flush();

    /**
     * Saves an entity and flushes changes instantly.
     *
     * 當發生改變我們沒有提交,可以幫助刷新*/
    <S extends T> S saveAndFlush(S entity);

    /**
     *
     * @param entities 根據傳入的對象刪除
     */
    void deleteInBatch(Iterable<T> entities);

    /**
     * 刪除數據庫中這個實體對應表的所有數據.
     */
    void deleteAllInBatch();

    /**
     * 根據id查詢出來的對象不為null,但是對象里面的所有屬性全部為null*/
    T getOne(ID id);

    /*
     * 根據條件查詢
     */
    @Override
    <S extends T> List<S> findAll(Example<S> example);

    /*
     * 根據條件以及排序規則進行查詢
     */
    @Override
    <S extends T> List<S> findAll(Example<S> example, Sort sort);
}

接下來進行測試

package com.yang.demo;

import com.yang.demo.dao.UserDao;
import com.yang.demo.entity.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Sort;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@SpringBootTest
class DemoApplicationTests {

    @Autowired
    UserDao userDao;

    @Test
    public void testJpaRepository() {
        // 查找所有
        // Hibernate: select user0_.id as id1_0_, user0_.create_time as create_t2_0_, user0_.u_sex as u_sex3_0_, user0_.username as username4_0_ 
        // from user user0_
        List<User> users = userDao.findAll();
        for (User user : users) {
            System.out.println(user);
            // User{id=7, username='xiao ming', sex='男', createTime=2020-02-29, noUse='null'}
            // User{id=8, username='小紅', sex='女', createTime=2020-02-29, noUse='null'}
        }
        // 獲取所有,根據id降序
        Sort.Order order = new Sort.Order(Sort.Direction.DESC, "id");
        ArrayList<Sort.Order> orders = new ArrayList<>();
        orders.add(order);
        Sort sort = Sort.by(orders);
        // Hibernate: select user0_.id as id1_0_, user0_.create_time as create_t2_0_, user0_.u_sex as u_sex3_0_, user0_.username as username4_0_ 
        // from user user0_ order by user0_.id desc
        List<User> userSorts = userDao.findAll(sort);
        for (User userSort : userSorts) {
            System.out.println(userSort);
            //User{id=8, username='小紅', sex='女', createTime=2020-02-29, noUse='null'}
            //User{id=7, username='xiao ming', sex='男', createTime=2020-02-29, noUse='null'}
        }
        // 根據ID查詢
        List<Long> ids = new ArrayList<>();
        ids.add(1L);
        ids.add(2L);
        // Hibernate: select user0_.id as id1_0_, user0_.create_time as create_t2_0_, user0_.u_sex as u_sex3_0_, user0_.username as username4_0_ 
        // from user user0_ where user0_.id in (? , ?)
        List<User> allById = userDao.findAllById(ids);
        for (User userById : allById) {
            System.out.println(userById);
            // none
        }
        // 保存所有
        User user2 = new User();
        user2.setUsername("xiao ming");
        user2.setCreateTime(new Date());
        user2.setSex("男");
        User user3 = new User();
        user3.setUsername("小紅");
        user3.setCreateTime(new Date());
        user3.setSex("女");
        List<User> userList = new ArrayList<>();
        userList.add(user2);
        userList.add(user3);
        // Hibernate: insert into user (create_time, u_sex, username) values (?, ?, ?)
        // Hibernate: insert into user (create_time, u_sex, username) values (?, ?, ?)
        List<User> users1 = userDao.saveAll(userList);
        for (User user1 : users1) {
            System.out.println(user1);
            //User{id=9, username='xiao ming', sex='男', createTime=Sun Mar 01 10:58:08 CST 2020, noUse='null'}
            //User{id=10, username='小紅', sex='女', createTime=Sun Mar 01 10:58:08 CST 2020, noUse='null'}
        }

        // 根據傳入對象刪除,無返回對象
        // userDao.deleteInBatch(users1);

        // 根據ID查詢,如果查詢不到就會報錯
        // User one = userDao.getOne(10L);
        // System.out.println(one);

        // 查詢,根據對象的示例
        // 設置實例
        User user = new User();
        // 設置查詢條件
        user.setUsername("xiao ming");
        // 定義example
        Example<User> example = Example.of(user);
        // select user0_.id as id1_0_, user0_.create_time as create_t2_0_, user0_.u_sex as u_sex3_0_, user0_.username as username4_0_
        // from user user0_ where user0_.username=?
        List<User> all = userDao.findAll(example);
        for (User user4 : all) {
            System.out.println(user4);
            // User{id=7, username='xiao ming', sex='男', createTime=2020-02-29, noUse='null'}
            // User{id=9, username='xiao ming', sex='男', createTime=2020-02-29, noUse='null'}
        }
    }

}

接下來看一下PagingAndSortingRepository

@NoRepositoryBean
public interface PagingAndSortingRepository<T, ID> extends CrudRepository<T, ID> {

    /**
     * 這個JpaRepository重寫了這個方法,就會根據排序規則查詢所有
     */
    Iterable<T> findAll(Sort sort);

    /**
     * 分頁查詢*/
    Page<T> findAll(Pageable pageable);
}

接下來,我們看一下分頁查詢

 

    @Test
    public void testPagingAndSort() {
        // 這個翻頁需要設定排序規則,注意字段需要與entity的類一致
        Sort.Order order = new Sort.Order(Sort.Direction.DESC, "createTime");
        List<Sort.Order> orders = new ArrayList<>();
        orders.add(order);
        // sort需要傳入的是集合
        Sort sort = Sort.by(orders);

        // 查詢需求
        // 第2頁
        int pageIndex = 2;
        // 每頁大小
        int pageSize = 2;
        Pageable pageable = PageRequest.of(pageIndex - 1, pageSize, sort);
        Page<User> all = userDao.findAll(pageable);
        System.out.println("總記錄: " + all.getTotalElements());  // 4
        System.out.println("總頁數: " + all.getTotalPages());  // 2
        System.out.println("當前第幾頁: : " + all.getNumber());  // 1 從0開始
        System.out.println("當前頁條數: : " + all.getNumberOfElements());  // 2
        for (User user : all) {
            System.out.println(user);
            // User{id=9, username='xiao ming', sex='男', createTime=2020-02-29, noUse='null'}
            // User{id=10, username='小紅', sex='女', createTime=2020-02-29, noUse='null'}
        }

    }

接下來看一下CrudRepository里面的方法

@NoRepositoryBean
public interface CrudRepository<T, ID> extends Repository<T, ID> {

    /**
     * 保存
     */
    <S extends T> S save(S entity);

    /**
     * 保存所有,跟JPARespository中一樣
     */
    <S extends T> Iterable<S> saveAll(Iterable<S> entities);

    /**
     * 根據ID查詢,查不到不會報錯
     */
    Optional<T> findById(ID id);

    /**
     * 根據ID查詢是否存在
     */
    boolean existsById(ID id);

    /**
     * 查詢所有
     */
    Iterable<T> findAll();

    /**
     * 根據ID可迭代對象查詢
     */
    Iterable<T> findAllById(Iterable<ID> ids);

    /**
     * 查詢這個表中一共多少條
     */
    long count();

    /**
     * 根據ID刪除
     */
    void deleteById(ID id);

    /**
     * 根據對象刪除
     */
    void delete(T entity);

    /**
     * 根據傳入的對象刪除
     */
    void deleteAll(Iterable<? extends T> entities);

    /**
     * 刪除整個表數據
     */
    void deleteAll();
}

這些都是一些基礎的方法,比較簡單,來看一下

@Test
    public void testCurdRepository() {
        // 保存
        User user = new User();
        user.setUsername("小明1");
        user.setSex("男");
        user.setCreateTime(new Date());
        // Hibernate: insert into user (create_time, u_sex, username) values (?, ?, ?)
        User user1 = userDao.save(user);
        // User{id=12, username='小明1', sex='男', createTime=Sun Mar 01 12:01:35 CST 2020, noUse='null'}
        System.out.println(user1);
        // 保存所有
        user1.setUsername("小明2");
        User user2 = new User();
        user2.setUsername("小明3");
        user2.setSex("男");
        user2.setCreateTime(new Date());
        List<User> userList = new ArrayList<>();
        userList.add(user1);
        userList.add(user1); // 連續添加兩個user1
        List<User> userList1 = userDao.saveAll(userList);
        // 從輸出結果可以看出,逐條保存,如果有ID就只是更新,不是保存
        for (User user3 : userList1) {
            System.out.println(user3);
            // User{id=12, username='小明2', sex='男', createTime=Sun Mar 01 12:01:35 CST 2020, noUse='null'}
            //User{id=12, username='小明2', sex='男', createTime=Sun Mar 01 12:01:35 CST 2020, noUse='null'}
        }
        // 根據ID查詢
        // Hibernate: select user0_.id as id1_0_0_, user0_.create_time as create_t2_0_0_, user0_.u_sex as u_sex3_0_0_, user0_.username as username4_0_0_
        // from user user0_ where user0_.id=?
        Optional<User> user4 = userDao.findById(100L);
        // Optional.empty
        System.out.println(user4);
        // 根據Id判斷是否存在
        // Hibernate: select count(*) as col_0_0_ from user user0_ where user0_.id=?
        System.out.println(userDao.existsById(100L)); // false
        // 查詢所有
        // Hibernate: select user0_.id as id1_0_, user0_.create_time as create_t2_0_, user0_.u_sex as u_sex3_0_, user0_.username as username4_0_
        // from user user0_
        List<User> users = userDao.findAll();
        for (User user3 : users) {
            System.out.println(user3);
            //User{id=7, username='xiao ming', sex='男', createTime=2020-02-29, noUse='null'}
            //User{id=8, username='小紅', sex='女', createTime=2020-02-29, noUse='null'}
            //User{id=9, username='xiao ming', sex='男', createTime=2020-02-29, noUse='null'}
            //User{id=10, username='小紅', sex='女', createTime=2020-02-29, noUse='null'}
            //User{id=11, username='小明2', sex='男', createTime=2020-02-29, noUse='null'}
            //User{id=12, username='小明2', sex='男', createTime=2020-02-29, noUse='null'}
        }
        // 查詢總數
        // Hibernate: select count(*) as col_0_0_ from user user0_
        System.out.println("總數:" + userDao.count());  // 6
        // 根據傳入的ID刪除
        // 查找id為7的
        Optional<User> user3 = userDao.findById(8L);
        System.out.println(user3);
        // 數據不存在會報錯
        userDao.deleteById(8L);
        System.out.println(userDao.existsById(8L));
        // 根據傳入對象刪除
        // getOne是懶加載,如果直接刪除這個對象會報錯,需要使用,因此使用findById
        // User user5 = userDao.getOne(9L);
        // findById 返回結果是Optional<T>,調用get即刻返回對象
        // Hibernate: select user0_.id as id1_0_0_, user0_.create_time as create_t2_0_0_, user0_.u_sex as u_sex3_0_0_, user0_.username as username4_0_0_ 
        // from user user0_ where user0_.id=?
        User user5 = userDao.findById(9L).get();
        System.out.println(user5);
        // Hibernate: delete from user where id=?
        userDao.delete(user5);
        System.out.println(userDao.existsById(9L));
        // 刪除所有
        // 看一下表中數據
        System.out.println(userDao.count()); // 6
        //Hibernate: delete from user where id=?
        //Hibernate: delete from user where id=?
        //Hibernate: delete from user where id=?
        //Hibernate: delete from user where id=?
        //Hibernate: delete from user where id=?
        //Hibernate: delete from user where id=?
        userDao.deleteAll();
        // 再看一下表中數據
        System.out.println(userDao.count());  // 0
    }

上面是常用的,但是感覺還是缺點什么,於是作者又搞了一個接口QueryByExampleExecutor

public interface QueryByExampleExecutor<T> {

    /**
     * 根據傳入的條件查詢一個
     */
    <S extends T> Optional<S> findOne(Example<S> example);

    /**
     * 根據傳入的條件查詢所有
     */
    <S extends T> Iterable<S> findAll(Example<S> example);

    /**
     * 根據查詢條件以及排序規則查詢所有
     */
    <S extends T> Iterable<S> findAll(Example<S> example, Sort sort);

    /**
     * 根據查詢條件以及分頁規則,查詢
     */
    <S extends T> Page<S> findAll(Example<S> example, Pageable pageable);

    /**
     * 根據查詢條件,進行計數
     */
    <S extends T> long count(Example<S> example);

    /**
     * 根據查詢條件,判斷表中是否存在
     */
    <S extends T> boolean exists(Example<S> example);
}

接下來看一下測試

    @Test
    public void testQueryByExampleExecutor() {
        // 測試數據
        List<User> all = userDao.findAll();
        for (User user : all) {
            System.out.println(user);
            // User{id=18, username='xiao ming', sex='男', createTime=2020-02-29, noUse='null'}
            //User{id=19, username='小紅', sex='女', createTime=2020-02-29, noUse='null'}
            //User{id=20, username='xiao ming', sex='男', createTime=2020-02-29, noUse='null'}
            //User{id=21, username='小寧', sex='男', createTime=2020-02-29, noUse='null'}
            //User{id=22, username='小紅', sex='女', createTime=2020-02-29, noUse='null'}
            //User{id=23, username='小美', sex='女', createTime=2020-02-29, noUse='null'}
            //User{id=24, username='小梅', sex='女', createTime=2020-02-29, noUse='null'}
        }
        // 設置查詢條件
        User user = new User();
        user.setId(18L);
        Example<User> of = Example.of(user);
        // 根據傳入條件查詢一個,如果不是唯一的會報錯
        // Hibernate: select user0_.id as id1_0_, user0_.create_time as create_t2_0_, user0_.u_sex as u_sex3_0_, user0_.username as username4_0_
        // from user user0_ where user0_.id=18
        Optional<User> one = userDao.findOne(of);
        // Optional[User{id=18, username='xiao ming', sex='男', createTime=2020-02-29, noUse='null'}]
        System.out.println(one);
        // 根據傳入條件查詢所有
        // 設置查詢條件
        User user1 = new User();
        user1.setUsername("小紅");
        Example<User> of1 = Example.of(user1);
        // Hibernate: select user0_.id as id1_0_, user0_.create_time as create_t2_0_, user0_.u_sex as u_sex3_0_, user0_.username as username4_0_
        // from user user0_ where user0_.username=?
        List<User> all1 = userDao.findAll(of1);
        for (User user2 : all1) {
            System.out.println(user2);
            // User{id=19, username='小紅', sex='女', createTime=2020-02-29, noUse='null'}
            // User{id=22, username='小紅', sex='女', createTime=2020-02-29, noUse='null'}
        }
        // 根據條件技術
        // Hibernate: select count(user0_.id) as col_0_0_ from user user0_ where user0_.id=18
        System.out.println(userDao.count(of)); //1
        // Hibernate: select count(user0_.id) as col_0_0_ from user user0_ where user0_.username=?
        System.out.println(userDao.count(of1)); //2
        // 根據查詢條件判斷是否存在
        // Hibernate: select user0_.id as id1_0_, user0_.create_time as create_t2_0_, user0_.u_sex as u_sex3_0_, user0_.username as username4_0_ from user user0_ where user0_.id=18
        System.out.println(userDao.exists(of));  // true
        // Hibernate: select user0_.id as id1_0_, user0_.create_time as create_t2_0_, user0_.u_sex as u_sex3_0_, user0_.username as username4_0_ from user user0_ where user0_.username=?
        System.out.println(userDao.exists(of1));  // true

        // 查詢需求
        // 第2頁
        int pageIndex = 1;
        // 每頁大小
        int pageSize = 1;
        // 排序
        Sort.Order order = new Sort.Order(Sort.Direction.DESC, "id");
        ArrayList<Sort.Order> orders = new ArrayList<>();
        orders.add(order);
        Sort sort = Sort.by(orders);
        Pageable pageable = PageRequest.of(pageIndex - 1, pageSize, sort);
        // 根據查詢條件以及分頁規則查詢
        // Hibernate: select user0_.id as id1_0_, user0_.create_time as create_t2_0_, user0_.u_sex as u_sex3_0_, user0_.username as username4_0_ 
        // from user user0_ where user0_.username=? order by user0_.id desc limit ?
        Page<User> all2 = userDao.findAll(of1, pageable);
        System.out.println("總記錄: " + all2.getTotalElements());  // 2
        System.out.println("總頁數: " + all2.getTotalPages());  // 2
        System.out.println("當前第幾頁: : " + all2.getNumber());  // 0 從0開始
        System.out.println("當前頁條數: : " + all2.getNumberOfElements());  // 1
        for (User user2 : all2) {
            System.out.println(user2);
            // User{id=22, username='小紅', sex='女', createTime=2020-02-29, noUse='null'}
        }
    }

這個就是大體算法,我們還可以使用自定義sql,注解方式,只要保持jpa規范就好,至於一對一,一對多,多對多就是@anyToMany之類的,一般都不使用,因為有外鍵不舒服,一般做邏輯一致。

另外對於對於多表操作,一定需要開啟事務。

 


免責聲明!

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



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