JPA : 기본 쿼리 결과 집합을 POJO 클래스 집합으로 변환하는 방법
나는 내 프로젝트에 JPA를 사용하고 있다.
나는 5개의 테이블에서 조인 수술을 해야 하는 문의에 왔다.그래서 나는 다섯 개의 필드를 반환하는 네이티브 쿼리를 만들었다.
이제 결과 객체를 동일한 5개의 문자열을 포함하는 자바 POJO 클래스로 변환하고 싶다.
JPA에서 그 결과를 POJO 객체 리스트에 직접 캐스팅할 수 있는 방법이 있는가?
나는 다음과 같은 해결책에 도달했다.
@NamedNativeQueries({
@NamedNativeQuery(
name = "nativeSQL",
query = "SELECT * FROM Actors",
resultClass = db.Actor.class),
@NamedNativeQuery(
name = "nativeSQL2",
query = "SELECT COUNT(*) FROM Actors",
resultClass = XXXXX) // <--------------- problem
})
이제 여기 resultClass에서 우리는 실제 JPA 엔터티인 클래스를 제공해야 하는가? 아니면 동일한 열 이름을 포함하는 JAVA POJO 클래스로 변환할 수 있는가?
나는 이것에 대한 몇 가지 해결책을 찾았다.
매핑된 엔티티(JPA 2.0) 사용
JPA 2.0을 사용하면 POJO에 네이티브 쿼리를 매핑할 수 없으며, 엔티티로만 할 수 있다.
예를 들어,
Query query = em.createNativeQuery("SELECT name,age FROM jedi_table", Jedi.class);
@SuppressWarnings("unchecked")
List<Jedi> items = (List<Jedi>) query.getResultList();
하지만 이 경우에는Jedi
는 매핑된 엔티티 클래스여야 한다.
여기서 확인되지 않은 경고를 피하기 위한 대안은 명명된 네이티브 쿼리를 사용하는 것이다.따라서 만약 우리가 엔티티에 네이티브 쿼리를 선언한다면
@NamedNativeQuery(
name="jedisQry",
query = "SELECT name,age FROM jedis_table",
resultClass = Jedi.class)
그러면 간단히 다음과 같은 작업을 수행할 수 있다.
TypedQuery<Jedi> query = em.createNamedQuery("jedisQry", Jedi.class);
List<Jedi> items = query.getResultList();
이것은 더 안전하지만, 우리는 여전히 지도화된 실체를 사용하는 것이 제한되어 있다.
수동 매핑
내가 조금 실험한 해결책은 (JPA 2.1이 도착하기 전) 약간의 반사를 이용하여 POJO 생성자에 대한 매핑을 수행하는 것이었다.
public static <T> T map(Class<T> type, Object[] tuple){
List<Class<?>> tupleTypes = new ArrayList<>();
for(Object field : tuple){
tupleTypes.add(field.getClass());
}
try {
Constructor<T> ctor = type.getConstructor(tupleTypes.toArray(new Class<?>[tuple.length]));
return ctor.newInstance(tuple);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
이 방법은 기본적으로 튜플 어레이(원본 쿼리에 의해 반환됨)를 취하여 필드 수와 유형이 동일한 생성자를 찾아 제공된 POJO 클래스에 대해 매핑한다.
그러면 다음과 같은 편리한 방법을 사용할 수 있다.
public static <T> List<T> map(Class<T> type, List<Object[]> records){
List<T> result = new LinkedList<>();
for(Object[] record : records){
result.add(map(type, record));
}
return result;
}
public static <T> List<T> getResultList(Query query, Class<T> type){
@SuppressWarnings("unchecked")
List<Object[]> records = query.getResultList();
return map(type, records);
}
그리고 우리는 이 기법을 간단히 다음과 같이 사용할 수 있다.
Query query = em.createNativeQuery("SELECT name,age FROM jedis_table");
List<Jedi> jedis = getResultList(query, Jedi.class);
@SqlResultSetMapping을 사용한 JPA 2.1
JPA 2.1의 도착과 함께 @SqlResultSetMapping 주석을 사용하여 문제를 해결할 수 있다.
우리는 결과 집합 매핑을 기업 내 어딘가에 선언할 필요가 있다.
@SqlResultSetMapping(name="JediResult", classes = {
@ConstructorResult(targetClass = Jedi.class,
columns = {@ColumnResult(name="name"), @ColumnResult(name="age")})
})
그리고 나서 우리는 다음과 같은 일을 한다.
Query query = em.createNativeQuery("SELECT name,age FROM jedis_table", "JediResult");
@SuppressWarnings("unchecked")
List<Jedi> samples = query.getResultList();
물론, 이 경우에는Jedi
매핑된 엔티티가 될 필요가 없다.일반 POJO가 될 수 있다.
XML 매핑 사용
나는 이 모든 것을 더하는 사람들 중 한 명이다.@SqlResultSetMapping
내 실체는 상당히 침습적이고, 특히 실체 내에서 명명된 질의의 정의를 싫어하기 때문에, 그 대신에 나는 이 모든 것을 나중에 한다.META-INF/orm.xml
파일:
<named-native-query name="GetAllJedi" result-set-mapping="JediMapping">
<query>SELECT name,age FROM jedi_table</query>
</named-native-query>
<sql-result-set-mapping name="JediMapping">
<constructor-result target-class="org.answer.model.Jedi">
<column name="name" class="java.lang.String"/>
<column name="age" class="java.lang.Integer"/>
</constructor-result>
</sql-result-set-mapping>
그리고 내가 아는 해결책은 그것뿐입니다.JPA 2.1을 사용할 수 있다면 마지막 두 가지가 가장 이상적인 방법이다.
JPA는 당신이 당신의 네이티브 쿼리에서 얻는 모든 수익을 엔티티나 사용자 정의 클래스로 매핑할 수 있는 것을 제공한다.
EDIT JPA 1.0은 비엔티 클래스에 대한 매핑을 허용하지 않는다.JPA 2.1에서만 ConstructorResult가 Java 클래스의 반환 값을 매핑하기 위해 추가되었다.
또한, OP가 카운트를 얻는 문제에 대해서는 결과 집합 매핑을 단일 집합으로 정의하기에 충분해야 한다.
응, JPA 2.1로는 쉬워.너는 매우 유용한 주석을 가지고 있다.그것들은 당신의 삶을 단순화시킨다.
먼저 기본 쿼리를 선언하고 결과 집합 매핑(데이터베이스가 POJO에 반환한 데이터 매핑을 정의함)을 실행하십시오.참조할 POJO 클래스를 작성하십시오(단순함을 위해 여기에 포함되지 않음).마지막이지만 중요한 사항: DAO에서 메소드를 만들어 쿼리를 호출하십시오(예:이것은 드롭위저드(1.0.0) 앱에서 나에게 효과가 있었다.
먼저 엔티티 클래스에서 네이티브 쿼리를 선언하십시오.
@NamedNativeQuery (
name = "domain.io.MyClass.myQuery",
query = "Select a.colA, a.colB from Table a",
resultSetMapping = "mappinMyNativeQuery") // must be the same name as in the SqlResultSetMapping declaration
아래에 결과 집합 매핑 선언을 추가할 수 있다.
@SqlResultSetMapping(
name = "mapppinNativeQuery", // same as resultSetMapping above in NativeQuery
classes = {
@ConstructorResult(
targetClass = domain.io.MyMapping.class,
columns = {
@ColumnResult( name = "colA", type = Long.class),
@ColumnResult( name = "colB", type = String.class)
}
)
}
)
나중에 DAO에서 쿼리를 다음과 같이 참조할 수 있다.
public List<domain.io.MyMapping> findAll() {
return (namedQuery("domain.io.MyClass.myQuery").list());
}
바로 그겁니다.
사용한다면Spring-jpa
, 이것은 답과 이 질문에 대한 보충물이다.결함이 있는 경우 이 문제를 수정하십시오.나는 주로 "매핑 결과"를 얻기 위해 세 가지 방법을 사용했다.Object[]
내가 충족해야 할 실질적인 필요성에 근거하여 "포조에게":
- 방법에 내장된 JPA면 충분하다.
- 메소드 빌드된 JPA로는 부족하지만, 맞춤형 JPA
sql
그것과 함께Entity
충분해 전자의 2개는 실패했고, 나는 a를 사용해야 한다.
nativeQuery
예를 들어보자.포조는 다음과 같이 예상하였다.public class Antistealingdto { private String secretKey; private Integer successRate; // GETTERs AND SETTERs public Antistealingdto(String secretKey, Integer successRate) { this.secretKey = secretKey; this.successRate = successRate; } }
방법 1: 포조를 인터페이스로 변경:
public interface Antistealingdto {
String getSecretKey();
Integer getSuccessRate();
}
및 저장소:
interface AntiStealingRepository extends CrudRepository<Antistealing, Long> {
Antistealingdto findById(Long id);
}
방법 2: 리포지토리:
@Query("select new AntistealingDTO(secretKey, successRate) from Antistealing where ....")
Antistealing whatevernamehere(conditions);
참고: POJO 생성자의 파라미터 시퀀스는 POJO 정의와 SQL에서 모두 동일해야 한다.
방법 3: 사용@SqlResultSetMapping
그리고@NamedNativeQuery
에Entity
에드윈 달로조의 대답에 예로써.
처음 두 가지 방법은 사용자 정의된 변환기와 같은 많은 중간 처리기를 호출할 것이다.예를 들어,AntiStealing
a를 규정하다secretKey
지속되기 전에 변환기를 삽입하여 암호화한다.이렇게 하면 처음 두 가지 방법이 변환된 데이터를 다시 반환할 수 있다.secretKey
그건 내가 원하는 게 아니야메소드 3이 컨버터를 극복하고secretKey
저장된 것과 같을 것이다(암호화된 것).
결과를 비엔티(콩/POJO)에 할당하기 위해 언랩 절차를 수행할 수 있다.절차는 다음과 같다.
List<JobDTO> dtoList = entityManager.createNativeQuery(sql)
.setParameter("userId", userId)
.unwrap(org.hibernate.Query.class).setResultTransformer(Transformers.aliasToBean(JobDTO.class)).list();
이 용도는 JPA-Hibernatic 구현을 위한 것이다.
가장 쉬운 방법은 그렇게 투영하는 것이다.쿼리 결과를 인터페이스에 직접 매핑할 수 있으며, SQLResultSetMapping을 사용하는 것보다 구현이 더 쉽다.
예는 다음과 같다.
@Repository
public interface PeopleRepository extends JpaRepository<People, Long> {
@Query(value = "SELECT p.name AS name, COUNT(dp.people_id) AS count " +
"FROM people p INNER JOIN dream_people dp " +
"ON p.id = dp.people_id " +
"WHERE p.user_id = :userId " +
"GROUP BY dp.people_id " +
"ORDER BY p.name", nativeQuery = true)
List<PeopleDTO> findByPeopleAndCountByUserId(@Param("userId") Long userId);
@Query(value = "SELECT p.name AS name, COUNT(dp.people_id) AS count " +
"FROM people p INNER JOIN dream_people dp " +
"ON p.id = dp.people_id " +
"WHERE p.user_id = :userId " +
"GROUP BY dp.people_id " +
"ORDER BY p.name", nativeQuery = true)
Page<PeopleDTO> findByPeopleAndCountByUserId(@Param("userId") Long userId, Pageable pageable);
}
// Interface to which result is projected
public interface PeopleDTO {
String getName();
Long getCount();
}
투영된 인터페이스의 필드는 이 엔터티의 필드와 일치해야 한다.그렇지 않으면 필드 매핑이 중단될 수 있다.
또한 만약 당신이 사용한다면SELECT table.column
표기법은 항상 예시와 같이 엔티티의 이름과 일치하는 별칭을 정의한다.
최대 절전 모드에서는 이 코드를 사용하여 기본 쿼리를 쉽게 매핑할 수 있다.
private List < Map < String, Object >> getNativeQueryResultInMap() {
String mapQueryStr = "SELECT * FROM AB_SERVICE three ";
Query query = em.createNativeQuery(mapQueryStr);
NativeQueryImpl nativeQuery = (NativeQueryImpl) query;
nativeQuery.setResultTransformer(AliasToEntityMapResultTransformer.INSTANCE);
List < Map < String, Object >> result = query.getResultList();
for (Map map: result) {
System.out.println("after request ::: " + map);
}
return result;}
먼저 다음 주석을 선언하십시오.
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface NativeQueryResultEntity {
}
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface NativeQueryResultColumn {
int index();
}
그런 다음 다음과 같이 POJO에 주석을 달으십시오.
@NativeQueryResultEntity
public class ClassX {
@NativeQueryResultColumn(index=0)
private String a;
@NativeQueryResultColumn(index=1)
private String b;
}
그런 다음 주석 프로세서를 작성하십시오.
public class NativeQueryResultsMapper {
private static Logger log = LoggerFactory.getLogger(NativeQueryResultsMapper.class);
public static <T> List<T> map(List<Object[]> objectArrayList, Class<T> genericType) {
List<T> ret = new ArrayList<T>();
List<Field> mappingFields = getNativeQueryResultColumnAnnotatedFields(genericType);
try {
for (Object[] objectArr : objectArrayList) {
T t = genericType.newInstance();
for (int i = 0; i < objectArr.length; i++) {
BeanUtils.setProperty(t, mappingFields.get(i).getName(), objectArr[i]);
}
ret.add(t);
}
} catch (InstantiationException ie) {
log.debug("Cannot instantiate: ", ie);
ret.clear();
} catch (IllegalAccessException iae) {
log.debug("Illegal access: ", iae);
ret.clear();
} catch (InvocationTargetException ite) {
log.debug("Cannot invoke method: ", ite);
ret.clear();
}
return ret;
}
// Get ordered list of fields
private static <T> List<Field> getNativeQueryResultColumnAnnotatedFields(Class<T> genericType) {
Field[] fields = genericType.getDeclaredFields();
List<Field> orderedFields = Arrays.asList(new Field[fields.length]);
for (int i = 0; i < fields.length; i++) {
if (fields[i].isAnnotationPresent(NativeQueryResultColumn.class)) {
NativeQueryResultColumn nqrc = fields[i].getAnnotation(NativeQueryResultColumn.class);
orderedFields.set(nqrc.index(), fields[i]);
}
}
return orderedFields;
}
}
위의 프레임워크를 다음과 같이 사용하십시오.
String sql = "select a,b from x order by a";
Query q = entityManager.createNativeQuery(sql);
List<ClassX> results = NativeQueryResultsMapper.map(q.getResultList(), ClassX.class);
최대 절전 모드 사용:
@Transactional(readOnly=true)
public void accessUser() {
EntityManager em = repo.getEntityManager();
org.hibernate.Session session = em.unwrap(org.hibernate.Session.class);
org.hibernate.SQLQuery q = (org.hibernate.SQLQuery) session.createSQLQuery("SELECT u.username, u.name, u.email, 'blabla' as passe, login_type as loginType FROM users u").addScalar("username", StringType.INSTANCE).addScalar("name", StringType.INSTANCE).addScalar("email", StringType.INSTANCE).addScalar("passe", StringType.INSTANCE).addScalar("loginType", IntegerType.INSTANCE)
.setResultTransformer(Transformers.aliasToBean(User2DTO.class));
List<User2DTO> userList = q.list();
}
ResultSet를 사용한 이전 스타일
@Transactional(readOnly=true)
public void accessUser() {
EntityManager em = this.getEntityManager();
org.hibernate.Session session = em.unwrap(org.hibernate.Session.class);
session.doWork(new Work() {
@Override
public void execute(Connection con) throws SQLException {
try (PreparedStatement stmt = con.prepareStatement(
"SELECT u.username, u.name, u.email, 'blabla' as passe, login_type as loginType FROM users u")) {
ResultSet rs = stmt.executeQuery();
ResultSetMetaData rsmd = rs.getMetaData();
for (int i = 1; i <= rsmd.getColumnCount(); i++) {
System.out.print(rsmd.getColumnName(i) + " (" + rsmd.getColumnTypeName(i) + ") / ");
}
System.out.println("");
while (rs.next()) {
System.out.println("Found username " + rs.getString("USERNAME") + " name " + rs.getString("NAME") + " email " + rs.getString("EMAIL") + " passe " + rs.getString("PASSE") + " email " + rs.getInt("LOGIN_TYPE"));
}
}
}
});
}
우리는 다음과 같은 방법으로 이 문제를 해결했다.
//Add actual table name here in Query
final String sqlQuery = "Select a.* from ACTORS a"
// add your entity manager here
Query query = entityManager.createNativeQuery(sqlQuery,Actors.class);
//List contains the mapped entity data.
List<Actors> list = (List<Actors>) query.getResultList();
다른 사람들이 이미 가능한 모든 해결책을 언급했기 때문에, 나는 나의 해결 방법을 공유하고 있다.
와의 내 처지에서는.Postgres 9.4
, 작업하는 동안Jackson
,
//Convert it to named native query.
List<String> list = em.createNativeQuery("select cast(array_to_json(array_agg(row_to_json(a))) as text) from myschema.actors a")
.getResultList();
List<ActorProxy> map = new ObjectMapper().readValue(list.get(0), new TypeReference<List<ActorProxy>>() {});
나는 네가 다른 데이터베이스에서도 같은 것을 찾을 수 있다고 확신한다.
또한 FYI, JPA 2.0 기본 쿼리 결과를 맵으로 표시
이것이 여기에 맞는지 확실하지 않지만, 비슷한 질문이 있었고 간단한 해결책/예:
private EntityManager entityManager;
...
final String sql = " SELECT * FROM STORE "; // select from the table STORE
final Query sqlQuery = entityManager.createNativeQuery(sql, Store.class);
@SuppressWarnings("unchecked")
List<Store> results = (List<Store>) sqlQuery.getResultList();
나의 경우 스트링스(Strings)에 정의된 SQL 부품을 다른 곳에서 사용해야 했기 때문에 NamedNativeQuery(NamedNativeQuery)만 사용할 수는 없었다.
복잡한 SQLResultSetMapping을 사용하지 않고 기본 쿼리에서 결과를 검색하기 위해 POJO를 유사 엔터티로 사용하는 경우 아래 예제를 참조하십시오.당신의 POJO에 있는 베어 @Enity와 더미 @Id 두 개의 주석만 있으면 된다. @Id는 당신이 선택한 어떤 필드에서도 사용될 수 있다. @Id 필드는 중복 키를 가질 수 있지만 null 값은 가질 수 없다.
@Enity는 어떠한 물리적 테이블에도 매핑되지 않기 때문에, 이 POJO를 사이비 실체라고 부른다.
환경: 일식셀링크 2.5.0-RC1, jpa-2.1.0, mysql-connector-java-5.1.14
당신은 여기서 완전한 maven 프로젝트를 다운로드 할 수 있다.
기본 쿼리는 mysql 샘플 직원 db http://dev.mysql.com/doc/employee/en/employees-installation.html을 기반으로 함
persistence.xml
<?xml version="1.0" encoding="UTF-8"?><persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.1"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
<persistence-unit name="jpa-mysql" transaction-type="RESOURCE_LOCAL">
<class>org.moonwave.jpa.model.pojo.Employee</class>
<properties>
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/employees" />
<property name="javax.persistence.jdbc.user" value="user" />
<property name="javax.persistence.jdbc.password" value="***" />
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
</properties>
</persistence-unit>
직원.자바를 만들다
package org.moonwave.jpa.model.pojo;
@Entity
public class Employee {
@Id
protected Long empNo;
protected String firstName;
protected String lastName;
protected String title;
public Long getEmpNo() {
return empNo;
}
public void setEmpNo(Long empNo) {
this.empNo = empNo;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("empNo: ").append(empNo);
sb.append(", firstName: ").append(firstName);
sb.append(", lastName: ").append(lastName);
sb.append(", title: ").append(title);
return sb.toString();
}
}
직원네이티브쿼리.java
public class EmployeeNativeQuery {
private EntityManager em;
private EntityManagerFactory emf;
public void setUp() throws Exception {
emf=Persistence.createEntityManagerFactory("jpa-mysql");
em=emf.createEntityManager();
}
public void tearDown()throws Exception {
em.close();
emf.close();
}
@SuppressWarnings("unchecked")
public void query() {
Query query = em.createNativeQuery("select e.emp_no as empNo, e.first_name as firstName, e.last_name as lastName," +
"t.title from employees e join titles t on e.emp_no = t.emp_no", Employee.class);
query.setMaxResults(30);
List<Employee> list = (List<Employee>) query.getResultList();
int i = 0;
for (Object emp : list) {
System.out.println(++i + ": " + emp.toString());
}
}
public static void main( String[] args ) {
EmployeeNativeQuery test = new EmployeeNativeQuery();
try {
test.setUp();
test.query();
test.tearDown();
} catch (Exception e) {
System.out.println(e);
}
}
}
만약 당신이 Spring을 사용하고 있다면, 당신은 사용할 수 있다.org.springframework.jdbc.core.RowMapper
예를 들면 다음과 같다.
public List query(String objectType, String namedQuery)
{
String rowMapper = objectType + "RowMapper";
// then by reflection you can instantiate and use. The RowMapper classes need to follow the naming specific convention to follow such implementation.
}
최대 절전 모드 사용:
@Transactional(readOnly=true)
public void accessUser() {
EntityManager em = repo.getEntityManager();
org.hibernate.Session session = em.unwrap(org.hibernate.Session.class);
org.hibernate.SQLQuery q = (org.hibernate.SQLQuery) session.createSQLQuery("SELECT u.username, u.name, u.email, 'blabla' as passe, login_type as loginType FROM users u")
.addScalar("username", StringType.INSTANCE).addScalar("name", StringType.INSTANCE)
.addScalar("email", StringType.INSTANCE).addScalar("passe", StringType.INSTANCE)
.addScalar("loginType", IntegerType.INSTANCE)
.setResultTransformer(Transformers.aliasToBean(User2DTO.class));
List<User2DTO> userList = q.list();
}
위의 답변에서 언급된 바와 같이 나는 많은 것을 시도했다.SQLmapper는 그것을 어디에 두어야 할지 매우 혼란스러웠다.관리되지 않은 POJO는 문제일 뿐이었다.나는 다양한 방법을 시도하고 있었고 내가 그것을 작동하게 한 쉬운 방법은 평소와 같았다.나는 동면-jpa-2.1을 사용하고 있다.
List<TestInfo> testInfoList = factory.createNativeQuery(QueryConstants.RUNNING_TEST_INFO_QUERY)
.getResultList();
유일하게 주의해야 할 것은 POJO가 쿼리의 그것과 같은 멤버 변수 이름(모두 소문자)을 가지고 있다는 점이었다.그리고 보아하니 JPQL의 TypeQueries에서처럼 나는 질의와 함께 대상 클래스에 말할 필요도 없었다.
테스트인포클래스
@Setter
@Getter
@NoArgsConstructor
@ToString
public class TestInfo {
private String emailid;
private Long testcount;
public TestInfo(String emailId, Long testCount) {
super();
this.emailid = emailId;
this.testcount = testCount;
}
}
불변의 엔터티 a.k.와 같이 "데이터베이스 뷰"를 사용하는 것은 이 경우에 매우 쉽다.
정규 도면요소
@Entity
@Table(name = "people")
data class Person(
@Id
val id: Long = -1,
val firstName: String = "",
val lastName: String? = null
)
도면요소 유사 보기
@Entity
@Immutable
@Subselect("""
select
p.id,
concat(p.first_name, ' ', p.last_name) as full_name
from people p
""")
data class PersonMin(
@Id
val id: Long,
val fullName: String,
)
모든 리포지토리에서 다음과 같은 쿼리 기능/메소드를 생성할 수 있다.
@Query(value = "select p from PersonMin p")
fun findPeopleMinimum(pageable: Pageable): Page<PersonMin>
질의가 너무 복잡하지 않다면 이런 일을 할 수 있다.나의 경우 H2 FT_Search 결과 쿼리를 사용하여 다른 쿼리를 만들어야 했다.
var ftSearchQuery = "SELECT * FROM FT_SEARCH(\'something\', 0, 0)";
List<Object[]> results = query.getResultList();
List<Model> models = new ArrayList<>();
for (Object[] result : results) {
var newQuery = "SELECT * FROM " + (String) result[0];
models.addAll(entityManager.createNativeQuery(newQuery, Model.class).getResultList());
}
아마도 이것을 하는 더 깨끗한 방법이 있을 것이다.
SQL 쿼리를 POJO 클래스 모음으로 변환하는 간단한 방법 ,
Query query = getCurrentSession().createSQLQuery(sqlQuery).addEntity(Actors.class);
List<Actors> list = (List<Actors>) query.list();
return list;
사용하다DTO Design Pattern
에 사용되었다.EJB 2.0
컨테이너를 관리했다.DTO Design Pattern
이 문제를 해결하기 위해 사용된다.하지만 응용 프로그램이 개발되면 지금 사용할 수 있다.Server Side
그리고Client Side
따로따로DTO
에 사용된다.Server side
합격/반품을 원하지 않다Entity
에 주석을 달고.Client Side
.
DTO 예제:
퍼스널리티.자바를 만들다
@Entity
public class PersonEntity {
@Id
private String id;
private String address;
public PersonEntity(){
}
public PersonEntity(String id, String address) {
this.id = id;
this.address = address;
}
//getter and setter
}
PersonDTO.java
public class PersonDTO {
private String id;
private String address;
public PersonDTO() {
}
public PersonDTO(String id, String address) {
this.id = id;
this.address = address;
}
//getter and setter
}
DTOBuilder.java
public class DTOBuilder() {
public static PersonDTO buildPersonDTO(PersonEntity person) {
return new PersonDTO(person.getId(). person.getAddress());
}
}
EntityBuilder.java <-- 필요할 것 같다.
public class EntityBuilder() {
public static PersonEntity buildPersonEntity(PersonDTO person) {
return new PersonEntity(person.getId(). person.getAddress());
}
}
'programing' 카테고리의 다른 글
Vuex 스토어가 Vue-roouter에서 정의되지 않음 (0) | 2022.05.22 |
---|---|
Java JAR 파일에서 리소스에 대한 경로를 가져오는 방법 (0) | 2022.05.22 |
일반 자바에서 HTML 기호를 이스케이프하는 방법은? (0) | 2022.05.22 |
왜 argc가 'int'('부호화되지 않은 int'가 아닌) (0) | 2022.05.22 |
파일을 문자열로 읽는 가장 간단한 방법은? (0) | 2022.05.22 |