2016년 8월 29일 월요일
2016년 8월 26일 금요일
2016년 8월 23일 화요일
2016년 8월 21일 일요일
2016년 8월 19일 금요일
2016년 8월 18일 목요일
탑크리에듀교육센터★기업위탁/단체교육안내_자바/스프링/JPA교육,닷넷,C#,ADO.NET교육, AngularJS/Node.JS교육,안드로이드교육,ETL/SQL/힌트튜닝교육
탑크리에듀교육센터(topcredu.co.kr) 기업위탁/단체교육안내_자바/스프링/JPA교육,닷넷,C#,ADO.NET교육, An…
FSP(이종철) 0 6 08.17 12:58
탑크리에듀교육센터(topcredu.co.kr) 기업위탁/단체교육안내_자바/스프링/JPA교육,닷넷,C#,ADO.NET교육, AngularJS/Node.JS교육,안드로이드교육,ETL/SQL/힌트튜닝교육
※ 탑크리에듀 기업위탁교육 과정안내
기업에 최적화된 맞춤형 실무위탁(파견) 교육 제공
실무현장에서 가능한 장소 및 시간에 최고의 실무강사를 통해 핵심요소기술을 최단시간에 맞춤형 교육을 제공받을 수 있습니다.
빠르게 변하는 최신 고급기술을 실무전문 강사를 통해 교육 받으실 수 있습니다.
IT업계는 나날이 발빠르게 변화하고 있습니다. 실무현장에서는 그 트렌드에 맞춰 준비할 시간이 부족하기 마련입니다. 탑크리에듀교육센터에서는 의뢰업체의 분야에 맞는 최신기술교육과 교육 대상자의 수준에 맞게 난이도를 조절하여 개인의 SKILL UP과 기업의 업무영역 확대에 도움을 드릴 것 입니다.
※ 주요특징
1. 실무위주의 개발자 중심 교육으로 실무 Tip 및 사례 중심의 교육 입니다.2. 과정별 미니 Project 또는 과제로 개발 능력을 평가 받습니다.
3. 실무에서 필요한 개발 사항에 지원 받습니다.
4. 이론 중심이 아닌 실습, 실무 중심의 교육 입니다.
2014년도 개강과정
- Spring, MyBatis, Hibernate 실무과정
- PL/SQL, ORACLE HINT TUNING
- SQL기초에서 Schema Object 까지
- 자바기초에서 JDBC Servlet/JSP까지
- 안드로이드 개발자과정
- C#4.0 WinForm ADO.NET 프로그래밍
- 개발자를 위한 Spring, MyBatis, Hibernate
- 웹퍼블리싱 마스터 (HTML5, CSS3, JavaScript, jQuery
- JAVA JDBS Servlet JSP
- 오라클자바 실무 개발자 신입과정
- 자바기초에서 JSP, Ajax, jQuery, Spring3.2, MyBatis 까지
- HTML5, CSS3, Ajax, jQuery 마스터과정
- Spring 3.X, MyBatis, Hibernate 실무과정
- C#4.0 ADO.NET Network 프로그래밍
- SQL기초에서 Schema Object, PLSQL 힌트튜닝
- 자바웹개발 기초과정(JAVA, JDBC, JSP, Servlet, Ajax)
- C# ASP.NET마스터
- SQL초보에서 실전전문가 까지
- 오라클자바 개발잘하는 신입뽑기 2개월
- 오라클&자바웹스프링 신입과정 3주
- 닷넷마스터과정
- Android App 개발과정
- JAVA&WEB 프레임워크 실무과정
- 자바초보에서 안드로이드까지
- JAVA Network&WEB&Framework
- SQL기초에서 실무까지
- Spring, MyBatis, Hibernate 개발자과정
- C#, ASP.NET 마스터
- Spring3.X, MyBatis, Hibernate 실무과정
- 자바&웹프레임워크 실무과정
- SQL기초에서 실무까지
- 자바초보에서 안드로이드까지
- JAVA&WEB 프레임워크 실무과정
- JAVA, Network & WEB & Framework 과정
2014년도 총 개강현황 : 54개 과정 개강
2013년도 개강과정
- SQL초보에서 실전전문가까지
- 자바기초에서 Ajax,Jquery,Struts2, Spring까지
- C#/.NET초보에서 전문가까지
- 채용자확정교육 14기
- 안드로이드 초보에서 전문가까지
- C언어프로그래밍 개발과정
- C#/.NET초보에서 전문가까지
- 채용자확정교육 15기
- C#, ASP, .NET 마스터
- JAVA기초에서 WEB&FRAMEWORK
- 자바웹&프레임워크실무과정
- Spring3.x, MyBatis, Hibernate 실무과정
- 자바기초에서 JDBC, Servlet/JSP까지
- 웹퍼블리싱마스터
- PL/SQL, ORACLE HINT TUNING
- 오라클자바 실무개발자 신입과정
- Spring Framework, MyBatis, Hibernate 실무과정
- C#, ASP, .NET마스터 개발자
- Spring3.x, MyBatis, Hibernate 실무과정
- 자바초보에서 안드로이드까지
- iphone 하이브리드 앱 개발 실무과정
- JAVA&WEB 프레임워크 실무과정
2013년도 총 개강현황 : 40개 과정 개강
2016년 8월 17일 수요일
2016년 8월 16일 화요일
2016년 8월 12일 금요일
(방학특강)[JPA/Spring Data JPA]SQL쿼리방법정리,예문(JPQL,Querydsl,Criteria Query,NativeS… - 스프링실무교육학원
(방학특강)[JPA/Spring Data JPA]SQL쿼리방법정리,예문(JPQL,Querydsl,Criteria Query,NativeSQL,Query Method,@Query), JPA 및 Spring Data JPA에서 쿼리 하는 방법에 대해 그림으로 요약했으며 간단히 예문을 추가 했습니다. - 스프링실무교육학원
참조하세요~ 열공하시구요,
감사합니다.
참조하세요~ 열공하시구요,
감사합니다.
(방학특강)[JPA강좌]스프링부트,Data JPA, MVC 심플 예제입니다. - 스프링실무교육학원
(방학특강)[JPA강좌]스프링부트,Data JPA, MVC 심플
예제입니다. - 스프링실무교육학원
Spring Data JPA Simple Example
n Spring Boot, WEB MVC, Spring Data JPA, Maria
DB를 이용하여 간단히 예제를 만들어 보자.
첨부파일 참조하세요~
감사합니다.
(방학특강)[JPA팁] @ManyToMany 설정, 삭제 작업 시 의도치 않은 테이블 정보가 삭제 될 때-송석원 - 스프링실무교육학원
(방학특강)[JPA팁] @ManyToMany 설정, 삭제 작업 시 의도치 않은 테이블 정보가 삭제 될 때-송석원 - 스프링실무교육학원
이를 처리하기 위해 @ManyToMany 애노테이션을 사용하고 있다.
이에 따라 테이블 3개가 만들어진다.
User - User_Authority - Authority
증상
User 정보를 삭제 시 User, User_Authority 정보가 삭제된다. 이는 원하는 결과다.
그런데, 원하지 않는 Authority 정보도 삭제가 되고 있다. 이러면 큰 사고다.
원인
@ManyToMany 설저에 CascadeType.ALL을 설정하고 있다.
그에 따라 삭제시 캐스케이드 작업이 발생한다.
User --> User_Authority --> Authority
해결
이를 CascadeType.PERSIST,CascadeType.MERGE 으로 변경한다.
정보의 수정은 사실 PERSIST로 충분하다. 지나친 설정은 피하자.
추가로, User, Authority 클래스 모두에 @JoinTable설정을 한다.
User
--------------------
@ManyToMany(fetch=FetchType.EAGER, cascade={CascadeType.PERSIST,CascadeType.MERGE})
@JoinTable(name = "UserAuthority",
joinColumns = @JoinColumn(name = "user_id"),
inverseJoinColumns = @JoinColumn(name = "authority_id"))
private Set<Authority> authorities = new HashSet<>();
Authority
--------------------
@ManyToMany(fetch=FetchType.LAZY, cascade={CascadeType.PERSIST,CascadeType.MERGE})
@JoinTable(name = "UserAuthority",
joinColumns = @JoinColumn(name = "authority_id"),
inverseJoinColumns = @JoinColumn(name = "user_id"))
private Set<User> users = new HashSet<>();
결론
해결책은 비 연관관계 주인이었던 엔티티도 연관관계 주인으로 만드는 것이다.
캐스케이드 작동
(방학특강)[JPA,Querydsl강좌]스프링에서Querydsl,SQLQueryFactory생성하기 - 스프링실무교육학원
(방학특강)[JPA,Querydsl강좌]스프링에서Querydsl,SQLQueryFactory생성하기
- 스프링실무교육학원
@Autowired
DataSource dataSource;
@Transactional()
public void run(String... args) {
/////////
}
public PlatformTransactionManager transactionManager() {
return new DataSourceTransactionManager(dataSource);
}
public Configuration querydslConfiguration() {
SQLTemplates templates = MySQLTemplates.builder().build();
Configuration configuration = new Configuration(templates);
configuration.setExceptionTranslator(new SpringExceptionTranslator());
return configuration;
}
public SQLQueryFactory queryFactory() {
Provider<Connection> provider = new SpringConnectionProvider(dataSource);
return new SQLQueryFactory(querydslConfiguration(), provider);
}
@Autowired
DataSource dataSource;
@Transactional()
public void run(String... args) {
/////////
}
public PlatformTransactionManager transactionManager() {
return new DataSourceTransactionManager(dataSource);
}
public Configuration querydslConfiguration() {
SQLTemplates templates = MySQLTemplates.builder().build();
Configuration configuration = new Configuration(templates);
configuration.setExceptionTranslator(new SpringExceptionTranslator());
return configuration;
}
public SQLQueryFactory queryFactory() {
Provider<Connection> provider = new SpringConnectionProvider(dataSource);
return new SQLQueryFactory(querydslConfiguration(), provider);
}
(방학특강)JPA,Querydsl4.X강좌 – 서브쿼리, JPAExpressions(예문에서 JPA__EXPRESSION__s… - 스프링실무교육학원
(방학특강)JPA,Querydsl4.X강좌
– 서브쿼리, JPAExpressions - 스프링실무교육학원
서브 쿼리
Sub Query는 JPAExpressions를 만들어서 사용한다.
/* Emp 테이블에서 최대급여 사원 추출, 서브쿼리 */
public List<Emp> selectEmpMaxSal() {
QEmp e = new QEmp("e");
List<Emp> emps = queryFactory.selectFrom(emp)
.where(emp.sal.eq(
JPAExpressions.select(e.sal.max()).from(e)))
.fetch();
return emps;
}
/* 부서별 최대급여받는 사원 추출 , 서브쿼리 */
public List<Emp> selectEmpMaxSalOfDept() {
QEmp e = new QEmp("e");
List<Emp> emps = queryFactory.selectFrom(emp)
.where(emp.sal.eq(
JPAExpressions
.select(e.sal.max()).from(e) .where(emp.dept.deptno.eq(e.dept.deptno))
))
.fetch();
return emps;
}
/* 자신이 속한 부서의 평균급여보다 급여가 많은 사원추출 ,서브쿼리 */
public List<Emp> selectEmpGreaterThanAvgSal() {
QEmp e = new QEmp("e");
List<Emp> emps = queryFactory.selectFrom(emp)
.where(emp.sal.gt(
JPAExpressions
.select(e.sal.avg()).from(e) .where(emp.dept.deptno.eq(e.dept.deptno))
))
.fetch();
return emps;
}
/* 입력받은 사원과 급여가 같은 사원추출 , 서브쿼리 */
/* 입력받은 사원은 출력안함 */
public List<Emp> selectEmpEqualsEmpno(Long empno) {
QEmp e = new QEmp("e");
List<Emp> emps = queryFactory.selectFrom(emp)
.where(emp.sal.eq(
JPAExpressions
.select(e.sal).from(e) .where(e.empno.eq(empno))
))
.where(emp.empno.ne(empno))
.fetch();
return emps;
}
/* Emp 테이블에서 급여상위 3명 추출 , 서브쿼리 */
public List<Emp> selectEmpMaxSalTop3() {
List<Emp> emps = queryFactory.selectFrom(emp)
.orderBy(emp.sal.desc())
.limit(3)
.fetch();
return emps;
}
/* Dept 테이블에서 사원이 한명이라도 존재하는 부서명추출, 서브쿼리 */
public List<String> selectDeptExistsEmp() {
List<String> depts = queryFactory.select(dept.dname).from(dept)
.where(JPAExpressions
.selectFrom(emp)
.where(emp.dept.deptno.eq(dept.deptno)).exists()
)
.fetch();
return depts;
}
서브 쿼리
Sub Query는 JPAExpressions를 만들어서 사용한다.
/* Emp 테이블에서 최대급여 사원 추출, 서브쿼리 */
public List<Emp> selectEmpMaxSal() {
QEmp e = new QEmp("e");
List<Emp> emps = queryFactory.selectFrom(emp)
.where(emp.sal.eq(
JPAExpressions.select(e.sal.max()).from(e)))
.fetch();
return emps;
}
/* 부서별 최대급여받는 사원 추출 , 서브쿼리 */
public List<Emp> selectEmpMaxSalOfDept() {
QEmp e = new QEmp("e");
List<Emp> emps = queryFactory.selectFrom(emp)
.where(emp.sal.eq(
JPAExpressions
.select(e.sal.max()).from(e) .where(emp.dept.deptno.eq(e.dept.deptno))
))
.fetch();
return emps;
}
/* 자신이 속한 부서의 평균급여보다 급여가 많은 사원추출 ,서브쿼리 */
public List<Emp> selectEmpGreaterThanAvgSal() {
QEmp e = new QEmp("e");
List<Emp> emps = queryFactory.selectFrom(emp)
.where(emp.sal.gt(
JPAExpressions
.select(e.sal.avg()).from(e) .where(emp.dept.deptno.eq(e.dept.deptno))
))
.fetch();
return emps;
}
/* 입력받은 사원과 급여가 같은 사원추출 , 서브쿼리 */
/* 입력받은 사원은 출력안함 */
public List<Emp> selectEmpEqualsEmpno(Long empno) {
QEmp e = new QEmp("e");
List<Emp> emps = queryFactory.selectFrom(emp)
.where(emp.sal.eq(
JPAExpressions
.select(e.sal).from(e) .where(e.empno.eq(empno))
))
.where(emp.empno.ne(empno))
.fetch();
return emps;
}
/* Emp 테이블에서 급여상위 3명 추출 , 서브쿼리 */
public List<Emp> selectEmpMaxSalTop3() {
List<Emp> emps = queryFactory.selectFrom(emp)
.orderBy(emp.sal.desc())
.limit(3)
.fetch();
return emps;
}
/* Dept 테이블에서 사원이 한명이라도 존재하는 부서명추출, 서브쿼리 */
public List<String> selectDeptExistsEmp() {
List<String> depts = queryFactory.select(dept.dname).from(dept)
.where(JPAExpressions
.selectFrom(emp)
.where(emp.dept.deptno.eq(dept.deptno)).exists()
)
.fetch();
return depts;
}
(방학특강)JPA,QueryDSL4.X강좌[그룹핑, 페이징 및 정렬, 조인, orderBy, groupBy, paging, join] - 스프링실무교육학원
(방학특강)JPA,QueryDSL4.X강좌[그룹핑, 페이징 및 정렬, 조인, orderBy, groupBy, paging,
join] - 스프링실무교육학원
첨부 파일
참조하세요.
(방학특강)JPA,QueryDSL4.X강좌 – 프로젝션(Projection)과 결과반환(예문에서 JPA__EXPRESSION_… - 스프링실무교육학원
(방학특강)JPA,QueryDSL4.X강좌
– 프로젝션(Projection)과 결과반환 - 스프링실무교육학원
프로젝션 과 결과반환
조회를 원하는 SELECT의 결과대상 칼럼을 지정하는 것을 프로젝션(Projection)이라 한다.
//단일 칼럼
/* Dept 테이블에서 사원이 한명이라도 존재하는 부서명추출, 서브쿼리 */
public List<String> selectDeptExistsEmp() {
List<String> depts = queryFactory.select(dept.dname).from(dept)
.where(JPAExpressions
.selectFrom(emp)
.where(emp.dept.deptno.eq(dept.deptno)).exists()
)
.fetch();
return depts;
}
// 여러 칼럼의 값을 SELECT 하는 경우
// com.querydsl.core.Tuple을 이용하고, 조회는 get() 메소드를 이용하면 된다.
/* Emp 테이블에서 입력받은 부서원 이름 및 부서명을 추출하는데 Dept 테이블과 조인
부서코드를 안가지는 사원은 추출되지 않는다 */
public List<Tuple> selectEmpEnameDnameJoinDept(Long deptno) {
List<Tuple> emps = queryFactory
.select(emp.ename, dept.dname)
.from(emp)
.innerJoin(emp.dept, dept)
.where(emp.dept.deptno.eq(deptno))
.fetch();
return emps;
}
결과를 받는쪽에서는 다음과 같이 Map을 이용하면 된다.
Map<String, String> m = new HashMap<String, String>();
QEmp emp = QEmp.emp;
List<Tuple> result = empService.selectEnameJobByEmpno(empno);
for (Tuple row : result) {
m.put(row.get(emp.ename), row.get(emp.job));
}
프로젝션 과 결과반환
조회를 원하는 SELECT의 결과대상 칼럼을 지정하는 것을 프로젝션(Projection)이라 한다.
//단일 칼럼
/* Dept 테이블에서 사원이 한명이라도 존재하는 부서명추출, 서브쿼리 */
public List<String> selectDeptExistsEmp() {
List<String> depts = queryFactory.select(dept.dname).from(dept)
.where(JPAExpressions
.selectFrom(emp)
.where(emp.dept.deptno.eq(dept.deptno)).exists()
)
.fetch();
return depts;
}
// 여러 칼럼의 값을 SELECT 하는 경우
// com.querydsl.core.Tuple을 이용하고, 조회는 get() 메소드를 이용하면 된다.
/* Emp 테이블에서 입력받은 부서원 이름 및 부서명을 추출하는데 Dept 테이블과 조인
부서코드를 안가지는 사원은 추출되지 않는다 */
public List<Tuple> selectEmpEnameDnameJoinDept(Long deptno) {
List<Tuple> emps = queryFactory
.select(emp.ename, dept.dname)
.from(emp)
.innerJoin(emp.dept, dept)
.where(emp.dept.deptno.eq(deptno))
.fetch();
return emps;
}
결과를 받는쪽에서는 다음과 같이 Map을 이용하면 된다.
Map<String, String> m = new HashMap<String, String>();
QEmp emp = QEmp.emp;
List<Tuple> result = empService.selectEnameJobByEmpno(empno);
for (Tuple row : result) {
m.put(row.get(emp.ename), row.get(emp.job));
}
(방학특강)JPA,QueryDSL4.X강좌 –쿼리결과를 특정빈에 담기(Bean population) - 스프링실무교육학원
(방학특강)JPA,QueryDSL4.X강좌 –쿼리결과를 특정빈에 담기(Bean population) - 스프링실무교육학원
쿼리 결과를 엔티티가 아닌 특정한 자바객체(DTO, VO)로 받고 싶은 경우 Pjojections를 사용하면 되는데 .bean()을 사용하면 Setter로 값을 채우고 .field()라고 하면 필드(멤버변수)에 직접 접근하여 값을 채우며, .constructor() 라고 하면 생성자를 통해 값을 채운다.
[ename, sal 필드를 갖는 EmpDTO가 있다면]
아래는 Setter를 통해 값을 저장한다.
List<EmpDTO> dtos = query
.select(
Projections.bean(EmpDTO.class, emp.ename, emp.sal))
.fetch();
아래는 필드에 직접 값을 저장한다.
List<EmpDTO> dtos = query
.select(
Projections.fields(EmpDTO.class, emp.ename, emp.sal))
.fetch();
쿼리 결과를 엔티티가 아닌 특정한 자바객체(DTO, VO)로 받고 싶은 경우 Pjojections를 사용하면 되는데 .bean()을 사용하면 Setter로 값을 채우고 .field()라고 하면 필드(멤버변수)에 직접 접근하여 값을 채우며, .constructor() 라고 하면 생성자를 통해 값을 채운다.
[ename, sal 필드를 갖는 EmpDTO가 있다면]
아래는 Setter를 통해 값을 저장한다.
List<EmpDTO> dtos = query
.select(
Projections.bean(EmpDTO.class, emp.ename, emp.sal))
.fetch();
아래는 필드에 직접 값을 저장한다.
List<EmpDTO> dtos = query
.select(
Projections.fields(EmpDTO.class, emp.ename, emp.sal))
.fetch();
(방학특강)[JPA강좌, 엔티티매니저, EntityManager,JPA엔티티] - 스프링실무교육학원
(방학특강)[JPA강좌, 엔티티매니저, EntityManager,JPA엔티티] - 스프링실무교육학원
엔티티 매니저(JPA
Entity Manager)
Ø JPA EntityManagerFactory
n 데이터베이스와의 상호 작용을 위해 EntityManager를 생성하기 위해 사용되는데 엔티티 매니저 팩토리는 애플리케이션 전체에서 딱
한번만 생성하고 공유해서 사용 해야한다.
Ø JPA EntityManager
n 도메인 객체를 테이블로 변환, 엔티티와 관련된 모든 일을 한다.(저장, 조회, 수정, 삭제), DB에서
엔티티를 가져오거나 생성, 삭제, 수정하는 일은 모두 EntityManager를 통해 이루어 진다.
n 엔티티 저장 요청시 엔티티 객체를 생성하여 DB에 저장하며 SQL과
같은 CRUD 오퍼레이션을 제공한다.
n EntityManager의 인스턴스는 영속성 컨텍스트(Persistence Context)를 나타내며 EntityManagerFactory를 통해서 얻는다.
n 트랜잭션 범위 EntityManager : 트랜잭션 기간동안 엔티티는 attach 상태이고 종료 후 자동으로 detach상태가 된다.
n 확장 범위 EntityManager
: 여러 트랜잭션을 걸쳐 라이프 사이클이 지속되며 유상태 세션빈과 함께 사용되며 빈 인스턴스가 살아있는 동안 계속된다. 빈 자체가 제거되거나 EntityManager가 종료되어야 끝난다.
Ø JPA EntityManager Interface
- persist(Object entity) : 엔티티를 DB로 저장
- merge(T entity) : EntityManager의 영속성 컨텍스트로 엔티티를 병합
- remove(Object entity) : DB에서 엔티티를 삭제
- find(Class<T> entityClass, Object primaryKey) : 주키로 엔티티 인스턴스를 찾는다.
- flush() : EntityManager의 영속성 컨텍스트안의 엔티티를 DB와 동기화 한다.
- setFlushMode(FlushModeType flushMode) : EntityManager의 지속성 컨텍스트의 flush 모드를 설정한다.(AUTO, COMMIT)
- getFlushMode() : 현재의 flush 모드를 리턴한다.
- refresh(Object entity) : DB의 엔티티를 리셋
- createQuery(String jpsqString) : JPQL문을 이용하여 동적 질의문 생성
- createNamedQuery(String name) : 질의 인스턴스 생성
- createNativeQuery(String sqlString) : 원시 SQL문을 이용하여 동적 질의 생성
- close() : EntityManager를 종료한다.
- isOpen() : EntityManager의 오픈여부 확인
- getTransaction() : 트랜잭션 객체를 검색한다.
- joinTransaction() : 기존 JTA 트랜잭션 조인을 요청한다.
(방학특강)[JPA란, JPA개요, 퍼시스턴스기술의 변천,JPA강좌]JPA공부많이하세요~ - 스프링실무교육학원
(방학특강)[JPA란, JPA개요, 퍼시스턴스기술의 변천,JPA강좌]JPA공부많이하세요~ - 스프링실무교육학원
JPA 개요
n JAVA는 표준 스펙을 정하고 그 구현을 DB벤더에게 맡기는 JDBC를 통해 최초 영속성 관리를 지원했는데 JDBC는 SQL중심의 트랜잭션 스크립트 방식의 개발을 지원했으며 엔터프라이즈 환경에서 잘 적용되었다.
n JDBC이후 데이터소스를 이용한 커넥션관리, JNDI를 통한 리소스 관리 등으로 변환 발전.
n 1990년대 후반에 등장한 EJB 기술은 JDBC의 트랜잭션 스크립트 방식을 벗어나 자바 객체의 특징을 유지한 채로 퍼시스턴스 기술을 적용할 수 있는 엔티티빈을 소개했다. 하지만 이러한 기술은 JDBC 방식에 비해 성능 오버헤드가 많았으며 시대적 상황상 객체를 정확히 DB에 매핑하지 못하는 어려움도 있었다.
n 이러한 엔티티빈의 대안 기술로 오라클의 TopLink와 같은 퍼시스턴스 프레임워크, 오픈소스로 등장한 POJO 기반의 하이버네이트, 엔터프라이즈 환경에도 사용 가능한 자바 모델 기반의 퍼시스턴스 기술인 JDO(Java Data Object)등이 있다.
n EJB3.0의 등장! EJB의 명성을 찾기 위한 노력의 결과로 EJB 설계 팀은 EJB3.0을 EJB2.X 기술의 상당 부분을 포기하는 한이 있더라도 새로운 모델로 접근하기로 결정하고 새로운 전문가그룹(expert group)의 멤버를 영입했다.
n 초기 EJB 스펙을 설계하는 주도적인 역할에 참여한 사람이 바로 하이버네이트의 창시자이자 그 즈음에 JBoss팀에 차세대 JBoss 서버의 JDO 개발의 책임자로 영입된 개빈 킹(Gavin King)이다. 개빈 킹은 하이버네이트를 통한 POJO 기반의 퍼시스턴스 프레임워크에 대한 기술적인 확신과 경험을 담아 EJB3.0의 엔티티빈 스펙을 완전히 새롭게 구성해 나가기 시작했다.
n EJB3.0 스펙 작업을 하고 있던 전문가 그룹은 엔티티빈, CMP파트를 독립적인 스펙으로 분리 했는데 이는 J2EE WAS를 구매할 때 CMP 엔진은 다른 벤더 제품을 쓸 수도 있다는 뜻이기 때문이다. 즉 따라서 특정 벤더에모든 것을 종속 당할 필요가 없어진 것인데 WebLogic 서버를 사용하면서 엔티티빈 엔진은 하이버네이트 기반의 CMP 엔진을 써도 된다는 것을 뜻하는 것이다.
n 결과적으로 EJB3.0 스펙은 두 가지로 구분이 되었다. 하나는 SessionBean과 MessageDriven Bean이고, 또하나는 EJB3 Java Persistence API(JPA)이다.
n JPA는 스펙이 분리된 후 이름이 엔티티빈에서 JPA로 변경되었고 EJB 엔티티빈의 경량화와 개선에 머무른 것이 아니라 새로운 이름으로 자바의 모든 기술과 환경에서 사용할 수 있는 독립적인 POJO 기반의 퍼시스턴스 프레임워크로 새롭게 시작된 기술로 발전했다.
n JPA(Java Persistence API)는 관계형 데이터베이스(RDB)에 접근하기 위한 표준 ORM 기술을 제공하며, 기존 EJB에서 제공되던 엔터티 빈(Entity Bean)을 대체하는 기술이다.
n JSR-220에서 EJB의 ORM인 EntityBean(3.0)을 JPA로 통합하였고, 자바에서 영속성 관리를 위한 표준 API 이다.
n JPA는 Hibernate, OpenJPA, EclipseLink, TopLink Essentials과 같은 구현체가 있는데 이들의 표준 인터페이스가 바로JPA이다.
n EJB의 엔티티빈 과는 다르게 일반 POJO빈을 이용한 프로그래밍 모델을 제공하며 EJB에 국한되지 않도록 만들었기에 JavaSE, JavaEE 모두에서 사용 가능한 표준 API 이다.
n 자바 객체와 RDB의 테이블을 Mapping하는 방법을 제공하며 어노테이션 및 XML 형태 모두 사용가능하고 자바객체간의 상속관계도 지원한다.
n 잘 이해하고 사용하지 않으면 데이터 손실이 발생할 수 있으며 성능 문제 등이 야기 될 수 있으므로 정확히 이해하고 사용하는 것이 좋다.
n 스프링 프레임워크에서는 Spring Data JPA를 제공하여 JPA기반 Repository를 구현할 수 있도록 지원하고 있다.
n 장점
ü SQL 쿼리구문을 직접 작성할 필요가 없다.
ü 데이터를 객체지향적으로 관리 하므로 프로그래머는 비즈니스 로직에 좀 더 집중 할 수 있고 테이블의 구조가 변경 되는 경우 기존 SQL을 사용하는 방식 보다 변경이 용이하다.
ü DB에 의존적이지 않는 코드 작성이 가능하다. (DB가 바뀌더라도 변경해야 하는 코드가 거의 없으므로 다양한DB에 대해 서비스하는 경우라면 적합하다.)
n 단점
ü 완벽하게 복잡한 쿼리구문을 작성 못할 수도 있다. 물론 이를 위해 Native SQL도 사용가능 하지만 이는 하나의 DB에 의존적인 코드가 될 수 있다.
ü DB모델링을 객체지향적으로 해야 한다. 테이블에서 데이터를 조회하는 것이 아닌 객체에서 조회한다고 생각하고 모델링 해야 한다. 객체지향 및 데이터베이스 양쪽 모두 잘 알고 있어야 한다.
ü 데이터베이스 테이블에 해당하는 도메인 객체 설계와 관계 설정을 이해해야 되고 객체지향 쿼리언어인 JPQL(Java Persistence Query Language) 또는 criteria 쿼리 등도 이해해야 한다.
피드 구독하기:
덧글 (Atom)