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,发现有重复的外键名称。