乐趣区

关于springboot:SpringBoot基础之Spring-Data-Jpa

明天讲一下 Spring Data Jpa 的根底写法,实际上很 easy,很多语句都能够用 DSL 来替换,很有意思。

在 Springboot 启动类加上 @EnableJpaRepositories 能够间接容许应用 Spring Data Jpa
上面这个是常见的 Jpa 的 Repository 的写法

public interface LocationJpaRepository extends JpaRepository<Location, Long> {}

Entity 配置,@Id 示意主键,@GeneratedValue(strategy = GenerationType.AUTO) 示意自增长,@Column 示意字段名称
@OneToMany 示意一对多的关系

@Entity
@Table(name = "APPLICATION")
public class Application {public Application() { }
    public Application(String name, String description, String owner) {
        this.name = name;
        this.description = description;
        this.owner = owner;
    }
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "application_id")
    private Integer id;
    @Column(name = "app_name", nullable = false)
    private String name;
    @Column(length = 2000)
    private String description;
    private String owner;
    @Override
    public String toString() {
        return "Application{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", description='" + description + '\'' +
                ", owner='" + owner + '\'' +
                '}';
    }
}

@OneToMany 须要有 @ManyToOne 对应,其中会有 ManyToOne 的表 Exercise 中减少外键索引,application_application_id,另外 FetchType.LAZY 示意只有在通过 getExercises 时才去表中查问,如果是 FetchType.EAGER 示意获取到 application 时就要同时去表中查问 exercises

public class Application {@OneToMany(mappedBy = "goal", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    private List<Exercise> exercises = new ArrayList<Exercise>();}
public class Exercise {
    @ManyToOne
    private Application application;
}

增删改查操作 CRUD

location loc;
Long id;
//save
locationJpaRepository.saveAndFlush(loc);// 或者 save
//update
locationJpaRepository.saveAndFlush(loc);// 或者 save
//delete
locationJpaRepository.delete(loc);
//find
locationJpaRepository.findOne(id);

DSL,其中 State 必须与 Location 中的字段完全一致即可间接应用含糊查询方法

List<Location> findByStateLike(String stateName);
// 执行时须要减少 like 须要的 %
locationJpaRepository.findByStateLike("dfdf%");

DSL 中有很多关键字

1. findBy 示意通过 By 前面的字段来查问
2. And 与 SQL 中的 and 意义雷同,findByStateAndCity(String value1, String value2),等同 SQL 语句为:where a.state = ? and a.city = ?
3. Or 与 SQL 中的 or 意义雷同,findByStateOrCity(String value1, String value2),等同 SQL 语句为:where a.state = ? or a.city = ?
4. Equals 和不带任何参数的意义雷同,findByStateEquals(String value),等同 SQL 语句为:where a.state = ?
5. Is 和 equals 意义雷同,findByStateIs(String value),等同 SQL 语句为:where a.state = ?
6. Not 与 SQL 中的 <> 意义雷同,findByStateIs(String value),等同 SQL 语句为:where a.state <> ?
7. Like 与 SQL 中的 like 意义雷同,findByStateLike("New%"),等同 SQL 语句为:where a.state like ?
8. NotLike 与 SQL 中的 not like 意义雷同,findByStateNotLike("New%"),等同 SQL 语句为:where a.state not like ?
9. StartingWith 与 SQL 中的 like 意义雷同,findByStateStartingWith("New"),等同 SQL 语句为:where a.state not like '%?'
10. EndingWith 与 SQL 中的 like 意义雷同,findByStateEndingWith("New"),等同 SQL 语句为:where a.state not like '?%'
11. Containing 与 SQL 中的 like 意义雷同,findByStateContaining("New"),等同 SQL 语句为:where a.state not like '%?%'
12. LessThan 与 SQL 中的 < 意义雷同,findByPriceLessThan(BigDemical big),等同 SQL 语句为:where a.price < ?
13. LessThanEqual 与 SQL 中的 <= 意义雷同,findByPriceLessThanEqual(BigDemical big),等同 SQL 语句为:where a.price <= ?
14. GreaterThan 与 SQL 中的 > 意义雷同,findByPriceGreaterThan(BigDemical big),等同 SQL 语句为:where a.price > ?
15. GreaterThanEqual 与 SQL 中的 >= 意义雷同,findByPriceGreaterThanEqual(BigDemical big),等同 SQL 语句为:where a.price >= ?
16. Before 与 SQL 中比拟日期的 < 意义雷同,findByFoundedDateBefore(Date date),等同 SQL 语句为:where a.date < ?
17. After 与 SQL 中比拟日期的 > 意义雷同,findByFoundedDateAfter(Date date),等同 SQL 语句为:where a.date > ?
18. Between 与 SQL 中比拟日期的 between and 意义雷同,findByFoundedDateBetween(Date date1,Date date2),
等同 SQL 语句为:where a.date between ? and ?
19. True 与 SQL 中比拟 Boolean 的 =true 意义雷同,findByActiveTrue(),等同 SQL 语句为:where a.active = true
20. False 与 SQL 中比拟 Boolean 的 =false 意义雷同,findByActiveFalse(),等同 SQL 语句为:where a.active = false
21. IsNull 与 SQL 中比拟的 is null 意义雷同,findByActiveIsNull(),等同 SQL 语句为:where a.active is null
22. IsNotNull 与 SQL 中比拟的 is not null 意义雷同,findByActiveIsNotNull(),等同 SQL 语句为:where a.active is not null
23. NotNull 与 SQL 中比拟的 is not null 意义雷同,findByActiveNotNull(),等同 SQL 语句为:where a.active is not null
24. In 与 SQL 中比拟的 in 意义雷同,findByStateIn(Collection<String> states),等同 SQL 语句为:where a.state in ?
25. NotIn 与 SQL 中比拟的 not in 意义雷同,findByStateNotIn(Collection<String> states),等同 SQL 语句为:where a.state not in ?
其中有一个非凡的状况,Model 类其中组合了 ModelType 类,因而能够通过 ModelType 来获取 Model,List<Model> models = findByModelTypeNameIn(List<String> modelTypeName)
26. IgnoreCase,findByStateIgnoreCase(String state),等同 SQL 语句为:where UPPER(a.state) = UPPER(?)
27. StartingWithIgnoreCase,findByStateStartingWithIgnoreCase(String state),等同 SQL 语句为:where UPPER(a.state) like UPPER('?%')
28. OrderByCountryAsc,findByStateOrderByCountryAsc(String state) , 等同于 SQl 语句为:whrere a.state = ? order by a.country asc
29. OrderByCountryDesc,findByStateOrderByCountryDesc(String state), 等同于 SQl 语句为:whrere a.state = ? order by a.country desc
30. First,findFirstByState(String state), 等同于 SQl 语句为:whrere a.state = ? limit 1
31. Top5,findTop5ByState(String state), 等同于 SQl 语句为:whrere a.state = ? limit 5
32. Distinct,findDistinctManufacturerByState(String state), 等同于 SQl 语句为:select discint manufacturer *** whrere a.state = ?

不实用 DQL 能够通过 @Query 注解自定义 JPQL 语句,@Param 指定参数对应 JPQL 中的:后边的参数

@Query("select m from Model m where m.price >= :lowest and m.price <= :highest and m.woodType like :wood")
List<Model> queryByPriceRangeAndWoodType(@Param("lowest")BigDecimal lowest,
                                         @Param("highest")BigDecimal high,
                                         @Param("wood")String wood);

通过 Entity 的 NamedQuery 办法定义的 JPQL 语句能够在 ModelJpaRepository 中间接实现,须要传入制订的参数

@Entity
@NamedQuery(name="Model.findAllModelsByType", query="select m from Model m where m.modelType.name = :name")
public class Model {
}
@Repository
public interface ModelJpaRepository extends JpaRepository<Model,Long> {public List<Model> findAllModelsByType(@Param("name") String name);
}

通过 Entity 的 NamedNativeQuery 办法定义的原生 SQL 语句能够在 ModelJpaRepository 中间接实现,须要传入制订的参数

@Entity
@NamedNativeQuery(name = "Manufacturer.getAllThatSellAcoustics", 
      query = "SELECT m.id, m.name, m.foundedDate, m.averageYearlySales, m.location_id as headquarters_id"
       + "FROM Manufacturer m"
      + "LEFT JOIN Model mod ON (m.id = mod.manufacturer_id)"
      + "LEFT JOIN ModelType mt ON (mt.id = mod.modeltype_id)"
       + "WHERE (mt.name = ?)", resultClass = Manufacturer.class)
public class Manufacturer {
}
@Repository
public interface ManufacturerJpaRepository extends JpaRepository<Manufacturer,Long> {List<Manufacturer> getAllThatSellAcoustics(String name);
}

所有带 @Query 的都是须要原生 SQL 解决的,而默认不带 @Query 的都是 DSL 规范的办法,如果应用原生 SQL,须要减少 nativeQuery = true
分页办法,须要在 Repository 的办法中减少 Pageable 办法

@Repository
public interface ModelJpaRepository extends JpaRepository<Model, Long> {@Query("select m from Model m where m.price >= :lowest and m.price <= :highest and m.woodType like :wood")
    Page<Model> queryByPriceRangeAndWoodType(@Param("lowest")BigDecimal lowest,
                                             @Param("highest")BigDecimal high,
                                             @Param("wood")String wood,
                                             Pageable page);
}
//service 办法,Sort 为排序形式,创立 PageRequest,第一个为页数,第二个每页展现个数,第三个是排序形式
public Page<Model> queryByPriceRangeAndWoodType(BigDecimal lowest,BigDecimal highest, String wood){Sort sort = new Sort(Sort.Direction.ASC, "name");
   Pageable page = new PageRequest(0,2, sort);
   return locationJpaRepository.queryByPriceRangeAndWoodType(lowest, highest, wood,page);
}

锁,有几种状况的锁,乐观乐观等

@Repository
public interface ModelJpaRepository extends JpaRepository<Model,Long> {@Lock(LockModeType.PESSIMISTIC_WRITE)
    public List<Model> findAllModelsByType(@Param("name") String name);
}
退出移动版