In the previous Spring JavaConfig article, JPA was used to configure data sources. Here are some common approaches to Spring Data JPA.

Introduction to Spring Data JPA

What is the JPA

JPA(Java Persistence API) is an official Java Persistence specification proposed by Sun. It provides Java developers with an object/association mapping tool to manage relational data in Java applications.

Spring Data JPA is a set of JPA application framework encapsulated by Spring based on ORM framework and JPA specification, which enables developers to access and operate Data with minimal code. It provides common functions including add, delete, change, check, etc., and easy to expand! Learning and using Spring Data JPA can greatly improve your development efficiency!

Spring Data JPA frees us from the DAO layer, and basically all CRUDS can rely on it for implementation

A simple query

Basic queries are also divided into two types, one is that Spring Data is implemented by default, and the other is automatically parsed into SQL according to the method of query.

Spring Data JPA pre-generates some basic CURD methods by default, such as add, delete, modify, and so on

public interface ItemRepository extends JpaRepository<Item.Integer>, JpaSpecificationExecutor<Item> {
// Empty, can not write anything
}Copy the code
@Test
public void test1(a) throws Exception {
    Item item = new Item();
    itemRepository.save(item);
    List<Item> itemList = itemRepository.findAll();
    Item one = itemRepository.findOne(1);
    itemRepository.delete(item);
    long count = itemRepository.count();
}Copy the code

Customize simple queries

Item findByItemName(String itemName);

List<Item> findByItemNameLike(String itemName);

Long deleteByItemId(Integer id);

List<Item> findByItemNameLikeOrderByItemNameDesc(String itemName);Copy the code

Specific keywords, use methods and production into SQL as shown in the following table

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.a ge ⇐? 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)

Paging query

Page<Item> findALL(Pageable pageable);Copy the code
@Test
public void test1(a) throws Exception {
    int page=1,size=10;
    Sort sort = new Sort(Sort.Direction.DESC, "id");// Sort by descending id
    Pageable pageable = new PageRequest(page, size, sort);
    Page<Item> pageResult = itemRepository.findALL(pageable);
    List<Item> itemList = pageResult.getContent();
}Copy the code

Customize SQL queries

Use @Query annotations on SQL Query methods, including @modifying where necessary when deleting and Modifying SQL Query methods. You can also add @Transactional support for things as needed

// Query data in one page
@Query(value = "select i from Item i",
        countQuery = "select count(i.itemId) from Item i")
Page<Item> findall(Pageable pageable);

//nativeQuery = true Native queries use native SQL queries
@Query(value = "select * from item  where item_id = ?1", nativeQuery = true)
Item findAllItemById(int id);

@Transactional
@Modifying
@Query("delete from Item i where i.itemId = :itemId")
void deleteInBulkByItemId(@Param(value = "itemId") Integer itemId);

//#{#entityName} is the specified @Entity
 @Query("select i from #{#entityName} i where i.itemId = ? 1")
 Item findById(Integer id);Copy the code

Named queries

Use @Namequeries annotations on entity classes

Define a method of the same name in the Repository interface of your implementation DAO

Spring then looks for a NamedQuery with the same name, and if so, does not parse it as defined by the interface.

// Name the query
@NamedQueries({
        @NamedQuery(name = "Item.findItemByitemPrice",
                query = "select i from Item i where i.itemPrice between ? 1 and ? 2. ""),
        @NamedQuery(name = "Item.findItemByitemStock",
                query = "select i from Item i where i.itemStock between ? 1 and ? 2. ""})),@Entity
@Data
public class Item implements Serializable {
    @Id
    @GeneratedValue
    @Column(name = "item_id")
    private int itemId;
    private String itemName;
    private Integer itemPrice;
    private Integer itemStock;
 }Copy the code
/** * this is in the domain entity class@NamedQueryWrite the corresponding HQL *@NamedQuery(name = "Item.findItemByitemPrice", baseQuery = "select i from Item i where i.itemPrice between ? 1 and ? * 2 ")@param price1
 * @param price2
 * @return* /
List<Item> findItemByitemPrice(Integer price1, Integer price2);
List<Item> findItemByitemStock(Integer stock1, Integer stock2);Copy the code

So how does spring Data JPA assemble queries from these specifications?

When parsing method names, the Spring Data JPA framework intercepts redundant prefixes such as find, findBy, read, readBy, get, and getBy, and then parses the rest.

Suppose you create the following query:findByUserDepUuid()When parsing the method, the framework first removes findBy and then parses the remaining attributes
  1. Determine whether userDepUuid (lowercase according to the POJO specification) is an attribute of the query entity, and if so, it indicates that the query is based on that attribute. If not, proceed to step 2;
  2. Cut the first uppercase string from right to left, here Uuid) and check whether the remaining string is an attribute of the query entity. If so, the query is based on that attribute; If not, repeat the second step and continue to intercept from right to left. Finally, assume that user is an attribute of the query entity.
  3. The rest (DepUuid) is then processed to determine whether the type to which the user corresponds has the DepUuid attribute, and if so, the method is ultimately based on DepUuidDoc.user.depUuidTo query the value of; Otherwise, the value is cut from right to left according to the rule in Step 2Doc.user.dep.uuidTo query the value of.
  4. There may be a special case where Doc contains a user attribute as well as a userDep attribute, where there is confusion. You can explicitly add “_” between attributes to express intent, for examplefindByUser_DepUuid()orfindByUserDep_uuid()

The use of text links: Spring Data JPA | fire yao