Spring Data JPA應用總結

Spring boot data jpa 1.11.8版本前端

(一)DAO層實現方法最好繼承JpaRepository接口,緣由有下(忽略源碼):java

1. 繼承關係:JpaRepository-->PagingAndSortRepository-->CrudRepository;git

2. CrudRepository 返回Iteralble,JpaRepository返回的是 List,使用起來更方便;github

3. JpaRepository增長了 InBatch 刪除方法, 實際執行時,後臺生成一條sql語句,效率更高,而CrudRepository 接口】是逐條刪除,更好笑的是 deleteAll 也是逐條刪除;spring

4. JpaReporsitory增長了 getOne() 方法,該方法返回的是對象引用,當查詢的對象不存在時,它的值不是Null。sql

5. 當數據進行後臺分頁時,JpaRepository表現的更加優秀:數據庫

自定義分佈類:數組

public class _Page<T> implements Serializable{

    public static final Integer PAGE_SIZE = Integer.MAX_VALUE;
    public static final int DIR_ASC = 0;
    public static final int DIR_DESC = 1;
    public static final String DEFAULT_ORDER = "createTime";       //全部類默認按照建立時間排序

    public _Page(Integer currentPage, Integer pageSize){
        init(pageSize,DIR_DESC,DEFAULT_ORDER);
        this.currentPage = currentPage;
        //從0開始第一頁
        this.request = new PageRequest(this.currentPage-1, this.limit, this.dir==DIR_DESC?Sort.Direction.DESC:Sort.Direction.ASC,this.order);
    }

    public _Page(Integer currentPage, Integer limit, Integer dir, String order){
        init(limit,dir,order);
        this.currentPage = currentPage;
        this.request = new PageRequest(this.currentPage-1, this.limit, this.dir==DIR_DESC?Sort.Direction.DESC:Sort.Direction.ASC,this.order);
    }

    private Integer currentPage;
    private Long totalCount;
    private List<T> results;
    private int limit;
    private int dir;
    private String order;   //暫時只按照一列排序,因此不用數組
    @JsonIgnore
    private PageRequest request;

    public Integer getCurrentPage() {
        return currentPage;
    }

    public void setCurrentPage(Integer currentPage) {
        this.currentPage = currentPage;
    }

    public Long getTotalCount() {
        return totalCount;
    }

    public void setTotalCount(Long totalCount) {
        this.totalCount = totalCount;
    }

    public List<T> getResults() {
        return results;
    }

    public void setResults(List<T> results) {
        this.results = results;
    }

    public int getLimit() {
        return limit;
    }

    public void setLimit(int limit) {
        this.limit = limit;
    }

    public int getDir() {
        return dir;
    }

    public void setDir(int dir) {
        this.dir = dir;
    }

    public String getOrder() {
        return order;
    }

    public void setOrder(String order) {
        this.order = order;
    }

    public PageRequest getRequest() {
        return request;
    }

    public void setRequest(PageRequest request) {
        this.request = request;
    }

    private void init(Integer limit,Integer dir,String order){
        this.limit = limit == null? PAGE_SIZE:limit;
        this.dir = dir == null?DIR_ASC:dir;
        if(order==null)this.order = DEFAULT_ORDER;
        else{
            try {
                this.getClass().getField(order);
                this.order = order;
            } catch (NoSuchFieldException e) {
                this.order = DEFAULT_ORDER;
            }
        }
    }
}

根據前端傳入分頁參數進行分頁:app

import org.springframework.data.domain.Example;
import org.springframework.data.domain.ExampleMatcher;
import org.springframework.data.domain.Page;

/**
     * 把查詢條件封閉成一個對象,根據對象屬性內容進行匹配查詢
     *
     * @return
     */
    private ExampleMatcher getMatcher() {
        return ExampleMatcher.matching().withStringMatcher(ExampleMatcher.StringMatcher.CONTAINING).withIgnoreNullValues();
    }

public _Page<Center> pageCenter(int currentPage, Integer limit, String name, Boolean enabled) {
        _Page<Center> _page = new _Page<>(currentPage, limit);
        Center center = new Center(name, enabled);
        Example<Center> example = Example.of(center, getMatcher());
        Page<Center> page = centerDao.findAll(example, _page.getRequest());
        _page.setResults(page.getContent());
        _page.setTotalCount(page.getTotalElements());
        return _page;
    }

6. 前端傳入一個JSON對象出現反序列化問題:dom

Caused by: com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of java.lang.Long out of START_OBJECT token

標記實體主鍵便可:

@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
@Entity

7. 動態查詢最佳實踐的項目可參照:https://github.com/wenhao/jpa-spec,前面武功盡廢:DAO須要繼承兩個接口便可:

public interface FarmDao extends JpaRepository<Farm,Long>,JpaSpecificationExecutor<Farm>{
    List<Farm> findByAccountAndEnabled(Long account, Boolean enabled);

    @Transactional
    @Modifying
    @Query(value="UPDATE Farm a SET a.enabled=?2 WHERE a.id=?1")
    Integer enabled(Long id, Boolean enabled);
}

8. 建立數據庫出現外鍵約束錯誤:

Caused by: org.hibernate.tool.schema.spi.SchemaManagementException: Unable to execute schema management to JDBC target [alter table jut_feeding_feed add constraint FK_FEEDING_FEEDING_FEED_ID foreign key (feeding_id) references jut_feeding (id)]
	at org.hibernate.tool.schema.internal.TargetDatabaseImpl.accept(TargetDatabaseImpl.java:59) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
	at org.hibernate.tool.schema.internal.SchemaMigratorImpl.applySqlString(SchemaMigratorImpl.java:431) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
	at org.hibernate.tool.schema.internal.SchemaMigratorImpl.applySqlStrings(SchemaMigratorImpl.java:420) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
	at org.hibernate.tool.schema.internal.SchemaMigratorImpl.applyForeignKeys(SchemaMigratorImpl.java:386) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
	at org.hibernate.tool.schema.internal.SchemaMigratorImpl.doMigrationToTargets(SchemaMigratorImpl.java:214) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
	at org.hibernate.tool.schema.internal.SchemaMigratorImpl.doMigration(SchemaMigratorImpl.java:60) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
	at org.hibernate.tool.hbm2ddl.SchemaUpdate.execute(SchemaUpdate.java:134) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
	at org.hibernate.tool.hbm2ddl.SchemaUpdate.execute(SchemaUpdate.java:101) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
	at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:472) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
	at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:444) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
	at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:879) ~[hibernate-entitymanager-5.0.12.Final.jar:5.0.12.Final]

查詢FK_FEEDING_FEEDING_FEED_ID,發現有重複的外鍵名稱。

相關文章
相關標籤/搜索