Spring에서 Hibernate4로 MySQL 연동하는 예제
pom.xml에 하이버네이트 추가
1 2 3 4 5 | < dependency > < groupId >org.hibernate</ groupId > < artifactId >hibernate-core</ artifactId > < version >4.3.1.Final</ version > </ dependency > |
이클립스에 하이버네이트 플러그인 설치
이클립스->Help->Install New Software->Work with : http://download.jboss.org/jbosstools/updates/stable 주소 입력
Hibernate tool를 검색해 설치
pom.xml에 mysql 연결 라이브러리 추가
1 2 3 4 5 | < dependency > < groupId >mysql</ groupId > < artifactId >mysql-connector-java</ artifactId > < version >5.1.28</ version > </ dependency > |
디비 커넥션 풀 관리자 소스
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | import org.hibernate.HibernateException; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.boot.registry.StandardServiceRegistryBuilder; import org.hibernate.cfg.Configuration; import org.hibernate.service.ServiceRegistry; public class HibernateUtil { private static final SessionFactory sessionFactory; private static final ServiceRegistry serviceRegistry; static { try { // Create the SessionFactory from hibernate.cfg.xml Configuration configuration = new Configuration(); configuration.configure( "hibernate.cfg.xml" ); serviceRegistry = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()).build(); sessionFactory = configuration.buildSessionFactory(serviceRegistry); } catch (Throwable ex) { // Make sure you log the exception, as it might be swallowed System.err.println( "Initial SessionFactory creation failed." + ex); throw new ExceptionInInitializerError(ex); } } private static final ThreadLocal<Session> session = new ThreadLocal<Session>(); public static Session getCurrentSession() throws HibernateException { Session s = session.get(); // Open a new Session, if this thread has none yet if (s == null ) { s = sessionFactory.openSession(); // Store it in the ThreadLocal variable session.set(s); } return s; } public static void closeSession() throws HibernateException { Session s = (Session) session.get(); if (s != null ) s.close(); session.set( null ); } } |
애노테이션을 사용해 디비테이블과 연동될 클래스 정의
JPA 애노테이션을 사용하므로, javax.persistence.* package를 사용해야 한다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.Table; import javax.validation.constraints.NotNull; @Entity @Table (name = "mytable" ) public class MyTestTable { @Id @GeneratedValue private Integer id; @NotNull @Column (updatable= false ) private String name; public Integer getId() { return id; } public void setId(Integer id) { this .id = id; } public String getName() { return name; } public void setName(String name) { this .name = name; } } |
MVC 컨틀롤러에 테스트 코드 추가
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | @RequestMapping (value= "/dbtest1" ) public String dbtest1(){ Session session = null ; try { // 세션 열기 session = HibernateUtil.getCurrentSession(); MyTestTable entity = (MyTestTable)session.get(MyTestTable. class , 1 ); logger.info( "Welcome dbtest user {}." ,entity.getName()); } catch (HibernateException e) { e.printStackTrace(); } finally { // 세션 닫기 HibernateUtil.closeSession(); } return "home" ; } |
테스트 코드를 실행하면, 다음과 같은 메시지가 콘솔에 찍혀 있다.
최신버전에서는 dtd의 위치가 변경되었기 때문에
제시된 위치로 hibernate.cfg.xml에 .dtd 위치를 변경
1 2 3 4 | <? xml version = "1.0" encoding = "UTF-8" ?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" |
- Using Hibernate built-in connection pool (not for production use!)
내장된 커넥션 풀을 사용했다는 메시지이고, 개선된 커넥션 풀을 사용하면 해결된다.
하이버네이트용 커넥션 풀
c3p0 |
|
Apache DBCP |
|
Proxool |
여기서는 c3p0를 사용하여 connection pool설정한다.
hibernate.cfg.xml에 추가
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | < session-factory > ... < property name = "connection.provider_class" >org.hibernate.connection.C3P0ConnectionProvider</ property > < property name = "hibernate.c3p0.acquire_increment" >1</ property > < property name = "hibernate.c3p0.idle_test_period" >60</ property > < property name = "hibernate.c3p0.min_size" >1</ property > < property name = "hibernate.c3p0.max_size" >2</ property > < property name = "hibernate.c3p0.max_statements" >50</ property > < property name = "hibernate.c3p0.timeout" >0</ property > < property name = "hibernate.c3p0.acquireRetryAttempts" >1</ property > < property name = "hibernate.c3p0.acquireRetryDelay" >250</ property > < property name = "hibernate.show_sql" >true</ property > < property name = "hibernate.use_sql_comments" >true</ property > < property name = "hibernate.transaction.factory_class" >org.hibernate.transaction.JDBCTransactionFactory</ property > < property name = "hibernate.current_session_context_class" >thread</ property > </ session-factory > |
pom.xml에 추가
위에서 설치한 Hibernate-core버전과 일치해야 한다.
1 2 3 4 5 | < dependency > < groupId >org.hibernate</ groupId > < artifactId >hibernate-c3p0</ artifactId > < version >4.3.1.Final</ version > </ dependency > |
acquire_increment |
풀이 고갈되었을 때, 신규로 생성할 커넥션 수 |
idle_test_period |
풀에 있는 세션들이 살아있는지 체크하는 주기(초) 디비서버가 재부팅되면, 풀에 등록된 세션들은 끊어진 세션이다. |
min_size |
풀의 최소 사이즈 |
max_size |
풀의 최대 사이즈 |
max_statements |
PreparedStatement 캐쉬의 사이즈 모든 커넥션에서 사용가능한 사이즈 커넥션 하나에서 사용하는 캐쉬 사이즈 * 커넥션 수(max_size) |
timeout |
풀에서 커넥션이 제거되는 시간(초) 풀에서 사용되기를 기다리는 커넥션이 timeout 시간보다 오랫동안 사용되지 않았을 때 제거된다. 0이면 제거되지 않는다. |
acquireRetryAttempts |
커넥션 생성 시도 수 디비서버가 죽은 상태라면, 커넥션 생성이 실패될 것이고, 지정한 수만큼 시도하다가 그래도 실패한다면, 예외를 준다. |
acquireRetryDelay |
커넥션 생성 시도 쿨타임(밀리초) |
- org.hibernate.MappingException: Unknown entity: com.yakolla.mvctest.MyTestTable
MyTestTable class가 디비테이블과 연동됨을 알리는 작업이 필요하다.
애노테이션을 이미 정의했지만, hibernate.cfg.xml에 추가해야 한다.
언젠간 자동으로 되겠지~
추가할 때 주의점은 <session-factory>의 <property>태크 정의가 끝난 이후부터 선언할 수 있다.
1 2 3 4 5 6 7 8 9 10 | < session-factory > ... < property name = "hibernate.transaction.factory_class" >org.hibernate.transaction.JDBCTransactionFactory</ property > < property name = "hibernate.current_session_context_class" >thread</ property > < mapping class = "com.yakolla.mvctest.MyTestTable" /> </ session-factory > |