您的位置:首页 > 编程语言 > ASP

Spring Data JpaSpecificationExecutor 做复杂查询

2017-09-28 09:43 603 查看
配置文件以及项目结构和数据表都是没变的

JpaSpecificationExecutor 源码

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);
}


PersonJpaSpecificationExecutor 需要继承JpaSpecificationExecutor和

JpaRepository接口 由于JpaSpecificationExecutor没有继承Repository接口所以不能被Sp
4000
ring 容器识别 自动识别为Repository

package com.ncsi.SpringData.Repository;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.stereotype.Repository;

import com.ncsi.SpringData.Entity.Person;

@Repository
public interface PersonJpaSpecificationExecutor extends JpaSpecificationExecutor<Person>,JpaRepository<Person, Integer>{

}


所以我们需要继承JpaRepository 才能被xml文件配置的jpa properties所识别

<!-- 加入 jpa 的命名空间 -->
<jpa:repositories base-package="com.ncsi.SpringData.Repository"
entity-manager-factory-ref="entityManagerFactory"></jpa:repositories>


Test:

package com.ncsi.SpringData;

import java.util.ArrayList;
import java.util.List;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import com.ncsi.SpringData.Entity.Person;
import com.ncsi.SpringData.Repository.PersonJpaSpecificationExecutor;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:springdata.xml")
public class TestPersonJpaSpecificationExecutor {

@Autowired(required=false)
PersonJpaSpecificationExecutor personJpaSpecificationExecutor;
@Test
public void testpersonJpaSpecificationExecutor(){
Person p=new Person();
p.setLastName("liu");
p.setEmail("@qq.com");
List<Person> persons=personJpaSpecificationExecutor.findAll(new Specification<Person>(){

@Override
public Predicate toPredicate(Root<Person> root,CriteriaQuery<?> query, CriteriaBuilder cb) {
// TODO Auto-generated method stub
List<Predicate> list=new ArrayList<Predicate>();
list.add(cb.equal(root.get("lastName").as(String.class),p.getLastName()));
list.add(cb.equal(root.get("email").as(String.class),p.getEmail()));

Predicate[] p2 = new Predicate[list.size()];
query.where(cb.and(list.toArray(p2)));
return query.getRestriction();
}

});
System.out.println(persons);
}
}


Hibernate:
select
person0_.id as id1_0_,
person0_.birth as birth2_0_,
person0_.email as email3_0_,
person0_.last_name as last_nam4_0_
from
jpa_person person0_
where
person0_.last_name=?
and person0_.email=?
17:55:55.351 [main] DEBUG o.s.orm.jpa.JpaTransactionManager - Initiating transaction commit
17:55:55.351 [main] DEBUG o.s.orm.jpa.JpaTransactionManager - Committing JPA transaction on EntityManager [org.hibernate.ejb.EntityManagerImpl@7561db12]
17:55:55.351 [main] DEBUG o.s.orm.jpa.JpaTransactionManager - Closing JPA EntityManager [org.hibernate.ejb.EntityManagerImpl@7561db12] after transaction
17:55:55.351 [main] DEBUG o.s.o.jpa.EntityManagerFactoryUtils - Closing JPA EntityManager
[Person [id=1, lastName=liu, email=@qq.com, birth=0912]]


这里面只是查询了where 条件的两个字段 当在项目中查询 插入数据是否在数据库中有相同数据的时候就可以使用这个,当然是在表的字段有许多个的时候,就可以用这个 返回的就是某些字段相同的数据的集合

为什么不直接继承Repository呢

当在继承Repository时 PersonJpaSpecificationExecutor 不会报错,只有一个警告,但是在运行时会出现PersonJpaSpecificationExecutor

no such bean这样的错误 也就是说没有起作用

我也试着直接在xml文件中以
<bean id="personJpaSpecificationExecutor" class="com.ncsi.SpringData.Repository.PersonJpaSpecificationExecutor"/>
的形式注册这个接口到容器中 但是由于我是注册的接口,所以我的理解是没有实现类只是一个接口 也就无法被容器实例化了

这两样都是不行的 暂时还没想到不继承JpaRepository 又能运行不报错的方法
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: