spring data jpa進級


記事の目次
  • カスタムSQLクエリ
  • 複合クエリはどのように
  • を実現しますか?
  • 事務について
  • 原理概説
    spring data jpaの提案を理解しないで先に私の前の文章を見ます.
    spring data jpa入門例
    本編のソースの住所:
    https://github.com/pony-maggie/spring-boot-jpa-advance
    カスタムSQLクエリ
    mybatisは大量にカスタマイズして検索するシーンが得意で、spring data jpaは優勢はここではありませんが、カスタムSQLクエリにも対応しています.それは主に@Queryで注釈してサポートしています.
    @Transactional
    @Modifying
    	@Query("update Student u set u.name = ?1 where u.id = ?2")
    	int modifyNameById(String  name, Long id);
    
    @Query("select u from Student u where u.age = ?1")
    	Student findByMyAge(int age);
    
    
    @Queryコメントでは更新文を作成していますが、@Modifyingを使って修正しなければなりません.Spring Dataに通知します.これはUPDATEまたはDELETE操作です.
    @Transationとは、ビジネスを開始するという意味で、追加しないと以下の異常が発生します.
    javax.persistence.TransactionRequiredException
    
    その後、私たちはcontrollerにテストインターフェースを入れてテストを行います.
    http://localhost:8080/student/byAge?age=16
    http://localhost:8080/student/modifyNameById?name=zhangsan&id=3
    複雑なクエリはどうやって実現されますか?
    いくつかのビジネスシーンでは、いくつかの条件を指定して改ページ、関連クエリなどの複雑なクエリが必要です.このような場面をサポートするために、spring data jpaを提供してくれました.
    JpaSpecification Exectorは以下のインターフェースを提供します.
    public interface JpaSpecificationExecutor<T> {
    
        T findOne(Specification<T> spec);
    
        List<T> findAll(Specification<T> spec);
    
        Page<T> findAll(Specification<T> spec, Pageable pageable);
    
        List<T> findAll(Specification<T> spec, Sort sort);
    
        long count(Specification<T> spec);
    }
    
    伝わるパラメータSpecificationはインタフェースです.私たちの主な仕事はこのインターフェースを実現することです.ここで一つ実現しました.
    public class MyTestSpec implements Specification {
    
        @Override
        public Predicate toPredicate(Root root, CriteriaQuery criteriaQuery, CriteriaBuilder criteriaBuilder) {
            Path id = root.get("id");
            Predicate predicate = criteriaBuilder.gt(id, 3);
    
    
            return  predicate;
    
        }
    }
    
    そして私たちはserviceでテストを呼び出します.
    //        ,             
        public Page<Student> findByMySpec(int page, int pageSize){
            Sort sort = new Sort(Sort.Direction.DESC, "id");
            Pageable pageable = PageRequest.of(page, pageSize);
    
            Page<Student> students = studentRepository.findAll(new MyTestSpec(), pageable);
            return students;
        }
    
    印刷されたSQLは以下の通りです
    Hibernate: select student0_.t_id as t_id1_0_, student0_.t_age as t_age2_0_, student0_.t_name as t_name3_0_, student0_.t_school as t_school4_0_ from t_student student0_ where student0_.t_id>3 limit ?, ?
    Hibernate: select count(student0_.t_id) as col_0_0_ from t_student student0_ where student0_.t_id>3
    
    私たちはカスタムSpecificationを通じて、3ページ以上のIDの照会操作を実現していることが分かります.だからSpecificationを利用して、私達は各種の複雑なクエリをカスタマイズして、甚だしきに至っては各種の複雑なクエリを組み合わせて使うことができます.
    みんなはソースをダウンロードして自分でテストしてみてください.
    事務について
    Jparepositoryが提供する添削のインタフェースの方法はデフォルトはすべて事務を支持したので、私達は更に単独で声明する必要がありません.これはJpaRepositoryがデフォルトでSimpleJpaRepositryを実現しているからです.その定義は以下の通りです.
    @Repository
    @Transactional(readOnly = true)
    public class SimpleJpaRepository<T, ID extends Serializable> implements JpaRepository<T, ID>,
            JpaSpecificationExecutor<T> {
        ......
        @Transactional
        public void delete(ID id) {
        ......
        }
     
        @Transactional
        public void delete(T entity) {
        ......
        }
        
        @Transactional
        public void delete(Iterable<? extends T> entities) {
        ......
        }
        
        @Transactional
        public void deleteInBatch(Iterable<T> entities) {
        ......
        }
        
        @Transactional
        public void deleteAll() {
        ......
        }
        
        @Transactional
        public void deleteAllInBatch() {
        ......
        }
    
        @Transactional
        public <S extends T> S save(S entity) {
        ......
        }
        
        @Transactional
        public <S extends T> S saveAndFlush(S entity) {
        ......
        }
     
        @Transactional
        public <S extends T> List<S> save(Iterable<S> entities) {
        ......
        }
     
        ......
    }
    
    もし私たちがservice層で起動したDAO方法がカスタムではないなら、springはSimpleJpaRespositryの方法を動的代理機構で呼び出します.
    カスタムSQLに対しては、トランザクションをサポートするには、方法に注釈@Transationを加えるだけでよい.例えば、前のカスタムSQLクエリの例.
    DAO層を除いて、サービス層に事務を導入する必要があります.例えば、service方式があれば、2段階のDAO層の操作(削除と挿入)を実行します.私たちの業務シーンはこの2つのステップが必要です.成功するか、失敗するかのどちらかです.
    @Transactional
        public void testWithTransactional() throws Exception {
    
            studentRepository.deleteById(4L);
    
            Student student = new Student();
            student.setName("test2");
            student.setAge(31);
            student.setSchool("test2 school");
            studentRepository.save(student);
    
            if (1 == 1) {
                throw new RuntimeException("             ");
            }
    
    
        }
    
        //           
        public void testWithoutTransactional() throws Exception {
    
            studentRepository.deleteById(4L);
    
            Student student = new Student();
            student.setName("test3");
            student.setAge(33);
            student.setSchool("test3 school");
            studentRepository.save(student);
    
            if (1 == 1) {
                throw new RuntimeException("              ");
            }
        }
    
    //      
    	@RequestMapping(value = "/twt", method = RequestMethod.GET)
    	public void twt() {
    		try {
    			studentService.testWithTransactional();
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    	}
    	@RequestMapping(value = "/twot", method = RequestMethod.GET)
    	public void twot() {
    		try {
    			studentService.testWithoutTransactional();
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    	}
    
    二つの方法を書いてデモを行いました.一つは事務注釈を持っています.一つは持たないで、二つの方法は例外を投げます.事務の方法を持って異常を投げたらロールバックします.事務を持たない方法はロールバックしません.
    ここで注意したいのですが、運転中に異常があったらロールバックします.
    原理の概要
    springは起動時にRepositoriesを具体化して、すべてのクラスをスキャンします.そして私達が定義したorg.springframe ork.data.repository.Repositoryのインターフェースを探し出して、これらのインターフェースを巡回して、各インターフェースに対して次のようないくつかの例を順次作成します.
  • SimpleJpasspositryは、デフォルトのDAO動作を行うために使用され、すべてのRepositoryのデフォルト実装
  • です.
  • Jparepository FactoryBean-組立beanは、動的エージェントProxyを搭載し、対応するDAOのbeanNameをkeyとしてDefault Listable BenFactoryに登録し、注入が必要なときにこのbeanから対応する動的エージェントProxyを取り出しDAO
  • に注入する.
  • JdkDynamicAopProxy――動的エージェントに対応するInvocationHandlerは、DAOインターフェースをブロックするすべての方法の呼び出しを担当し、それに対応する処理を行います.例えば、findByUsernameが呼び出された時に、まずこの種類のinvoke方法
  • を通ります.
    参照
    http://www.luckyzz.com/java/spring-data-jpa/
    https://blog.csdn.net/J080624/article/details/84581231