JPA 뷰 질의 확인
만약 우리가 두 장의 시계, 한 장의 학원표, 한 장의 학생표가 있다고 가정하자.학원 표에는 학원 ID와 학원 이름이 저장되어 있고 학생 표에는 학생의 기본 정보가 저장되어 있다. 학번, 학원 ID와 학생 이름(다른 복잡한 속성은 보지 않는다)을 포함한다. 아래의 건표 문장에서 보듯이
-- ----------------------------
-- Table structure for `depts`
-- ----------------------------
DROP TABLE IF EXISTS `depts`;
CREATE TABLE `depts` (
`deptId` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT ' ID',
`deptName` varchar(50) NOT NULL COMMENT ' ',
PRIMARY KEY (`deptId`)
) ENGINE=InnoDB AUTO_INCREMENT=14 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of depts
-- ----------------------------
INSERT INTO `depts` VALUES ('1', ' ');
INSERT INTO `depts` VALUES ('2', ' ');
INSERT INTO `depts` VALUES ('3', ' ');
INSERT INTO `depts` VALUES ('4', ' ');
INSERT INTO `depts` VALUES ('5', ' ');
INSERT INTO `depts` VALUES ('6', ' ');
INSERT INTO `depts` VALUES ('7', ' ');
INSERT INTO `depts` VALUES ('8', ' ');
INSERT INTO `depts` VALUES ('9', ' ');
INSERT INTO `depts` VALUES ('10', ' ');
INSERT INTO `depts` VALUES ('11', ' ');
INSERT INTO `depts` VALUES ('12', ' ');
INSERT INTO `depts` VALUES ('13', ' ');
학생표를 하나 더 만들고 그 안에 점 데이터를 삽입한다.
-- ----------------------------
-- Table structure for `students`
-- ----------------------------
DROP TABLE IF EXISTS `students`;
CREATE TABLE `students` (
`stuNo` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT ' 1000 ',
`deptId` int(10) unsigned NOT NULL COMMENT ' ID',
`stuName` varchar(50) NOT NULL COMMENT ' ',
PRIMARY KEY (`stuNo`),
KEY `FK_DEPTID` (`deptId`),
CONSTRAINT `FK_DEPTID` FOREIGN KEY (`deptId`) REFERENCES `depts` (`deptId`) ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=1006 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of students
-- ----------------------------
INSERT INTO `students` VALUES ('1000', '13', ' ');
INSERT INTO `students` VALUES ('1001', '7', ' ');
INSERT INTO `students` VALUES ('1002', '3', ' ');
INSERT INTO `students` VALUES ('1003', '3', ' ');
INSERT INTO `students` VALUES ('1004', '2', ' ');
INSERT INTO `students` VALUES ('1005', '3', ' ');
현재 우리는 각 학원에 얼마나 많은 학생이 있는지 통계하고 싶다.이 문제는 우리가 SQL을 공부할 때 더할 나위 없이 간단하다.두 가지 실현 방법:Group By를 사용하고 Group By를 사용하지 않음:
SELECT b.deptId, b.deptName, count(*) as 'totalCount' FROM students a LEFT JOIN depts b ON a.deptId=b.deptId GROUP BY b.deptId ORDER BY b.deptId;
Group By를 사용한 후 학생에 대한 기록이 없는 학원은 모두 표시되지 않았습니다.
+--------+--------------+------------+
| deptId | deptName | totalCount |
+--------+--------------+------------+
| 2 | | 1 |
| 3 | | 3 |
| 7 | | 1 |
| 13 | | 1 |
+--------+--------------+------------+
Group By를 사용하지 않는 조회 하나 더:
SELECT a.deptId, a.deptName, (SELECT count(*) FROM students b where b.deptId=a.deptId) as 'totalCount' FROM depts a;
이번에 완전히 드러났어요.
+--------+--------------+------------+
| deptId | deptName | totalCount |
+--------+--------------+------------+
| 1 | | 0 |
| 2 | | 1 |
| 3 | | 3 |
| 4 | | 0 |
| 5 | | 0 |
| 6 | | 0 |
| 7 | | 1 |
| 8 | | 0 |
| 9 | | 0 |
| 10 | | 0 |
| 11 | | 0 |
| 12 | | 0 |
| 13 | | 1 |
+--------+--------------+------------+
이로써 저희 SQL이 다 썼습니다.그런데 어떻게 하면 JPA를 사용해서 같은 보기를 조회할 수 있을까요?우리는 일반적인 인코딩에 따라 하나의 주요 실체 조작 서비스에서 Entity Manager를 폭로했다.
package net.csdn.blog.chaijunkun.dao;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import org.springframework.stereotype.Service;
@Service
public class ObjectDaoServiceImpl implements ObjectDaoService {
@PersistenceContext
private EntityManager entityManager;
@Override
public EntityManager getEntityManager(){
return this.entityManager;
}
}
이렇게 하는 장점은 모든 데이터 조작이 같은 실체 관리자에서 기원된다는 것이다.앞으로 배치에 변화가 생기면 이 부분만 고쳐서 주입하면 된다.그리고 우리는 이전과 같이 두 개의 표를 구성하는 실체류가 필요하다.
학원표의 실체류:
package net.csdn.blog.chaijunkun.pojo;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name="depts")
public class Depts implements Serializable {
/**
*
*/
private static final long serialVersionUID = 3602227759878736655L;
@Id
@GeneratedValue(strategy= GenerationType.AUTO)
@Column(name= "deptId")
private Integer deptId;
@Column(name= "deptName", length= 50, nullable= false)
private String deptName;
//getters and setters...
}
학생표의 실체류:
package net.csdn.blog.chaijunkun.pojo;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
@Entity
@Table(name= "students")
public class Students implements Serializable {
/**
*
*/
private static final long serialVersionUID = -5942212163629824609L;
@Id
@GeneratedValue(strategy= GenerationType.AUTO)
@Column(name= "stuNo")
private Long stuNo;
@ManyToOne
@JoinColumn(name= "deptId", nullable= false)<SPAN style="WHITE-SPACE: pre"> </SPAN>
private Depts depts;
@Column(name= "stuName", length= 50, nullable= false)
private String stuName;
//getters and setters...
}
두 실체류를 모두 구성했다. 우리는 다음에 보기류를 하나 더 만들어야 한다. 속성의 유형은 완전히 당신이 원하는 구조로 구성된다.예를 들어 이 예에서 우리는 학원 번호, 학원 명칭과 총 인원수를 요구한다.그러면 우리는 이렇게 정의한다.
package net.csdn.blog.chaijunkun.pojo;
import java.io.Serializable;
public class Report implements Serializable {
/**
*
*/
private static final long serialVersionUID = 4497500574990765498L;
private Integer deptId;
private String deptName;
private Integer totalCount;
public Report(){};
public Report(Integer deptId, String deptName, Integer totalCount) {
this.deptId = deptId;
this.deptName = deptName;
this.totalCount = totalCount;
}
//getters and setters...
}
보기 대상의 정의는 실체 정의보다 간단하고 주석이 필요 없고 비추지 않아도 된다고 할 수 있다. (이상 코드는 코드의 양을 줄이기 위해 각 속성의 get과 set 방법을 절약했으니 스스로 추가하십시오.)그러나 유일하게 다른 것은 필드 초기화가 있는 구조 함수를 추가로 만들어야 한다는 것이다.또한 기본 무참구조 함수를 덮어쓸 수 없습니다.그리고 우리는 진정한 조회에 들어가기 시작했다. (보기로 볼 때 SQL 규범에서는 데이터를 수정할 수 없다. 따라서 보기는 SELECT 특성만 가지고 있다. 이것이 바로 많은 사람들이 JPA를 사용하여 실체 맵 데이터베이스에서 보기를 만드는 방식으로 조회를 하려고 하지만 맵이 성공하지 못하는 이유이다.)
package net.csdn.blog.chaijunkun.dao;
import java.util.List;
import javax.annotation.Resource;
import javax.persistence.EntityManager;
import javax.persistence.TypedQuery;
import org.springframework.stereotype.Service;
import net.csdn.blog.chaijunkun.pojo.Depts;
import net.csdn.blog.chaijunkun.pojo.Report;
import net.csdn.blog.chaijunkun.pojo.Students;
@Service
public class ReportServiceImpl implements ReportService {
@Resource
private ObjectDaoService objectDaoService;
@Override
public List<Report> getReport() {
String jpql= String.format("select new %3$s(a.deptId, a.deptName, (select count(*) from %2$s b where b.deptId= a.deptId) as totalCount) from %1$s a",
Depts.class.getName(),
Students.class.getName(),
Report.class.getName());
EntityManager entityManager= objectDaoService.getEntityManager();
//
TypedQuery<Report> reportTypedQuery= entityManager.createQuery(jpql, Report.class);
// jpql (?1 ?2 ?3....),
//reportTypedQuery.setParameter(1, params);
List<Report> reports= reportTypedQuery.getResultList();
return reports;
}
}
위의 코드에서 우리는 JPQL의 보기 조회 문장을 구성했다.가장 중요한 것은 최초의 select 뒤에 새로운 대상을 내놓는 것이다.그리고 우리가 조회한 결과를 보기 대상의 구조 함수를 통해 각 속성에 주입한다.통계로 생성된 필드는 보기 대상의 속성 이름과 동일하게 유지하기 위해 as로 이름을 바꾸는 것이 좋습니다.이렇게 해서 우리는 보기 데이터를 얻었다.다음은 이 목록을 훑어보도록 하겠습니다. 조작이 매우 편리합니다.또 Apress출판사에서 출판한'Pro JPA 2 Mastering the Java trade Persistence API'를 추천합니다. 이 책은 JPA의 관련 기술을 상세하게 소개해 실용적입니다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
JPA + QueryDSL 계층형 댓글, 대댓글 구현(2)이번엔 전편에 이어서 계층형 댓글, 대댓글을 다시 리팩토링해볼 예정이다. 이전 게시글에서는 계층형 댓글, 대댓글을 구현은 되었지만 N+1 문제가 있었다. 이번에는 그 N+1 문제를 해결해 볼 것이다. 위의 로직은 이...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.