Tüm veritabanı işlemlerini gerçekleştirmek için Bahar JPA kullanıyorum. Ancak Bahar JPA bir tablodan belirli sütunları seçmek nasıl bilmiyorum?
Örneğin:
SELECT projectId, projectName FROM projects
Tüm veritabanı işlemlerini gerçekleştirmek için Bahar JPA kullanıyorum. Ancak Bahar JPA bir tablodan belirli sütunları seçmek nasıl bilmiyorum?
Örneğin:
SELECT projectId, projectName FROM projects
Yanıtlar:
Ayarlayabilirsiniz nativeQuery = true
içinde @Query
bir gelen açıklama Repository
şöyle sınıfa:
public static final String FIND_PROJECTS = "SELECT projectId, projectName FROM projects";
@Query(value = FIND_PROJECTS, nativeQuery = true)
public List<Object[]> findProjects();
Ancak haritayı kendiniz yapmanız gerektiğini unutmayın. Sadece bu iki değere gerçekten ihtiyacınız olmadıkça, bu gibi düzenli eşlenmiş aramayı kullanmak daha kolaydır:
public List<Project> findAll()
Muhtemelen Spring veri belgelerine de bakmaya değer .
FIND_PROJECTS
olan) value
olarak yazmak için bu benim kod olsaydı dolayısıyla ben olurdu özellik adının ( @Query(value = FIND_PROJECTS, nativeQuery = true)
vs
Spring Data JPA (doc) projeksiyonlarını kullanabilirsiniz . Sizin durumunuzda arayüz oluşturun:
interface ProjectIdAndName{
String getId();
String getName();
}
ve deponuza aşağıdaki yöntemi ekleyin
List<ProjectIdAndName> findAll();
Özellikle sözdizimini sevmiyorum (biraz hacky görünüyor ...) ama bulabildiğim en zarif çözüm (JPA veri havuzu sınıfında özel bir JPQL sorgusu kullanıyor):
@Query("select new com.foo.bar.entity.Document(d.docId, d.filename) from Document d where d.filterCol = ?1")
List<Document> findDocumentsForListing(String filterValue);
O zaman elbette, yapıcı argümanlarını Document
kabul eden docId
ve filename
yapıcı olarak bir yapıcı sağlamanız gerekir .
Benim durumumda, sadece json sonucuna ihtiyacım var ve bu benim için çalışıyor:
public interface SchoolRepository extends JpaRepository<School,Integer> {
@Query("select s.id, s.name from School s")
List<Object> getSchoolIdAndName();
}
Denetleyicide:
@Autowired
private SchoolRepository schoolRepository;
@ResponseBody
@RequestMapping("getschoolidandname.do")
public List<Object> getSchool() {
List<Object> schools = schoolRepository.getSchoolIdAndName();
return schools;
}
Object
mpr tarafından açıklanan özel bir arayüzle değiştirmelisiniz . kusursuz çalışıyor
Benim durumumda gerekli olmayan alanlar olmadan ayrı bir varlık sınıfı oluşturdum (sadece gerekli olan alanlarla).
Varlığı aynı tabloyla eşleyin. Şimdi tüm sütunlar gerektiğinde eski varlığı kullanıyorum, yalnızca bazı sütunlar gerektiğinde lite varlığını kullanıyorum.
Örneğin
@Entity
@Table(name = "user")
Class User{
@Column(name = "id", unique=true, nullable=false)
int id;
@Column(name = "name", nullable=false)
String name;
@Column(name = "address", nullable=false)
Address address;
}
Şunun gibi bir şey oluşturabilirsiniz:
@Entity
@Table(name = "user")
Class UserLite{
@Column(name = "id", unique=true, nullable=false)
int id;
@Column(name = "name", nullable=false)
String name;
}
Bu getirilecek sütunları bildiğinizde işe yarar (ve bu değişmeyecektir).
sütunlara dinamik olarak karar vermeniz gerekiyorsa çalışmaz.
Sanırım en kolay yol , Spring-Data ile birlikte gelen QueryDSL kullanmaktır .
Sorunuzu kullanarak cevap olabilir
JPAQuery query = new JPAQuery(entityManager);
List<Tuple> result = query.from(projects).list(project.projectId, project.projectName);
for (Tuple row : result) {
System.out.println("project ID " + row.get(project.projectId));
System.out.println("project Name " + row.get(project.projectName));
}}
Varlık yöneticisi Otomatik Kablolu olabilir ve her zaman * QL dili kullanmadan nesne ve sınıflarla çalışacaksınız.
Bağlantıda görebileceğiniz gibi, son seçim neredeyse benim için daha zarif görünüyor, yani sonucu saklamak için DTO kullanıyor. Aşağıdaki örneklere başvurun:
JPAQuery query = new JPAQuery(entityManager);
QProject project = QProject.project;
List<ProjectDTO> dtos = query.from(project).list(new QProjectDTO(project.projectId, project.projectName));
ProjectDTO'nun tanımlanması:
class ProjectDTO {
private long id;
private String name;
@QueryProjection
public ProjectDTO(long projectId, String projectName){
this.id = projectId;
this.name = projectName;
}
public String getProjectId(){ ... }
public String getProjectName(){....}
}
Yeni Spring versiyonlarıyla One aşağıdakileri yapabilir:
Yerel sorgu kullanılmıyorsa, bu aşağıdaki gibi yapılabilir:
public interface ProjectMini {
String getProjectId();
String getProjectName();
}
public interface ProjectRepository extends JpaRepository<Project, String> {
@Query("SELECT p FROM Project p")
List<ProjectMini> findAllProjectsMini();
}
Yerel sorgu kullanılarak aynı şekilde yapılabilir:
public interface ProjectRepository extends JpaRepository<Project, String> {
@Query(value = "SELECT projectId, projectName FROM project", nativeQuery = true)
List<ProjectMini> findAllProjectsMini();
}
Ayrıntılı bilgi için dokümanları kontrol edin
Bence bu harika bir çözüm:
interface PersonRepository extends Repository<Person, UUID> {
<T> Collection<T> findByLastname(String lastname, Class<T> type);
}
ve böyle kullanmak
void someMethod(PersonRepository people) {
Collection<Person> aggregates =
people.findByLastname("Matthews", Person.class);
Collection<NamesOnly> aggregates =
people.findByLastname("Matthews", NamesOnly.class);
}
Spring Data JPA kullanıldığında, veritabanından belirli sütunları seçmek için bir hüküm vardır
---- DAOImpl'de ----
@Override
@Transactional
public List<Employee> getAllEmployee() throws Exception {
LOGGER.info("Inside getAllEmployee");
List<Employee> empList = empRepo.getNameAndCityOnly();
return empList;
}
---- Repo'da ----
public interface EmployeeRepository extends CrudRepository<Employee,Integer> {
@Query("select e.name, e.city from Employee e" )
List<Employee> getNameAndCityOnly();
}
Benim durumumda% 100 çalıştı. Teşekkürler.
JPQL kullanabilirsiniz:
TypedQuery <Object[]> query = em.createQuery(
"SELECT p.projectId, p.projectName FROM projects AS p", Object[].class);
List<Object[]> results = query.getResultList();
veya yerel sql sorgusu kullanabilirsiniz.
Query query = em.createNativeQuery("sql statement");
List<Object[]> results = query.getResultList();
Aşağıdaki kodu depo arabirim sınıfınıza uygulayabilirsiniz.
varlık adı, projeler gibi veritabanı tablo adınız anlamına gelir. Ve Liste, Projelerinizde Proje'nin Entity sınıfı olduğu anlamına gelir.
@Query(value="select p from #{#entityName} p where p.id=:projectId and p.projectName=:projectName")
List<Project> findAll(@Param("projectId") int projectId, @Param("projectName") String projectName);
Yerel Sorgu Kullanma:
Query query = entityManager.createNativeQuery("SELECT projectId, projectName FROM projects");
List result = query.getResultList();
@Jombie tarafından önerilen yanıtı kullanabilirsiniz ve:
findAll()
bu amaç için yöntemi geçersiz kılmayın, ancak seçtiğiniz adı kullanın;List
yeni arayüzünüzle parametreli bir parametre döndürmeyi unutmayın (örn. List<SmallProject>
).