Spring Data JPA를 잠시 동안 사용하고 있습니다. 이 기간 동안 나는 몇 가지를 배웠고 몇 가지 문제에 직면했습니다. 여기서 당신과 공유하겠습니다.
머리말:
스프링 데이터 소개 :
Spring Data는 데이터베이스 액세스를 단순화하고 클라우드 서비스를 지원하기위한 오픈 소스 프레임 워크입니다. 주요 목표는 데이터에 편리하고 빠르게 액세스하고 Map-Reduce 프레임 워크 및 클라우드 컴퓨팅 데이터 서비스를 지원하는 것입니다. 스프링 데이터에는 여러 하위 프로젝트가 포함됩니다.
Commons- 각 하위 프로젝트에 사용하기에 적합한 공유 기본 프레임 워크를 제공하고 교차 - 다이저 지속성을 지원합니다.
JPA- 스토리지 전체에서 JPA 데이터 액세스 계층 및 지속권 계층을 만드는 기능을 단순화합니다.
Hadoop -Spring의 Hadoop 작업 구성 및 Pojo 프로그래밍 모델 기반 Mapreduce 작업
Key -Value- Redis 및 Riak을 통합하여 여러 공통 시나리오에서 간단한 포장을 제공합니다.
문서 - 문서 데이터베이스 통합 : CouchDB 및 MongoDB 및 기본 구성 매핑 및 라이브러리 지원 제공
그래프 - 강력한 포조 기반 프로그래밍 모델을 제공하기위한 통합 NEO4J
그래프 루어 애드온 - NEO4J에 대한 루 지원
JDBC 확장 - Oracle Rad, 고급 큐 및 고급 데이터 유형 지원
매핑 - 다른 데이터베이스를 지원하는 성배를 기반으로 객체 매핑 프레임 워크 제공
예제 - 샘플 프로그램, 문서 및 그래프 데이터베이스
지침 - 고급 문서
1. 스프링 데이터 JPA 소개
Spring Data JPA는 ORM 프레임 워크 및 JPA 사양을 기반으로 Spring으로 캡슐화 된 JPA 응용 프로그램 프레임 워크이며 전체 데이터 액세스 계층 솔루션 세트를 제공합니다.
2. 스프링 데이터 JPA 기능
스프링 데이터 JPA는 매우 강력한 기능을 가지고 있습니다. 여기서 우리는 환경 구성 단계를 건너 뛰고 스프링 데이터 JPA의 "단맛"을 살펴 봅니다.
Spring Data JPA는 사용자에게 다음 인터페이스를 제공합니다.
3. 스프링 데이터 JPA 인터페이스
1. Crudrepository 인터페이스
엔티티 클래스 생성 :
@entity @table (name = "user") 공개 클래스 사용자 {@id @generatedValue 개인 정수 ID; // 계정 개인 문자열 계정; // 이름 개인 문자열 이름; // 비밀번호 개인 문자열 비밀번호; // 이메일 개인 문자열 이메일; } 인터페이스를 작성하고 crudrepository 인터페이스를 상속합니다.
공개 인터페이스 userrepository 확장 crudrepository <User, Integer> {} 테스트 클래스를 작성합니다 (보다 직관적으로 효과를 확인하려면 모든 테스트 클래스는 어설 션과 직접 사용되는 인쇄 문을 사용하지 않습니다) :
public class userrepositoryTest {@autowired private userrepository dao; @test // public void testsave () {user user = new user (); user.setName ( "chhliu"); user.setAccount ( "10000"); user.seteMail ( "[email protected]"); user.setpassword ( "123456"); dao.save (사용자); } @test // public void testsave1 () {list <user> users = new arraylist <user> (); 사용자 user = 새 사용자 (); user.setName ( "tanjie"); user.setAccount ( "10000"); user.seteMail ( "[email protected]"); user.setpassword ( "123456"); user.add (사용자); user = new user (); user.setName ( "esdong"); user.setAccount ( "10000"); user.seteMail ( "[email protected]"); user.setpassword ( "123456"); user.add (사용자); user = new user (); user.setName ( "qinhongfei"); user.setAccount ( "10000"); user.seteMail ( "[email protected]"); user.setpassword ( "123456"); user.add (사용자); user = new user (); user.setName ( "huizhang"); user.setAccount ( "10000"); user.seteMail ( "[email protected]"); user.setpassword ( "123456"); user.add (사용자); user = new user (); user.setName ( "Caican"); user.setAccount ( "10000"); user.seteMail ( "[email protected]"); user.setpassword ( "123456"); user.add (사용자); dao.save (사용자); } @test // 업데이트 public void testupdate () {user user = dao.findone (1); user.setpassword ( "123890"); // 이러한 방식으로 업데이트 함수를 구현하려면 @transaction thing thing thing that the service layer} @test // public void testdelete () {dao.delete (2); } @test // query 모든 공개 void testfindall () {list <user> users = (list <user>) dao.findall (); System.out.println (json.tojsonstring (사용자)); } @test // query 지정된 ID 객체가 존재하는지 여부 공개 void testisexist () {boolean isexist = dao.exists (8); System.out.println (isexist); } @test // query public void testfinduserByids () {list <integer> listIds = new ArrayList <integer> (); ListIds.add (2); ListIds.add (4); ListIds.add (7); List <user> user = (list <user>) dao.findall (listids); System.out.println (json.tojsonstring (사용자)); }} 보시다시피,이 시점에서 나는 하나의 인터페이스 클래스 만 작성 했고이 인터페이스 클래스를 구현하지 않았으므로 기본 CRUD 작업을 완료 할 수있었습니다. 이 인터페이스는 비즈니스 계층을 직접 사용하기 위해 도메인 객체를 추가, 삭제, 수정 및 검색하기위한 메소드를 자동으로 생성하기 때문입니다.
인터페이스는 다음과 같이 정의되며 총 11 개의 방법이 제공되며 기본적으로 간단한 CRUD 작업 및 배치 작업을 충족시킬 수 있습니다.
@norepositorybean public interface crudrepository <t, id는 Serializable> 확장 리포지토리 <t, id> {<s extends t> s save (s entity); // save <s interable <s> save (iterable <s> entitities); // id id) 반복적 인 <t> findall (); // query 모든 객체 반복 가능한 <t> findall (iterable <id> ids); // id lets list long count (); // juber void delete (id id)의 총 개체 void delete (t entity); // 삭제 삭제 (iterable <? extente); void deleteall (); // 모두 삭제} 2. PAGIGENDANDSORTINGREPOSITORY 인터페이스
PigingAndSortingRepository 인터페이스는 Crudrepository 인터페이스를 상속합니다.
인터페이스를 작성하고 PagingAndSortingRepository 인터페이스를 상속합니다
Public Interface userRepository는 PAGIGENDANDSORTINGREPOSITORITY <USER, Integer> {}을 확장합니다. 테스트 수업 작성 :
@RunWith (springJunit4classRunner.class) @ContextConfiguration (locations = { "classPath : ApplicationContext-config.xml"}) @transactionConfiguration (defaultrollback = false) @autowired private uspositoration dao; @test public void testorder () {sort sort = new Sort (Direction.desc, "id"); pageable pagable = new pagerequest (0, 5, sort); Page <user> page = dao.findall (pagable); System.out.println (json.tojsonstring (page)); System.out.println (page.getSize ()); }} 이 인터페이스를 상속하는 한 Spring Data JPA는 이미 페이지 매김 및 정렬 기능을 제공합니다. 인터페이스는 다음과 같이 정의되며 사용을 위해 두 가지 방법이 제공됩니다. 여기서 t는 작동 할 엔티티 클래스이고 ID는 엔티티 클래스 기본 키의 유형입니다.
@NorepositoryBean Public Interface PagingandSortingRepository <T, ID는 Serializeable> 확장 CrudRepository <t, id> {iterable <T> findAll (정렬); // 페이징 페이지 <T> findAll (pagable pagable); // PAGIE와 정렬}; 3. jparepository 인터페이스
비즈니스가 CRUD 운영을 제공하고 페이징 및 정렬 기능을 제공 해야하는 경우이 인터페이스를 직접 상속받을 수 있습니다. 이 인터페이스는 페이징 및 조종 조상 인터페이스를 상속합니다.
인터페이스는 다음과 같이 정의됩니다.
공개 인터페이스 jparepository <t, id serializable> 확장 patingandsortingrepository <t, id> {list <t> findall (); 모든 객체 쿼리, <t> findall (정렬)을 정렬하지 마십시오 (정렬); // 쿼리 <s> 목록 <S> 저장 (iterable <s> entrities); // boath voloid (entients); 데이터베이스 T SaveAndFlush (t entity)와 동기화; // void deleteInbatch (iterable <t> entities)를 저장하고 힘 동기화; // 배치 삭제 void deleteallinbatch (); // all}} 4. JPASPECIFICIATIONEXECUTOR 인터페이스
이 인터페이스는 JPA 기준 쿼리를 지원합니다. 이 인터페이스는 매우 특별하며 저장소 시스템에 속하지 않습니다. 스프링 데이터 JPA는 자동으로 스캔하고 인식하지 않으므로 해당 콩을 찾을 수 없습니다. 저장소를 상속하거나 저장소 인터페이스를 직접 상속하는 하위 인터페이스 만 상속하면됩니다. Spring Data JPA는 통합 관리를 자동으로 스캔하고 인식하고 수행합니다.
인터페이스는 다음과 같이 작성됩니다.
public Interface SpecificationExecutorRepository 확장 CrudRepository <User, Integer>, jpaspecificationExecutor <user> {} 서비스 수업 :
@Service public class SpecificationExecutorRepositoryManager {@autowired private specificationExecutorRepository dao; / *** 설명 : 이름*/ public user findUserByName (최종 문자열 이름) {return dao.findone (새 사양 <user> () {@override public preticate topredicate (root <user> root, critiagequery <?> 쿼리, criteriaBuilder cb) {root.equal (root.eget (pretical) "; }); } / *** 설명 : 이름과 이메일을 기반으로 사용자를 쿼리* / 공개 사용자 findUserByNameAndEmail (최종 문자열 이름, 최종 문자열 이메일) {return dao.findone (new spucification <user> () {@override public predicate topredicate (root <user> root, criteriaQuery <?> query, criteriAilder cb) {precticate>); predict1 = cb.get ( "이름"). } / *** 설명 : 조합 쿼리* / 공개 사용자 findUserByUser (최종 사용자 Uservo) {return dao.findone (새 사양 <user> () {@override public predicate topredicate (root <user> root, critiagecer <?> 쿼리, criteriaBuilder cb) {root.equal (root. uservo.getName (); } / *** 설명 : [2,10]에서 사용자 ID로 사용자를 쿼리하는 것과 같은 범위 쿼리* / public list <user> findUserByIds (Final List <Erdeger> ids) {return dao.findall (new Specification <user> () {@override public percritice topredicate (root <user> root, criteriaquery <?> query, criteriaBuilder CB) root.in (ids); } / *** 설명 : 범위 쿼리 GT 메서드, 9* / public list <user> finduserbygtid (final int id) {return dao.findall (new Specification <user> () {@override public predicate topredicate (root <user> root, criteriaquery <?> cbuilder cbuilder cbuilder cbuilder cbuilder cbuilder cbuilder cbuilder cb.gt (root.get ( "id"). as (integer.class), id); } / *** 설명 : 범위 쿼리 LT 메소드 (10* / public list <user> finduserbyltid) {return dao.findall (new Specification <user> () {@override public predicate topredicate (root <user> root, criteriaquery <?> querybuilder cb) {criteriaBuilder cb) cb.lt (root.get ( "id"). as (integer.class), id); } / *** 설명 : 3에서 10 사이의 ID로 사용자를 쿼리하는 것과 같은 범위 쿼리* / public list <user> finduserbetweenid (finduserbetweenid, final int end) {return dao.findall (new Specification <user> () {@override public predicate propredicate (root <user> root, critiaruery <?> query, criteriabuilder cb). cb.betgreen (root.get ( "id"). as (integer.class), end); } / *** 설명 : 정렬 및 페이지 매김 작업* / public page <user> findUserAndorder (final int id) {sort sort = new Sort (Direction.desc, "id"); return dao.findall (새 사양 <user> () {@override public predicate topredicate (root <user> root, criteriaQuery <?> query, criteriaBuilder cb) {return cb.gt ( "id"). } / *** 설명 : 전용 분류 작업* / public list <user> findUserAndordorderSecondMethod (Final int id) {return dao.findall (new Specification <user> () {@override public the percedicate topredicate (rood <user> root, criteriaQuery <?> query, criteriabuilder cb) { cb.gt ( "id"). as (integer.class), query.orderby (root.get ( "id")); }} 테스트 클래스 :
@RunWith (SpringJunit4classRunner.class) @ContextConfiguration (locations = { "classPath : ApplicationContext-config.xml"}) @transactionConfiguration (defaultrollback = false) @transactional public classexecutorrepository ManagerTest {@autowired pritaleexexexecutoreManger; @test public void testfinduserbyname () {user user = manager.finduserbyname ( "chhliu"); System.out.println (json.tojsonstring (user)); } @test public void testfinduserbynameandemail () {user user = manager.finduserbynameandemail ( "chhliu", "chhliu @.com"); System.out.println (json.tojsonstring (user)); } @test public void testfinduserByUservo () {user user = new user (); user.setName ( "chhliu"); user.seteMail ( "[email protected]"); User U = Manager.FinduserByUser (사용자); System.out.println (json.tojsonstring (u)); } @test public void testfinduserbyids () {list <user> user = manager.finduserByids (new arraylist <integer> (arrays.aslist (1,3,5,6))); System.out.println (json.tojsonstring (사용자)); } @test public void testfinduserbygtid () {list <user> users = manager.finduserbygtid (5); System.out.println (json.tojsonstring (사용자)); } @test public void testfinduserbyltid () {list <user> users = manager.finduserByltid (5); System.out.println (json.tojsonstring (사용자)); } @test public void testfinduserbetweenid () {list <user> users = manager.finduserbetweenid (4, 9); System.out.println (json.tojsonstring (사용자)); } @test public void testfinduserAndorder () {page <user> user = manager.finduserAndorder (1); System.out.println (json.tojsonstring (사용자)); } @test public void testfinduserAndorderCondMethod () {list <user> users = manager.finduserAndorderSecondMethod (1); System.out.println (json.tojsonstring (사용자)); }} 5. 저장소 인터페이스
이 인터페이스는 가장 기본적인 인터페이스이며 상징적 인 인터페이스 일 뿐이며 방법이 정의되지 않으므로이 인터페이스의 사용은 무엇입니까? 스프링 데이터 JPA는이 인터페이스를 제공하기 때문에 물론 유용합니다. 예를 들어, 외부에서 제공하고 싶지 않은 일부 방법. 예를 들어, 삭제 방법이 아닌 첨가 및 수정 방법 만 제공하려면 이전 인터페이스가 수행 할 수 없습니다. 현재이 인터페이스를 상속하고 Crudrepository 인터페이스의 해당 메소드를 리포지토리 인터페이스에 복사 할 수 있습니다.
요약 : 개발자는 위의 5 개의 인터페이스를 어떻게 선택해야합니까? 실제로, 기초는 매우 간단합니다. 특정 비즈니스 요구에 따라 그 중 하나를 선택하십시오. 각 인터페이스 사이에 강도와 힘의 문제가 없기 때문입니다.
4. 스프링 데이터 JPA 쿼리
1. @Query를 사용하여 쿼리를 만듭니다
@Query 주석의 사용은 매우 간단합니다. 선언 된 메소드에 주석에 레이블을 지정하고 JP QL 쿼리 문을 제공하면됩니다. 많은 개발자가 JP QL을 만들 때 위치 번호 대신 이름 지정된 매개 변수를 사용하는 것을 좋아하며 @Query도이를 지원합니다. JP QL 문에서 매개 변수는 ": variable"형식을 통해 지정되고 동시에 @Param은 메소드 매개 변수 앞에서 JP QL의 명명 된 매개 변수에 해당합니다. 또한 개발자는 @Query를 사용하여 업데이트 작업을 수행 할 수도 있습니다. 이를 위해서는 @Modify를 사용하여 @Query를 사용하는 동안 작업을 수정 된 쿼리로 식별해야하므로 프레임 워크가 결국 쿼리 작업이 아닌 업데이트 된 작업이 생성됩니다.
다음과 같이 인터페이스를 작성하십시오.
/*** 설명 : 사용자 정의 쿼리. 스프링 데이터 JPA가 제공 할 수없는 경우 사용자 정의 인터페이스가 필요합니다. 이 방법은이 시간에 사용할 수 있습니다*/ public interface userDefineByself는 jparepository <User, Integer> {/ *** 이름이 매개 변수* 설명 :이 메소드를 사용하는 것이 좋습니다. 매개 변수의 위치를 무시할 수 있습니다*/ @Query ( "U.Name = : name") 사용자 findUserByName (@param ( "name")); /*** 색인 매개 변수* 설명 : 사용? 자리 표시기*/ @Query ( "U.Email =? 1") // 1 사용자 u에서 U를 선택하십시오. /*** 설명 : @Modifying 및 @query를 통해 업데이트를 달성 할 수 있습니다.* 쿼리 수정의 반환 값은 void 또는 int/integer 만 가능하거나 @Query ( "Update U.name = : u.id = : id") int updateUserById ( "name") String (@param ( "id")); } 참고 : @Modifying Annotation에는 구성이 포함되어 있습니다
그것은 기본 지속성 컨텍스트를 지울 수 있으며, 이는 EntityManager 클래스입니다. JPA의 기본 구현에는 보조 캐시, 즉 데이터베이스를 업데이트 한 후 나중에이 개체를 사용하면 객체를 확인할 것입니다. 이 객체는 첫 번째 레벨에서 캐시되지만 데이터베이스와 동기화되지는 않습니다. 현재 ClearAutomically = True는 최대 절전 모드의 첫 번째 레벨 캐시를 새로 고치는 데 사용됩니다. 그렇지 않으면 동일한 인터페이스에서 객체를 업데이트 한 다음이 객체를 쿼리하면 찾은 객체는 이전에 이전에 업데이트되지 않은 이전 상태입니다.
테스트 클래스 :
@RunWith (SpringJunit4classRunner.class) @ContextConfiguration (locations = { "classPath : ApplicationContext-config.xml"}) @transactionConfiguration (defaultrollback = false) @autowired private userdefinebysfinbysfiflybysfinbysfilefinbysfinbyseffinbysfinbysfilefinbyselfefinbyselfefinbyseff dao; @test public void testfinduserbyname () {user user = dao.finduserbyname ( "chhliu"); assert.assertequals ( "chhliu", user.getname ()); System.out.println (user.getName ()); } @test public void testfinduserByemail () {user user = dao.finduserByemail ( "chhliu @.com"); assert.assertequals ( "chhliu", user.getname ()); System.out.println (user.getName ()); } @test public void testupdateuserbyid () {dao.updateuserByid ( "tanjie", 4); }} 테스트 코드에서 구현 클래스없이 인터페이스 만 정의하지만 필요한 기능을 구현한다는 것을 알 수 있습니다.
2. @Namedqueries를 사용하여 쿼리를 만듭니다
명명 된 쿼리는 JPA에서 제공하는 함수로 여러 메소드를 공유하기 위해 메소드 본문에서 쿼리 문을 분리합니다. Spring Data JPA는 또한 명명 된 쿼리를 잘 지원합니다. 사용자는 orm.xml 파일 또는 JPA 사양에 따라 코드에서 쿼리 문을 정의하면됩니다. 그들이해야 할 유일한 일은 진술을 지명 할 때 "domainclass.methodname ()"의 이름 지정 규칙을 충족시키는 것입니다.
인터페이스 작성 :
public interface findUserByNamedQueryRepository 확장 jparePository <User, Integer> {user findUserWithName (@param ( "name") 문자열 이름); } 수업 작성 :
@entity @namedQuery (value = {@namedquery (name = "user.finduserwithName" ", query ="query = "U.name = : name")})))) : 여기에 여러 가지 메소드가 있으면 @namedquery를 사용해야합니다. 메소드가 하나만 있으면 @NamedQuery를 사용할 수 있습니다. 쓰기 방법은 다음과 같습니다. @NamedQuery (이름 = "user.finduserwithName", query = "u.name = : name") public class findUserByNamedQuery { / *** 참고 :이 엔티티 클래스는 여기에 정의되어야합니다. } 참고 : 기사에서 빨간색으로 표시된 부분은 하나씩 일치해야하며, 그렇지 않으면 JPA 사양을 충족하지 않습니다.
테스트 클래스 :
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = { "classpath:applicationContext-config.xml" }) @TransactionConfiguration(defaultRollback = false) @Transactional public class FindUserByNamedQueryRepositoryTest { @Autowired private FindUserByNamedQueryRepository dao; @test public void testfinduserbyname () {user user = dao.finduserwithname ( "Caican"); System.out.println (json.tojsonstring (user)); }} 3. 메소드 이름을 분석하여 쿼리를 만듭니다
이름에서 알 수 있듯이 메소드 이름을 기반으로 쿼리를 작성하는 것입니다. 어쩌면 처음에는 믿어지지 않지만 테스트 후 모든 것이 가능하다는 것을 알았습니다.
인터페이스 작성 :
공개 인터페이스 SimpleConditionQueryRepository 확장 jparepository <User, Integer> { /*** 설명 : 스프링 데이터로 정의 된 규칙에 따라 쿼리 메소드는 조건부 쿼리와 관련하여 찾기 | 읽기 | get*로 시작됩니다. 조건의 속성은 조건부 키워드와 연결됩니다. 조건부 속성의 첫 번째 문자는 대문자이어야합니다*// *** 참고 :이 인터페이스는 SQL을 보내는 것과 같습니다. U.name = : U.Name = : U.Name = : U.Mail = : 이메일* 매개 변수 이름은 대체 이름의 초기 문자와 동일합니다. FindByNameAndEmail (문자열 이름, 문자열 이메일); / ** * 참고 : 여기서이 인터페이스는 SQL을 전송하는 것과 같습니다. U.name =? 1 또는 u.password =? 2 */ list <user> findbynameorpassword (문자열 이름, 문자열 암호); / ** * 참고 : 여기서이 인터페이스는 SQL을 전송하는 것과 같습니다. U.id 사이의 U.id에서 u.id u.id u.id here u에서 u를 선택하십시오. / ** * 참고 : 여기서이 인터페이스는 SQL을 전송하는 것과 같습니다. U.id 사이의 U.id에서 u.id u.id u.id here u에서 u를 선택하십시오. / ** * 참고 : 여기서이 인터페이스는 SQL을 보내는 것과 같습니다. U.id <? 1 */ list <user> findByidlessthan (Integer end); / ** * 참고 : 여기서이 인터페이스는 SQL을 보내는 것과 같습니다. U.id>? 1 */ list <user> findByIdGreaterThan (Integer start); / ** * 참고 : 여기서이 인터페이스는 SQL을 전송하는 것과 같습니다. U.Name은 u.name이 null */ list <user> findbynameisnull (); / ** * 참고 : 여기서이 인터페이스는 SQL을 전송하는 것과 같습니다. U.Name이 아닌 User U에서 U를 선택하십시오 */ list <user> findByNameIsNotNull (); / ** * 참고 : 여기서이 인터페이스는 SQL을 전송하는 것과 같습니다. U.Name Like? 1 */ list <user> findBynamelike (문자열 이름); / ** * 참고 : 여기서이 인터페이스는 SQL을 전송하는 것과 같습니다. U.Name이 좋아하지 않는 사용자 U에서 U를 선택하십시오. / ** * 참고 : 여기서이 인터페이스는 SQL을 전송하는 것과 같습니다. U.id desc */ list <user> findbypasswordOrderByIddesc (String password)에 의한 U.Password =? 1 Order에서 U.Password =? / ** * 참고 : 여기서이 인터페이스는 SQL을 보내는 것과 같습니다. U.Name <> 1 */ list <user> findBynamenot (String Name); / ** * 참고 : 여기서이 인터페이스는 SQL을 보내는 것과 같습니다. U.id in? 1 */ list <user> findbyidin (list <integer> ids); / ** * 참고 : 여기서이 인터페이스는 SQL을 전송하는 것과 같습니다. U.id가 아닌 Use U.id에서 U.id에서 U를 선택하십시오. } 테스트 클래스 (주석 부분은 실제 보낸 SQL 문) :
@RunWith (SpringJunit4classRunner.class) @ContextConfiguration (위치 = { "classPath : ApplicationContext-config.xml"}) @transactionConfiguration (defaultrollback = false) @transactional public class simpleconditionQueryRepository {@autowired privateCondefurepitory dao; /*** user0_.id를 id0_, user0_.account as ac 그리고 user0_.email =? 한계 ? */ @test public void testfinduserbynameandemail () {user user = dao.findbyameandemail ( "chhliu", "chhliu @.com"); System.out.println (json.tojsonstring (user)); } /*** user0_.id as as id1_, user0_.account as ac 또는 user0_.password =? */ @test public void testfinduserbynameorpassword () {list <user> users = dao.findbynameorpassword ( "chhliu", "123456"); System.out.println (json.tojsonstring (사용자)); } /*** use as as as as as account1_, user0_.email as email1_, user0_.name as name1_, user0_.password as user user0_. 그리고 ? */ @test public void testfindbyIdbetween () {list <user> users = dao.findbyIdbetween (5, 8); System.out.println (json.tojsonstring (사용자)); } /*** user0_.id as as id1_, user0_.account as ac */ @test public void testfindbyidlessthan () {list <user> users = dao.findbyidlessthan (4); System.out.println (json.tojsonstring (사용자)); } /*** user0_.id as Id0_, user0_.account as ac */ @test public void testfindbyidgreaterthan () {list <user> users = dao.findbyidgreaterthan (6); System.out.println (json.tojsonstring (사용자)); } / ** * user0_.id as id0_, user0_.account as account0_, user0_.email as aven0_, user0_.name as name0_, user0_.name as user user0_.name as user0_.name은 null * / @test public void testfindbyNameisnull () {user> user> user> us us user0_.name as us user0_.name as us user0_.name as as user0_.password as as user0_.password를 선택합니다. System.out.println (json.tojsonstring (사용자)); } / ** * user0_.id, id1_, user0_.account as account1_, user0_.email as email1_, user0_.name as name1_, user0_.password as user user0_. dao.findbynameisnotnull (); System.out.println (json.tojsonstring (사용자)); } /*** user0_.id as as id1_, user0_.account as ac */ @test public void testfindbynamelike () {list <user> users = dao.findbynamelike ( "chhliu"); System.out.println (json.tojsonstring (사용자)); } /*** user0_.id as id0_, user0_.account as ac */ @test public void testfindbynamenot like () {list <user> users = dao.findbynamenot like ( "chhliu"); System.out.println (json.tojsonstring (사용자)); } /*** user0_.id as Id0_, user0_.account as ac user0_.id desc */ @test public void testfindbypasswordordordordordordesc () {list <user> users = dao.findbypasswordordordoDdesc ( "123456"); System.out.println (json.tojsonstring (사용자)); } /*** user0_.id as id1_, user0_.account as ac */ @test public void testfindbynamenot () {list <user> users = dao.findbynamenot ( "chhliu"); System.out.println (json.tojsonstring (사용자)); } / ** * user0_.id as id1_, user0_.account as account1_, user0_.email as email1_, user0_.name as name1_, user0_.name as user user0_.id as user user0_. ArrayList <integer> (arrays.aslist (3,4,6,8))); System.out.println (json.tojsonstring (사용자)); } / ** * user0_.id as id0_, user0_.account as ac dao.findbyidnotin (new Arraylist <integer> (Arrays.aslist (3, 4, 6, 8))); System.out.println (json.tojsonstring (사용자)); }} 여기서는 하나의 인터페이스 만 정의합니다. 인터페이스에는 메소드가 있지만 구현은 없지만 다양한 작업이 완료됩니다.
이것을 본 후, 많은 사람들이 아마도 봄 데이터 JPA가 어떻게했는지 물어볼 것입니다. 프레임 워크가 메소드 이름을 분석 할 때 먼저 찾기, findby, read, readby, get, getby, 나머지 부분을 구문 분석하는 메소드 이름의 초과 접두사를 차단합니다. 이 메소드의 마지막 매개 변수가 정렬 또는 pagable 유형 인 경우 규칙별로 정렬 또는 페이지 매김 쿼리를 위해 관련 정보가 추출됩니다. 쿼리를 만들 때 findbyidin ()과 같은 메소드 이름에서 속성 이름을 사용하여 표현합니다. 프레임 워크 가이 방법을 구문 분석하면 먼저 Findby를 제거한 다음 나머지 속성을 구문 분석합니다.
쿼리 할 때 일반적으로 여러 속성을 기반으로 동시에 쿼리해야하며 쿼리 조건은 다른 형식 (특정 값, 특정 범위에서)이 다릅니다. Spring Data JPA는 조건부 쿼리를 표현하기위한 몇 가지 키워드를 제공합니다.
그리고 --- findByUsernameandPassword (String User, Striang PWD)와 같은 SQL의 및 키워드와 동등한 것
또는 --- findByUserNameOrAddress (String user, String Addr)와 같은 SQL의 또는 키워드에 해당합니다.
사이의 --- FindBysAlaryBetween (Int Max, Int Min)과 같은 SQL과 동등한 키워드 간
Lessthan --- findBysalarylessthan (int max)과 같은 SQL의 "<"와 동일합니다.
Greater than --- findbysalarygreaterthan (int min)과 같은 SQL의 ">"에 해당합니다.
ISNULL --- findByUserNameisNull ()와 같은 SQL에서 "is null"에 해당합니다.
ISNOTNULL --- findByUserNameISNOTNULL ()와 같은 SQL에서 "NOT NULL"에 해당합니다.
NOTNULL --- ISNOTNULL에 해당합니다
like --- findbyusernamelike (String user)와 같은 SQL에서 "좋아요"에 해당합니다.
알게되지 않습니다 --- findbyusernamenot like (string user)와 같은 SQL에서 "좋아하지 않음"에 해당합니다.
Orderby ---- FindByUserNameRorderBysalaryAsc (String user)와 같은 SQL에서 "Order"에 해당합니다.
예를 들어 SQL에서 "! ="에 해당하지 않습니다.
in --- findbyusernamein (collection <string> userList)과 같은 SQL에서 "in"에 해당합니다. 방법의 매개 변수는 수집 유형 또는 배열 또는 무한 길이 매개 변수 일 수 있습니다.
Notin --- findbyusernamenotin (collection <string> userlist)과 같은 SQL에서 "Not In"과 동일합니다. 방법의 매개 변수는 수집 유형 또는 배열 또는 무한 길이 매개 변수 일 수 있습니다.
5. 쿼리 생성 순서
인터페이스에 대한 프록시 객체를 만들 때 위의 상황 중 하나가 동시에 사용할 수 있다는 것을 알게되면 어떤 전략을 먼저 채택해야합니까? 이렇게하려면 <jpa : repositories>는 검색 순서를 지정하기 위해 쿼리-루프-스트레이트기 속성을 제공합니다. 다음 세 가지 값이 있습니다.
작성 --- 메소드 이름을 해결하여 쿼리를 만듭니다. @Query를 통해 메소드에 의해 지정된 쿼리 명령이 일치하는 경우에도 무시됩니다.
Create-if-not-found --- 메소드가 @Query를 통해 쿼리 문을 지정하면 쿼리가 구현됩니다. 그렇지 않은 경우, 기준을 충족하는 이름의 쿼리가 정의되는지 여부를 발견하면 이름이 지정된 쿼리가 사용되는지 여부가 발견됩니다. 도 발견되지 않으면 메소드 이름을 구문 분석하여 쿼리가 생성됩니다. This is the default value of the query-lookup-strategy property.
use-declared-query --- 如果方法通过@Query 指定了查询语句,则使用该语句实现查询;如果没有,则查找是否定义了符合条件的命名查询,如果找到,则使用该命名查询;如果两者都没有找到,则抛出异常。
六、Spring Data JPA 对事务的支持
Careful readers may see some clues from the above code. When we use Spring data JPA, we just define the interface. When using it, we can just inject it directly, and we do not do any processing related to things. But in fact, things have already achieved results. 이게 왜?
默认情况下,Spring Data JPA 实现的方法都是使用事务的。针对查询类型的方法,其等价于@Transactional(readOnly=true);增删改类型的方法,等价于@Transactional。可以看出,除了将查询的方法设为只读事务外,其他事务属性均采用默认值。
如果用户觉得有必要,可以在接口方法上使用@Transactional 显式指定事务属性,该值覆盖Spring Data JPA 提供的默认值。同时,开发者也可以在业务层方法上使用@Transactional 指定事务属性,这主要针对一个业务层方法多次调用持久层方法的情况。持久层的事务会根据设置的事务传播行为来决定是挂起业务层事务还是加入业务层的事务。
위는이 기사의 모든 내용입니다. 모든 사람의 학습에 도움이되기를 바랍니다. 모든 사람이 wulin.com을 더 지원하기를 바랍니다.