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
- 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;
- 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.
- 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 DepUuid
Doc.user.depUuid
To query the value of; Otherwise, the value is cut from right to left according to the rule in Step 2Doc.user.dep.uuid
To query the value of. - 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 example
findByUser_DepUuid()
orfindByUserDep_uuid()
The use of text links: Spring Data JPA | fire yao