아주 오래전에 Hibernate xml로 삽질했던 기억이 있는데, Annotation으로 해보겠다는 게 세월(?)이 벌써 이렇게 흘렀군요.

하이버네이트는 셋팅이 참 어렵군요. 책을 보면 그냥 hibernate함수를 이용해서 어떻게 이용하는지, 하이버네이트의 특성이 주로 나와있는데, 셋팅에 대한 삽질은 좀 자세하지 않은 듯(내가 못본 것일 수도 있음-_-)

NetBeans 6.8에서 삽질했습니다.
넷빈즈다운로드 : http://netbeans.org/downloads/index.html

일단 소녀시대 테이블만 하나 만들어 놓읍시다.
테이블은 sosi랑 schedule 2개가 1:N의 관계형태로 만드려고 합니다. (DB쪽에 취약해서 맞는지 모르겠네-_- 뭐 다취약하지만-_-)
[code]
DROP TABLE IF EXISTS `sosi`;
CREATE TABLE IF NOT EXISTS `sosi` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `birthYear` int(11) NOT NULL,
  `name` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=10 ;

INSERT INTO `sosi` (`id`, `birthYear`, `name`) VALUES
(1, 1989, '효연'),
(2, 1990, '윤아'),
(3, 1990, '수영'),
(4, 1989, '유리'),
(5, 1989, '태연'),
(6, 1989, '제시카'),
(7, 1989, '티파니'),
(8, 1990, '써니'),
(9, 1991, '서현');
[/code]

1. 프로젝트 생성
File -> New Project(Ctrl + Shift + N) -> Java -> Java Application -> Project이름은 SosiSchedule

2. 하이버네이트 설정파일 셋팅
 Ctrl + N을 눌러서 새로운 파일을 만듭니다. SosiSchedule을 선택하고, Hibernate -> Hibernate Configuration Wizard선택, File Name은 hibernate.cfg 디폴트로, Database는 자신이 셋팅하고 sosi테이블을 만들어놓은 Mysql 데이터베이스를 선택합니다. 안만들었으면 New Database Connector를 선택해서 Host, Port, Database, User Name Password를 입력하면 됩니다. 이거 하면 자동으로 Library가 추가되나봅니다.
설정 파일이 만들어졌어요. 근데, 하이버네이트에서는 src최상위 폴더에 넣으면 자동으로 설정파일을 인식하나봐요. 설정파일 경로 지정하는 부분이 없는 것 같은데-_-
테이블 자동생성 및 날라가는 sql을 보기위해 아래 두옵션을 추가합니다.
[code]<property name="hibernate.show_sql">true</property>
<property name="hibernate.hbm2ddl.auto">update</property>[/code]

3. HibernateUtl만들기
Ctrl + N을 눌러서 새로운 파일 작성 -> Hibernate -> HibernateUtl.java, ClassName은 HibernateUtl로 package는 sosischedule.util로 finish!

4. 매핑할 ENTITY클래스 작성
일단 entity클래스는 database에 table이 존재하면 자동으로 만들 수 있습니다.
Ctrl + N을 눌러서 새로운 파일 작성 -> Persistence -> Entity Classes  from Database 선택.
Database Connection에서 셋팅한 mysql선택하면  테이블명이 나오는데, sosi테이블을 Add합니다.
package는 알아보기 쉽게 sosischedule.entity로 하고 finish를...-_-
이쁘게 소스가 만들어지네요.
Sosi.java
[code]/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package sosischedule.entity;

import java.io.Serializable;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;

/**
 *
 * @author mudchobo
 */
@Entity
@Table(name = "sosi")
@NamedQueries({
    @NamedQuery(name = "Sosi.findAll", query = "SELECT s FROM Sosi s"),
    @NamedQuery(name = "Sosi.findById", query = "SELECT s FROM Sosi s WHERE s.id = :id"),
    @NamedQuery(name = "Sosi.findByBirthYear", query = "SELECT s FROM Sosi s WHERE s.birthYear = :birthYear"),
    @NamedQuery(name = "Sosi.findBySosiName", query = "SELECT s FROM Sosi s WHERE s.sosiName = :sosiName")})
public class Sosi implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    @Column(name = "id")
    private Long id;
    @Basic(optional = false)
    @Column(name = "birthYear")
    private int birthYear;
    @Column(name = "sosiName")
    private String sosiName;

    public Sosi() {
    }

    public Sosi(Long id) {
        this.id = id;
    }

    public Sosi(Long id, int birthYear) {
        this.id = id;
        this.birthYear = birthYear;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public int getBirthYear() {
        return birthYear;
    }

    public void setBirthYear(int birthYear) {
        this.birthYear = birthYear;
    }

    public String getSosiName() {
        return sosiName;
    }

    public void setSosiName(String sosiName) {
        this.sosiName = sosiName;
    }

    @Override
    public int hashCode() {
        int hash = 0;
        hash += (id != null ? id.hashCode() : 0);
        return hash;
    }

    @Override
    public boolean equals(Object object) {
        if (!(object instanceof Sosi)) {
            return false;
        }
        Sosi other = (Sosi) object;
        if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return "sosischedule.entity.Sosi[id=" + id + "]";
    }

}
[/code]
각각의 어노테이션들은 구글링을 통해 찾아보는걸로 저도 잘 몰라서-_-
Annotation기반으로 하기전에는 mapping xml파일을 작성했는데, 그걸 그냥 클래스에 보기좋게 해놓은 거라고 보면 될 듯.

스케쥴 클래스는 직접 만들어봅시다.
Ctrl + N을 통해 새로운 파일생성, Persistence -> Entity Class, Class Name은 Schedule, package는 sosischedule.entity선택 후 finish.
그러면 id만 달랑 있습니다. 여기에 칼럼을 만들어 봅시다. 많이 만들면 귀찮아 지니까-_- program명과 소시객체 연동하는 것만 만들어봅시다.
[code]private String program;
private Sosi sosi;[/code]입력하고, Alt + Insert하면 getter, setter자동생성기로 만듭니다.
사실 이렇게만 만들어 놓아도 테이블이 생성됩니다-_- 다 디폴트로 만들어서. 귀찮으니까 이렇게만 만들고 맙시다-_- 아 그리고, 생성자를 두개 추가했습니다. 기본생성자와 property를 세팅해서 만들어주는 생성자.
그리고 테이블과 관계를 맺기 위해 @ManyToOne을 넣어줘야합니다. 안 넣어주면 무슨 Blob으로 그냥 저장해버리는..-_-
Schedule.java
[code]package sosischedule.entity;

import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToOne;

@Entity
public class Schedule implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    private String program;

    @ManyToOne
    private Sosi sosi;

    public Schedule() {
    }

    public Schedule(String program, Sosi sosi) {
        this.program = program;
        this.sosi = sosi;
    }

    public Sosi getSosi() {
        return sosi;
    }

    public void setSosi(Sosi sosi) {
        this.sosi = sosi;
    }

    public Long getId() {
        return id;
    }

    public String getProgram() {
        return program;
    }

    public void setProgram(String program) {
        this.program = program;
    }

    public void setId(Long id) {
        this.id = id;
    }

    @Override
    public int hashCode() {
        int hash = 0;
        hash += (id != null ? id.hashCode() : 0);
        return hash;
    }

    @Override
    public boolean equals(Object object) {
        if (!(object instanceof Schedule)) {
            return false;
        }
        Schedule other = (Schedule) object;
        if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return "sosischedule.entity.Schedule[id=" + id + "]";
    }
}
[/code]
오...이저 hibernate.cfg.xml파일을 열어서 매핑파일이라고 추가합니다.
hibernate.cfg.xml
[code]<mapping class="sosischedule.entity.Sosi"/>
<mapping class="sosischedule.entity.Schedule"/>[/code]
작성한 클래스 두개. 이제 hql을 날릴 수 있어요. hibernate.cfg.xml파일을 선택 후 오른쪽버튼을 누르면 "Run HQL Query"라는 메뉴가 나와요.
from Sosi때리면 소시멤버데이터가 나오네요.
※여기서 해당 프로젝트에 대해서 한번이라도 run을 때리지 않으면 Sosi is not mapped라고 나오네요. 안되면 한번 실행하고 해보세요.
사용자 삽입 이미지
이제 다 된 것 같으니 dao와 service를 만들어봅시다.

5. Dao생성
sosischedule.dao.SosiScheduleDao.java파일을 생성
SosiScheduleDao.java
[code]package sosischedule.dao;

import java.util.List;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
import sosischedule.entity.Schedule;
import sosischedule.entity.Sosi;
import sosischedule.util.HibernateUtil;

public class SosiScheduleDao {

    public List<Sosi> getSosiList() {
        Session session = HibernateUtil.getSessionFactory().openSession();
        Query q = session.createQuery("from Sosi");
        List<Sosi> list = q.list();
        session.close();

        return list;
    }

    public Sosi getSosi(int sosiId) {
        Session session = HibernateUtil.getSessionFactory().openSession();
        Sosi sosi = (Sosi) session.get(Sosi.class, new Long(sosiId));
        session.close();

        return sosi;
    }

    public List<Schedule> getSchedule(Long sosiId) {
        Session session = HibernateUtil.getSessionFactory().openSession();
        Query q = session.createQuery("from Schedule s where s.sosi.id = " + sosiId);
        List<Schedule> list = q.list();
        session.close();

        return list;
    }

    public void addSchedule(Schedule schedule) {
        Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction tx = session.beginTransaction();
        session.save(schedule);
        tx.commit();
        session.close();
    }

    public void removeSchedule(int scheduleId) {
        Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction tx = session.beginTransaction();
        Schedule schedule =
                (Schedule) session.load(Schedule.class, new Long(scheduleId));
        session.delete(schedule);
        tx.commit();
        session.close();
    }
}
[/code]
음....분명 이렇게 하는 건 아닌 것 같아-_- 암튼, 일단 셋팅이 목적이니-_- 대충 이렇게도 할 수 있다는 것을..-_-
getSosiList는 소시리스트를 가져오고, getSosi는 소시를 가져오고, getSchedule은 스케쥴리스트를 가져오고, addSchedule은 스케쥴추가하고, removeSchedule은 스케쥴을 삭제하고...

6. 서비스생성
이걸 사용할 서비스를 만들어봅시다.
sosischedule.service.SosiScheduleService.java
[code]package sosischedule.service;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import sosischedule.dao.SosiScheduleDao;
import sosischedule.entity.Schedule;
import sosischedule.entity.Sosi;

public class SosiScheduleService {

    private SosiScheduleDao sosiScheduleDao = new SosiScheduleDao();

    public void menuSosi() {
        List<Sosi> sosiList = sosiScheduleDao.getSosiList();
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        while(true){
            try {
                for (Sosi sosi : sosiList) {
                    System.out.println(sosi.getId() + "." + sosi.getSosiName());
                }
                System.out.println("번호를 입력하세요!(0은 종료) => ");
                int menuNum = Integer.parseInt(br.readLine());
                if (menuNum == 0){
                    System.out.println("종료!");
                    break;
                }
                // 소시데이터 가져오기
                Sosi sosi = sosiScheduleDao.getSosi(menuNum);
                if (sosi != null){
                    menuSchedule(sosi);
                    break;
                } else {
                    System.out.println("없는 번호입니다.");
                }

            } catch (IOException ex) {
                Logger.getLogger(SosiScheduleService.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

    public void menuSchedule(Sosi sosi) {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        while(true){
            try {
                List<Schedule> scheduleList = sosiScheduleDao.getSchedule(sosi.getId());
                for (Schedule schedule : scheduleList) {
                    System.out.println(schedule.getId() + "." + schedule.getProgram());
                }
                if (scheduleList.size() <= 0){
                    System.out.println("스케쥴이 없습니다.\n");
                }
                System.out.println("1.스케쥴추가 2.스케쥴삭제 0.뒤로 =>");
                int menuNum = Integer.parseInt(br.readLine());
                if (menuNum == 0) {
                    System.out.println("뒤로!");
                    menuSosi();
                    break;
                }
                else if (menuNum == 1) {
                    System.out.println("스케쥴명 입력 : ");
                    String program = br.readLine();
                    System.out.println("스케쥴 = " + program);
                    sosiScheduleDao.addSchedule(new Schedule(program, sosi));
                    System.out.println("추가완료!");
                }
                else if (menuNum == 2) {
                    System.out.println("스케쥴번호 : ");
                    int scheduleId = Integer.parseInt(br.readLine());
                    sosiScheduleDao.removeSchedule(scheduleId);
                    System.out.println("삭제완료!");
                }
            } catch (IOException ex) {
                Logger.getLogger(SosiScheduleService.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }
}[/code]
메인에서 이렇게 사용하면 됩니다.
Main.java
[code]package sosischedule;

import sosischedule.service.SosiScheduleService;

public class Main {

    public static void main(String[] args) {
        SosiScheduleService sosiScheduleService = new SosiScheduleService();
        sosiScheduleService.menuSosi();
    }
}
[/code]

결과
[code]Hibernate: select sosi0_.id as id0_, sosi0_.birthYear as birthYear0_, sosi0_.sos
iName as sosiName0_ from sosi sosi0_
1.효연
2.윤아
3.수영
4.유리
5.태연
6.제시카
7.티파니
8.써니
9.서현
번호를 입력하세요!(0은 종료) =>
5
Hibernate: select sosi0_.id as id0_0_, sosi0_.birthYear as birthYear0_0_, sosi0_
.sosiName as sosiName0_0_ from sosi sosi0_ where sosi0_.id=?
Hibernate: select schedule0_.id as id1_, schedule0_.program as program1_, schedu
le0_.sosi_id as sosi3_1_ from Schedule schedule0_ where schedule0_.sosi_id=5
스케쥴이 없습니다.

1.스케쥴추가 2.스케쥴삭제 0.뒤로 =>
1
스케쥴명 입력 :
태연의 친한친구
스케쥴 = 태연의 친한친구
Hibernate: insert into Schedule (program, sosi_id) values (?, ?)
추가완료!
Hibernate: select schedule0_.id as id1_, schedule0_.program as program1_, schedu
le0_.sosi_id as sosi3_1_ from Schedule schedule0_ where schedule0_.sosi_id=5
Hibernate: select sosi0_.id as id0_0_, sosi0_.birthYear as birthYear0_0_, sosi0_
.sosiName as sosiName0_0_ from sosi sosi0_ where sosi0_.id=?
3.태연의 친한친구
1.스케쥴추가 2.스케쥴삭제 0.뒤로 =>
1
스케쥴명 입력 :
태연의 친한친구2
스케쥴 = 태연의 친한친구2
Hibernate: insert into Schedule (program, sosi_id) values (?, ?)
추가완료!
Hibernate: select schedule0_.id as id1_, schedule0_.program as program1_, schedu
le0_.sosi_id as sosi3_1_ from Schedule schedule0_ where schedule0_.sosi_id=5
Hibernate: select sosi0_.id as id0_0_, sosi0_.birthYear as birthYear0_0_, sosi0_
.sosiName as sosiName0_0_ from sosi sosi0_ where sosi0_.id=?
3.태연의 친한친구
4.태연의 친한친구2
1.스케쥴추가 2.스케쥴삭제 0.뒤로 =>
2
스케쥴번호 :
4
Hibernate: select schedule0_.id as id1_1_, schedule0_.program as program1_1_, sc
hedule0_.sosi_id as sosi3_1_1_, sosi1_.id as id0_0_, sosi1_.birthYear as birthYe
ar0_0_, sosi1_.sosiName as sosiName0_0_ from Schedule schedule0_ left outer join
 sosi sosi1_ on schedule0_.sosi_id=sosi1_.id where schedule0_.id=?
Hibernate: delete from Schedule where id=?
삭제완료!
Hibernate: select schedule0_.id as id1_, schedule0_.program as program1_, schedu
le0_.sosi_id as sosi3_1_ from Schedule schedule0_ where schedule0_.sosi_id=5
Hibernate: select sosi0_.id as id0_0_, sosi0_.birthYear as birthYear0_0_, sosi0_
.sosiName as sosiName0_0_ from sosi sosi0_ where sosi0_.id=?
3.태연의 친한친구
1.스케쥴추가 2.스케쥴삭제 0.뒤로 =>[/code]
와....잘된다....-_-
 
Posted by 머드초보
,
 
셋팅이 끝났으니 Hibernate Mapping파일을 생성합니다.
New -> Other -> Hibernate -> Hibernate Mapping Files and POJOs from Database선택 -> File Name은 디폴트 ->
Avaliable Tables에서 sosi테이블 add -> JDK 5 Language Features체크, package는 sm.sosi.sosiage.map입력 후 Finish. 여기서 이상한게 매핑파일을 만들었는데, 패키지가 보이지 않습니다. 처음부터 생성되지 않은 패키지를 선택해서 그런 것 같은데, 넷빈즈 껐다 키면 보입니다-_-;(버그인 듯-_-)

이제 Dao를 하나 만들어봅시다.
sm.sosi.sosiage.dao패키지에 AgeDao클래스를 만들어봅시다. 이 클래스에 메소드는 나이를 알려주는 메소드 1개-_-; 이 클래스는 HibernateDaoSupport를 상속받습니다.
AgeDao.java
[code]public class AgeDao extends HibernateDaoSupport {
    public int searchAge(String name) {
        List<Sosi> sosi = getHibernateTemplate().find("from Sosi where name = ?", name);
        if (sosi.size() > 0) {
            return sosi.get(0).getAge();
        } else {
            return 0;
        }
    }
}[/code]
코드는 간단합니다. 제가 아직 하이버네이트를 공부중이라 저거 하나만 객체로 받아오는 걸 못하겠는데요-_-; List로 받아와서 그냥 첫번째꺼 가져오도록 했습니다-_-;

sm.sosi.sosiage.service패키지에 AgeService를 만들어봅시다.
AgeService.java
[code]public class AgeService {
    private AgeDao ageDao;

    public void setAgeDao(AgeDao ageDao) {
        this.ageDao = ageDao;
    }

    public String searchAge(String name) {
        int age = ageDao.searchAge(name);
        String message;

        if (age == 0) {
            message = name + "은/는 소녀시대의 멤버가 아닙니다.";
        } else {
            message = name + "의 나이는 " + age + "세입니다.";
        }
        return message;
    }
}[/code]
간단하게 메세지를 만들어서 리턴해주는 서비스입니다.

심플컨트롤러를 생성해봅시다. New -> Other -> Srpingframework -> Simple Form Controller선택 -> Class Name은 AgeController, package는 sm.sosi.sosiage.controller -> Finish.
AgeController.java
[code]public class AgeController extends SimpleFormController {

    private AgeService ageService;

    public void setAgeService(AgeService ageService) {
        this.ageService = ageService;
    }

    public AgeController() {
        setCommandClass(Sosi.class);
        setCommandName("sosiAge");
        setSuccessView("successView");
        setFormView("formView");
    }

    /*
    @Override
    protected void doSubmitAction(Object command) throws Exception {
        throw new UnsupportedOperationException("Not yet implemented");
    }
    */

    //Use onSubmit instead of doSubmitAction
    //when you need access to the Request, Response, or BindException objects
    @Override
    protected ModelAndView onSubmit(
            HttpServletRequest request,
            HttpServletResponse response,
            Object command,
            BindException errors) throws Exception {
        Sosi sosi = (Sosi)command;
        ModelAndView mv = new ModelAndView(getSuccessView());
        mv.addObject("message", ageService.searchAge(sosi.getName()));
        return mv;
    }
}[/code]
이제 formView와 successView만 작성하면 끝이네요.
Web Pages -> WEB-INF ->jsp에서 New -> JSP -> JSP File Name은 formView -> Finish.
formView.jsp
[code]<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
   "http://www.w3.org/TR/html4/loose.dtd">

<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>소녀시대 짱-_-;</title>
    </head>
    <body>
        <form:form commandName="sosiAge" method="post" action="age.htm">
            소녀시대 멤버이름을 입력하세요:
            <form:input path="name" />
            <input type="submit" value="검색">
        </form:form>
    </body>
</html>[/code]
또다른 View파일 JSP File Name은 successView -> Finish.
successView.jsp
[code]<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>소녀시대 나이 결과</title>
    </head>
    <body>
         <h2>${message}</h2>
    </body>
</html>[/code]
이제 dispatcher-servlet.xml에 bean을 등록해봅시다.
dispatcher-servlet.xml
[code]<bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
        <property name="mappings">
            <props>
                <prop key="index.htm">indexController</prop>
                <prop key="age.htm">ageiController</prop>
            </props>
        </property>
    </bean>
   
    <bean id="viewResolver"
          class="org.springframework.web.servlet.view.InternalResourceViewResolver"
          p:prefix="/WEB-INF/jsp/"
          p:suffix=".jsp" />

    <!-- dao -->
    <bean name="ageDao"
          class="sm.sosi.sosiage.dao.AgeDao"
          p:sessionFactory-ref="sessionFactory" />

    <!-- service -->
    <bean name="ageService"
          class="sm.sosi.sosiage.service.AgeService"
          p:ageDao-ref="ageDao"/>

    <!-- controller -->
    <bean name="indexController"
          class="org.springframework.web.servlet.mvc.ParameterizableViewController"
          p:viewName="index" />
    <bean name="ageController"
          class="sm.sosi.sosiage.controller.AgeController"
          p:ageService-ref="ageService" />[/code]
실행해보면
정보: Hibernate: select sosi0_.idx as idx0_, sosi0_.name as name0_, sosi0_.age as age0_ from hibernate.sosi sosi0_ where sosi0_.name=?
이런 쿼리가 날아가네요.
사용자 삽입 이미지
사용자 삽입 이미지
태연 짱-_-; 역시 원더걸스 예제보다 소녀시대 예제가 더 접근성이 높은 듯-_-;

PS. 보니까 Hibernate도 애노테이션으로 할 수 있는 듯 한데, 그것도 좀 해봐야겠네요. 다시 하이버네이트 책을 좀 읽어봐야겠어요-_-;
 
Posted by 머드초보
,
 
요즘 하이버네이트3 프로그래밍(최범균 저)를 보고 있는데, 뭔소린지 잘 이해가 안가서 쉬어갈 겸-_-; 넷빈즈에서 스프링이랑 하이버네이트 연동하는 거 정리해서 올립니다-_-;

환경 : GlassFishV3 + SpringFramework 2.5 + Hibernate 3.2.5 + MySQL5.0 + Netbeans6.5

접근성을 높이기 위해(?) 소녀시대를 예제로 작성해봅시다. 멤버이름을 입력하면 멤버의 나이를 알려주는 웹애플리케이션을 만들어봅시다-_-;

Database
[code]CREATE TABLE `sosi` (
  `idx` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(45) NOT NULL,
  `age` int(10) unsigned NOT NULL,
  PRIMARY KEY (`idx`)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8;

INSERT INTO `sosi` (`idx`,`name`,`age`) VALUES
 (1,'윤아',20),
 (2,'수영',20),
 (3,'효연',21),
 (4,'유리',21),
 (5,'태연',21),
 (6,'제시카',21),
 (7,'티파니',21),
 (8,'써니',21),
 (9,'서현',19);
[/code]

New Project -> Java Web -> Web Application -> Project Name : SosiAge -> Glass Fish V3으로 하구요 -> Spring Web MVC 2.5랑 Hibernate 3.2.5체크합니다.
Hibernate에서 DB를 설정해야하는데, New Database Connection해서 Name을 MySQL로 맞추고, 설정에 맞게 입력한 뒤, 추가한 것으로 선택한 뒤 Finish를 누른 뒤 완료합니다.

한글문제로 인한 web.xml파일에 아래 코드를 추가합니다.
web.xml
[code]<filter>
          <filter-name>Request Encoding</filter-name>
          <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
          <init-param>
               <param-name>encoding</param-name>
               <param-value>UTF-8</param-value>
          </init-param>
     </filter>
     <filter-mapping>
          <filter-name>Request Encoding</filter-name>
          <servlet-name>dispatcher</servlet-name>
     </filter-mapping>[/code]
hibernate를 사용하기 위한 필수작업인 session bean을 생성해야합니다.
applicationContext.xml
[code]<bean id="sessionFactory"
        class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
        <property name="configLocation" value="classpath:hibernate.cfg.xml" />
    </bean>[/code]
설정을 여기에 다 적고, datasource를 session에 di를 해도 상관없고, hibernate.cfg.xml파일에 설정해도 다 되더군요. 우선 기본적으로 hibernate.cfg.xml파일을 직접 만들어주니 configLocation설정해서 해봅시다.

하이버네이트 설정파일에서 SQL문을 직접볼 수 있는 옵션을 추가합시다.
Source Packages -> default package -> hibernate.cfg.xml파일을 열어봅니다.
design모드에서 Configuration Properties에서 add한 뒤, hibernate.show_sql값 true로 추가합니다. 쿼리를 직접보도록...-_-;

이제 뭐 셋팅이 끝났네요. 셋팅 끝나면 뭐 그냥 쓰기만 하면 됩니다-_-;
다음 장에서......
 
Posted by 머드초보
,
 

[NetBeans] 넷빈즈를 이용한 Hibernate 초간단 예제1 - Hibernate 셋팅

에 이어서-_-;

이제 셋팅은 다 된 것 같으니, 이 데이터를 가져와봅시다.
Hibernate에서 쉽게 데이터를 가져올 수 있도록 Helper클래스를 만들어봅시다.

Ctrl + N -> Java -> Java Class -> Class Name은 ScoreHelper, Package는 wondergirlshibernate로 합니다.

ScoreHelper.java
[code]package wondergirlshibernate;

import java.util.List;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
import wondergirlshibernate.entity.Score;
import wondergirlshibernate.util.HibernateUtil;

public class ScoreHelper {
Session session = null;

    public ScoreHelper() {
        this.session = HibernateUtil.getSessionFactory().openSession();
    }

    public List<Score> getWondergirlsScore() {
        List<Score> wondergirlsScoreList = null;

        try {
            Transaction tx = session.beginTransaction();
            Query q = session.createQuery("from Score");
            wondergirlsScoreList = (List<Score>) q.list();
        } catch (HibernateException e) {
            e.printStackTrace();
        }
        return wondergirlsScoreList;
    }
}
[/code]
getWondergirlsScore를 보면 from Score를 실행하는 것이 다 입니다. 그리고, 그 리스트를 받아오는 거죠.

Main클래스를 봅시다.
Main.java
[code]package wondergirlshibernate;

import java.util.List;
import wondergirlshibernate.entity.Score;

public class Main {

    public static void main(String[] args) {
        ScoreHelper helper = new ScoreHelper();

        List list = helper.getWondergirlsScore();

        System.out.println(
                String.format("%10s %10s %10s %10s", "이름", "나이", "국어", "수학"));
        for (int i = 0; i < list.size(); i++) {
            Score score = (Score) list.get(i);

            System.out.println(
                String.format("%10s %10s %10d %10d",
                    score.getWondergirls().getName(),
                    score.getWondergirls().getAge(),
                    score.getKorean(),
                    score.getMath())
            );
        }
    }
}
[/code]
그냥 출력합니다-_-; 결과는 이렇게 나올 겁니다.
[code]Hibernate: select score0_.idx as idx1_, score0_.widx as widx1_, score0_.korean as korean1_, score0_.math as math1_ from wondergirls.score score0_
        이름         나이         국어         수학
Hibernate: select wondergirl0_.idx as idx0_0_, wondergirl0_.name as name0_0_, wondergirl0_.age as age0_0_ from wondergirls.wondergirls wondergirl0_ where wondergirl0_.idx=?
        선예         20        100        100
Hibernate: select wondergirl0_.idx as idx0_0_, wondergirl0_.name as name0_0_, wondergirl0_.age as age0_0_ from wondergirls.wondergirls wondergirl0_ where wondergirl0_.idx=?
        선미         20         90         90
Hibernate: select wondergirl0_.idx as idx0_0_, wondergirl0_.name as name0_0_, wondergirl0_.age as age0_0_ from wondergirls.wondergirls wondergirl0_ where wondergirl0_.idx=?
        소희         17         80         80
Hibernate: select wondergirl0_.idx as idx0_0_, wondergirl0_.name as name0_0_, wondergirl0_.age as age0_0_ from wondergirls.wondergirls wondergirl0_ where wondergirl0_.idx=?
        예은         17         70         70
Hibernate: select wondergirl0_.idx as idx0_0_, wondergirl0_.name as name0_0_, wondergirl0_.age as age0_0_ from wondergirls.wondergirls wondergirl0_ where wondergirl0_.idx=?
        유빈         21         60         60
BUILD SUCCESSFUL (total time: 3 seconds)
[/code]
음... 저기서 wondergirls참조하는 것을 가져오려고 하면 다시 쿼리를 날리는 군요-_-; 뭔가 다른 방법이 있는 건가...
Hibernate를 더 공부해봐야겠습니다. 넷빈즈에서 쉽게 Hibernate를 할 수 있네요. 예전에 Hibernate Hello World예제를 따라해보고 셋팅에 겁을 먹은 기억이 있었는데, 쉽게 할 수 있네요.
이제 공부를 해봅시다 ㅠㅠ

 
Posted by 머드초보
,
 
오....간만에 초간단 시리즈-_-;
그냥 넷빈즈6.5가 새로 나와서 Hibernate도 공부해볼 겸 해서 삽질을 좀 해봤습니다. Hibernate를 공부하고 있는데, 왜이렇게 어렵죠ㅠ 아직도 잘 모르겠습니다. 좋은 자료가 있으시면 댓글로 좀 알려주세요 ㅠ(굽신굽신 ㅠ)

넷빈즈6.5 JDK6U10환경에서 해봤습니다.

File New Project -> Java -> Java Application 선택.
Project Name은 WondergirlsHibernate로 하고 Finish!(원더걸스를 예제로 해야 접근성이 좋은..-_-)

Mysql에다가 DB를 만들어봅시다.
첫번째 테이블은 wondergirls에 대한 정보를 나타냅니다. 이름과 나이가 있습니다.
[code]CREATE TABLE  `wondergirls`.`wondergirls` (
  `idx` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(45) DEFAULT NULL,
  `age` int(10) unsigned DEFAULT NULL,
  PRIMARY KEY (`idx`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;

INSERT INTO `wondergirls` (`idx`,`name`,`age`) VALUES
 (1,'선예',20),
 (2,'선미',20),
 (3,'소희',17),
 (4,'예은',17),
 (5,'유빈',21);
[/code]
두번째 테이블은 과목점수를 나타냅니다. widx 칼럼이 wondergirls테이블의 idx와 FK로 연결되었습니다.
[code]CREATE TABLE  `wondergirls`.`score` (
  `idx` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `widx` int(10) unsigned NOT NULL,
  `korean` int(10) unsigned DEFAULT NULL,
  `math` int(10) unsigned DEFAULT NULL,
  PRIMARY KEY (`idx`),
  KEY `FK_score_1` (`widx`),
  CONSTRAINT `FK_score_1` FOREIGN KEY (`widx`) REFERENCES `wondergirls` (`idx`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;

INSERT INTO `score` (`idx`,`widx`,`korean`,`math`) VALUES
 (1,1,100,100),
 (2,2,90,90),
 (3,3,80,80),
 (4,4,70,70),
 (5,5,60,60);
[/code]
넷빈즈에 Mysql을 추가를 안하셨다면 추가를 하셔야합니다.
왼쪽에서 Projects탭 말고,  Services탭을 클릭합니다. Register Mysql를 클릭해서 정보를 입력하여 추가합니다. connect했을 때 db가 보인다면 추가가 잘 된 것입니다. start나 stop도 이곳에서 관리하려면 추가로 입력하시면 되는데, 입력안하고, 외부에서 실행하고 종료해도 상관 없더군요.

그러면 다시 Projects탭으로 돌아와서.....프로젝트이름에 대고, 오른쪽버튼 -> New -> Hibernate -> Hibernate Configuration File선택 -> Name and Location에서는 그냥 Next -> Database Connection은 방금 추가한 테이블이 있는 Mysql의 db를 선택합니다. Finish를 누르면 각종 설정화면이 나옵니다.
여기서 Optional Properties -> Configuration Properties에 add하고, hibernate.show_sql을 true로 설정한 것을 추가합니다. 이제 XML로 보면 이렇게 보일겁니다.
[code]<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
  <session-factory>
    <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
    <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
    <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/wondergirls</property>
    <property name="hibernate.connection.username">root</property>
    <property name="hibernate.connection.password">mudchobo</property>
    <property name="hibernate.show_sql">true</property>
  </session-factory>
</hibernate-configuration>
[/code]
설정하기 편하게 되어있군요. 다 뭐하는 건지는 하나씩 해봐야 알 것 같아요 ㅠ 우선은 sql쿼리만 볼 수 있도록 하고-_-;

이제 HibernateUtil을 추가합니다. 설정파일을 통해 session을 가져오는 유틸인 듯 합니다.
Ctrl + N -> Hibernate -> HibernateUtil.java 선택.
Class Name은 New를 뺀 HibernateUtil, Package는 wondergirlshibernate.util로 합시다. Finish를 누르면 자동으로 생성됩니다.

이제 매핑파일을 가져옵시다.
Ctrl + N -> Hibernate -> Hibernate Mapping Files and POJOs from Database 선택.
Name and Location에서는 그냥 Next.
hibernate.cfg.xml이 자동으로 선택이 되는데, 거기에 방금 생성한 테이블이 있을 겁니다.
사용자 삽입 이미지
score를 추가하면 wondergirls는 따라옵니다. 서로 연결이 되어있어서 필요합니다. Next한다음에 Package에 wondergirlshibernate.entity로 하고 Finish를 클릭합니다.

이제 entity도 만들어졌으니, HQL을 테스트해볼 수 있습니다.
Source Packages -> default package -> hibernate.cfg.xml에 오른쪽버튼 클릭 후 Run HQL Query를 클릭하면 쿼리를 날릴 수 있습니다. 아래와 같이 날려봅시다.
[code]from Score[/code]
사용자 삽입 이미지
이렇게 결과를 볼 수 있습니다.
별 것도 없는데 글이 길어 지네-_-; 다음 글에-_-;

[NetBeans] 넷빈즈를 이용한 Hibernate 초간단 예제2 - 데이터가져오기.


참조글 : http://www.netbeans.org/kb/docs/java/hibernate-java-se.html
 
Posted by 머드초보
,