Spring Boot - Jpa use (rpm)

First, understand what Jpa that?

Jpa (Java Persistence API) is a Java Sun Crown persistence specification. It provides an object for Java developers / association mapping tools to manage relational data in Java applications. It appears mainly to simplify the existing persistence ORM technology development and integration, the end of the current Hibernate, TopLink, JDO and other ORM framework for their own business situation.

Notably, JPA is fully absorbed in the existing Hibernate, based TopLink, JDO and other ORM framework developed from, an easy to use, stretchable and strong advantages. From the reaction of the current development community point of view, Jpa been a great support and praise, including the Spring and EJB3. 0 of the development team.

Note: Jpa is a norm, not a product, like Hibernate, TopLink, JDO they are a product, if these products to achieve this Jpa specification, then we can call them Jpa of their products.

Spring Boot Jpa

Spring ORM based on the Boot Jpa the Spring Framework, the package on the basis of a specification Jpa Jpa application framework, developers can use to achieve the minimalist code to access and manipulate data. It offers including CRUD etc., commonly used functions, and easy to expand! Learning and using Spring Data Jpa can greatly improve development efficiency!

Spring Boot Jpa let us relief operations DAO layer, basically all CRUD can rely on it to achieve

Basic query

The basic queries can also be divided into two types, one is the Spring Data default has been achieved, one is automatically parsed into SQL queries based on the method.

The method of pre-generated

Spring Boot Jpa previously generated default CURD some basic methods, for example: add, delete, change, etc.

1 inherited JpaRepository

public interface UserRepository extends JpaRepository<User, Long> {
}

2 Use the default method

@Test
public void testBaseQuery() throws Exception {
    User user=new User();
    userRepository.findAll();
    userRepository.findOne(1l);
    userRepository.save(user);
    userRepository.delete(user);
    userRepository.count();
    userRepository.exists(1l);
    // ...
}

The method will not explain the meaning of the name will be seen

Custom simple query

From simple query definition is automatically generated according to the method name SQL, the syntax is the main findXXBy, readAXXBy, queryXXBy, countXXBygetXXByfollowed by property name:

User findByUserName(String userName);

Also use some add some keywords And Or

User findByUserNameOrEmail(String username, String email);

Modify, delete, statistics also similar syntax

Long deleteById(Long id);
Long countByUserName(String userName)

Basically the system SQL keywords can be used, for  LIKE example:  IgnoreCaseOrderBy, .

List<User> findByEmailLike(String email);
User findByUserNameIgnoreCase(String userName);
List<User> findByUserNameOrderByEmailDesc(String email);

Specific keywords, and using production methods into SQL table below

Keyword Sample JPQL snippet
And findByLastnameAndFirstname … where x.lastname = ?1 and x.firstname = ?2
Or findByLastnameOrFirstname … where x.lastname = ?1 or x.firstname = ?2
Is,Equals findByFirstnameIs,findByFirstnameEquals … where x.firstname = ?1
Between findByStartDateBetween … where x.startDate between ?1 and ?2
LessThan findByAgeLessThan … where x.age < ?1
LessThanEqual findByAgeLessThanEqual … where x.age ⇐ ?1
GreaterThan findByAgeGreaterThan … where x.age > ?1
GreaterThanEqual findByAgeGreaterThanEqual … where x.age >= ?1
After findByStartDateAfter … where x.startDate > ?1
Before findByStartDateBefore … where x.startDate < ?1
IsNull findByAgeIsNull … where x.age is null
IsNotNull, NotNull findByAge(Is)NotNull … where x.age not null
Like findByFirstnameLike … where x.firstname like ?1
NotLike findByFirstnameNotLike … where x.firstname not like ?1
StartingWith findByFirstnameStartingWith … where x.firstname like ?1 (parameter bound with appended %)
EndingWith findByFirstnameEndingWith … where x.firstname like ?1 (parameter bound with prepended %)
Containing findByFirstnameContaining … where x.firstname like ?1 (parameter bound wrapped in %)
OrderBy findByAgeOrderByLastnameDesc … where x.age = ?1 order by x.lastname desc
Not findByLastnameNot … where x.lastname <> ?1
In findByAgeIn(Collection ages) … where x.age in ?1
NotIn findByAgeNotIn(Collection age) … where x.age not in ?1
TRUE findByActiveTrue() … where x.active = true
FALSE findByActiveFalse() … where x.active = false
IgnoreCase findByFirstnameIgnoreCase … where UPPER(x.firstame) = UPPER(?1)

Complex queries

In the actual development, we need to use tabs, delete selection, even when the query tables, etc. need special methods or custom SQL

Paging query

Paging query in the actual use is very common, Spring Boot Jpa has helped us achieve paging function, in a query method, the need to pass parameters Pageable , when there are multiple query parameters Pageableis recommended as the last parameter passed .

Page<User> findALL(Pageable pageable);
Page<User> findByUserName(String userName,Pageable pageable);

Pageable Spring is a page implementation class package, when in use need to pass the number of pages, and each page article number collation

@Test
public void testPageQuery() throws Exception {
    int page=1,size=10;
    Sort sort = new Sort(Direction.DESC, "id");
    Pageable pageable = new PageRequest(page, size, sort);
    userRepository.findALL(pageable);
    userRepository.findByUserName("testName", pageable);
}

限制查询

有时候我们只需要查询前N个元素,或者支取前一个实体。

User findFirstByOrderByLastnameAsc();
User findTopByOrderByAgeDesc();
Page<User> queryFirst10ByLastname(String lastname, Pageable pageable);
List<User> findFirst10ByLastname(String lastname, Sort sort);
List<User> findTop10ByLastname(String lastname, Pageable pageable);

自定义SQL查询

其实 Spring Data 觉大部分的 SQL 都可以根据方法名定义的方式来实现,但是由于某些原因我们想使用自定义的 SQL 来查询,Spring Data 也是完美支持的;在 SQL 的查询方法上面使用@Query注解,如涉及到删除和修改在需要加上@Modifying.也可以根据需要添加 @Transactional对事物的支持,查询超时的设置等。

@Modifying
@Query("update User u set u.userName = ?1 where u.id = ?2")
int modifyByIdAndUserId(String  userName, Long id);
    
@Transactional
@Modifying
@Query("delete from User where id = ?1")
void deleteByUserId(Long id);
  
@Transactional(timeout = 10)
@Query("select u from User u where u.emailAddress = ?1")
User findByEmailAddress(String emailAddress);

多表查询

多表查询 Spring Boot Jpa 中有两种实现方式,第一种是利用 Hibernate 的级联查询来实现,第二种是创建一个结果集的接口来接收连表查询后的结果,这里主要第二种方式。

首先需要定义一个结果集的接口类。

public interface HotelSummary {

    City getCity();

    String getName();

    Double getAverageRating();

    default Integer getAverageRatingRounded() {
        return getAverageRating() == null ? null : (int) Math.round(getAverageRating());
    }

}

查询的方法返回类型设置为新创建的接口

@Query("select h.city as city, h.name as name, avg(r.rating) as averageRating from Hotel h left outer join h.reviews r where h.city = ?1 group by h")
Page<HotelSummary> findByCity(City city, Pageable pageable);

@Query("select h.name as name, avg(r.rating) as averageRating from Hotel h left outer join h.reviews r  group by h")
Page<HotelSummary> findByCity(Pageable pageable);

使用

Page<HotelSummary> hotels = this.hotelRepository.findByCity(new PageRequest(0, 10, Direction.ASC, "name"));
for(HotelSummary summay:hotels){
        System.out.println("Name" +summay.getName());
}

在运行中 Spring 会给接口(HotelSummary)自动生产一个代理类来接收返回的结果,代码汇总使用 getXX的形式来获取

多数据源的支持

同源数据库的多源支持

日常项目中因为使用的分布式开发模式,不同的服务有不同的数据源,常常需要在一个项目中使用多个数据源,因此需要配置 Spring Boot Jpa 对多数据源的使用,一般分一下为三步:

  • 1 配置多数据源
  • 2 不同源的实体类放入不同包路径
  • 3 声明不同的包路径下使用不同的数据源、事务支持

异构数据库多源支持

比如我们的项目中,即需要对 mysql 的支持,也需要对 Mongodb 的查询等。

实体类声明@Entity 关系型数据库支持类型、声明@Document 为 Mongodb 支持类型,不同的数据源使用不同的实体就可以了

interface PersonRepository extends Repository<Person, Long> {
 …
}

@Entity
public class Person {
  …
}

interface UserRepository extends Repository<User, Long> {
 …
}

@Document
public class User {
  …
}

但是,如果 User 用户既使用 Mysql 也使用 Mongodb 呢,也可以做混合使用

interface JpaPersonRepository extends Repository<Person, Long> {
 …
}

interface MongoDBPersonRepository extends Repository<Person, Long> {
 …
}

@Entity
@Document
public class Person {
  …
}

也可以通过对不同的包路径进行声明,比如 A 包路径下使用 mysql,B 包路径下使用 MongoDB

@EnableJpaRepositories(basePackages = "com.neo.repositories.jpa")
@EnableMongoRepositories(basePackages = "com.neo.repositories.mongo")
interface Configuration { }

其它

使用枚举

使用枚举的时候,我们希望数据库中存储的是枚举对应的 String 类型,而不是枚举的索引值,需要在属性上面添加 @Enumerated(EnumType.STRING) 注解

@Enumerated(EnumType.STRING) 
@Column(nullable = true)
private UserType type;

不需要和数据库映射的属性

正常情况下我们在实体类上加入注解@Entity,就会让实体类和表相关连如果其中某个属性我们不需要和数据库来关联只是在展示的时候做计算,只需要加上@Transient属性既可。

@Transient
private String  userName;

 

 

转自:http://www.ityouknow.com/springboot/2016/08/20/spring-boot-jpa.html

Guess you like

Origin www.cnblogs.com/helios-fz/p/11200912.html