2015年10月23日 星期五

使用HibernateUtil做PK的CRUD (Hibernate3.x 四)

依照前面兩篇合起來做一個測試,只針對Emp做測試

※使用XML設定


hibernate.cfg.xml
<hibernate-configuration>
    <session-factory>
        <property name="hibernate.connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
        <property name="hibernate.connection.url">jdbc:oracle:thin:@127.0.0.1:1521:orcl</property>
        <property name="hibernate.connection.username">account</property>
        <property name="hibernate.connection.password">password</property>
        <property name="hibernate.dialect">org.hibernate.dialect.OracleDialect</property>
        <property name="hibernate.show_sql">true</property>
        <property name="hibernate.format_sql">true</property>
        <property name="hibernate.connection.autocommit">true</property>
    
        <property name="hibernate.transaction.factory_class">org.hibernate.transaction.JDBCTransactionFactory</property>
        <property name="hibernate.current_session_context_class">thread</property>
    
        <mapping resource="vo/Emp.hbm.xml" />
    </session-factory>
</hibernate-configuration>

Emp.hbm.xml
<hibernate-mapping>
    <class name="vo.Emp" table="Emp">
        <id name="empno" type="int">
            <column name="EMPNO" />
            <generator class="assigned" />
        </id>
        <property name="ename" type="java.lang.String">
            <column name="ENAME" />
        </property>
        <property name="job" type="java.lang.String">
            <column name="JOB" />
        </property>
        <property name="mgr" type="java.lang.Integer">
            <column name="MGR" />
        </property>
        <property name="hiredate" type="java.util.Date">
            <column name="HIREDATE" />
        </property>
        <property name="sal" type="java.lang.Double">
            <column name="SAL" />
        </property>
        <property name="comm" type="java.lang.Double">
            <column name="COMM" />
        </property>
        <property name="deptno" type="java.lang.Integer">
            <column name="DEPTNO" />
        </property>
    </class>
</hibernate-mapping>

Emp.java
private int empno;
private String ename;
private String job;
private Integer mgr;
private Date hiredate;
private Double sal;
private Double comm;
private Integer deptno;
    
//setter/getter

DAOFactory.java
public class DAOFactory {
    public static IEmpDAO getIEmpDAOInstance() {
        return new EmpDAOImpl() ;
    }
}

IEmpDAO.java
public interface IEmpDAO {
    public boolean saveOrUpdate(Emp vo) throws Exception;
    public boolean delete(int id) throws Exception;
    public Emp load(int id) throws Exception;
}

EmpDAOImpl.java
public class EmpDAOImpl implements IEmpDAO {
    @Override
    public boolean saveOrUpdate(Emp vo) throws Exception {
        // 使用官方的HibernateUtil
        Transaction tx = HibernateUtil.getSessionFactory().getCurrentSession()
                .beginTransaction();
        HibernateUtil.getSessionFactory().getCurrentSession().saveOrUpdate(vo);
        tx.commit();
    
        // 使用自定的 HibernateUtil
        // HibernateUtil2.getSession().saveOrUpdate(vo);
        // HibernateUtil2.getSession().flush();
        return true;
    }
    
    @Override
    public boolean delete(int id) throws Exception {
        // 使用官方的HibernateUtil
        Transaction tx = HibernateUtil.getSessionFactory().getCurrentSession()
                .beginTransaction();
        HibernateUtil.getSessionFactory().getCurrentSession()
                .delete(this.load(id));
        tx.commit();
    
        // 使用自定的 HibernateUtil
        // HibernateUtil2.getSession().delete(this.load(id));
        // HibernateUtil2.getSession().flush();
        return true;
    }
    
    @Override
    public Emp load(int id) throws Exception {
        // 使用官方的HibernateUtil
        HibernateUtil.getSessionFactory().getCurrentSession().beginTransaction();
        return (Emp) HibernateUtil.getSessionFactory().getCurrentSession()
                .load(Emp.class, id);
    
        // 使用自定的 HibernateUtil
        // return (Emp) HibernateUtil2.getSession().load(Emp.class, id);
    }
}

IEmpServiceTest
public class IEmpServiceTest {
    
    // @Test
    public void testSaveOrUpdate() throws Exception {
        Emp emp = new Emp();
        emp.setEmpno(1);
        emp.setEname("bruce");
        emp.setJob("IT");
        emp.setMgr(7839);
        emp.setHiredate(new Date());
        emp.setSal(20000.35);
        emp.setComm(251.13);
        emp.setDeptno(20);
        boolean rtn = DAOFactory.getIEmpDAOInstance().saveOrUpdate(emp);
        TestCase.assertEquals(rtn, true);
    }
    
    @Test
    public void testDelete() throws Exception {
        boolean rtn = DAOFactory.getIEmpDAOInstance().delete(1);
        TestCase.assertEquals(rtn, true);
    }
    
    // @Test
    public void testLoad() throws Exception {
        Emp emp = DAOFactory.getIEmpDAOInstance().load(1);
        TestCase.assertEquals(emp != null, true);
    }
    
    @After
    public void testCloseSession() {
        if (HibernateUtil2.getSession().isOpen()) {
            System.out.println("session2 未關閉!");
            HibernateUtil2.getSession().close();
        } else {
            System.out.println("session2 已關閉!");
        }
    
        if (HibernateUtil.getSessionFactory().getCurrentSession().isOpen()) {
            System.out.println("session 未關閉!");
            HibernateUtil.getSessionFactory().close();
        } else {
            System.out.println("session 已關閉!");
        }
    }
}

這一次的專案圖:


※HibernateUtil和HibernateUtil2,依照IEmpServiceTest.java的測試,看起來都是使用同一個session
※使用官方的HibernateUtil一定要beginTransaction(查詢也要),最後也要commit(查詢可不用)
※使用自定的HibernateUtil只要flush即可

※使用Annotation設定

將xml設定的hibernate.cfg.xml改成下面的樣子
<!-- <mapping resource="vo/Dept.hbm.xml" /> -->
<mapping class="vo.Emp" />

Emp.java
package vo;

import java.util.Date;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

@Entity
@Table(name = "EMP", catalog = "c##scott") //, schema = "c##scott")
public class Emp {
    private int empno;
    private String ename;
    private String job;
    private Integer mgr;
    private Date hiredate;
    private Double sal;
    private Double comm;
    private Integer deptno;
    
    @Id
    @Column(name = "EMPNO", unique = true, nullable = false)
    public int getEmpno() {
        return empno;
    }
    
    public void setEmpno(int empno) {
        this.empno = empno;
    }
    
    @Column(name = "ENAME")
    public String getEname() {
        return ename;
    }
    
    public void setEname(String ename) {
        this.ename = ename;
    }
    
    @Column(name = "JOB")
    public String getJob() {
        return job;
    }
    
    public void setJob(String job) {
        this.job = job;
    }
    
    @Column(name = "MGR")
    public Integer getMgr() {
        return mgr;
    }
    
    public void setMgr(Integer mgr) {
        this.mgr = mgr;
    }
    
    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "HIREDATE")
    public Date getHiredate() {
        return hiredate;
    }
    
    public void setHiredate(Date hiredate) {
        this.hiredate = hiredate;
    }
    
    @Column(name = "SAL")
    public Double getSal() {
        return sal;
    }
    
    public void setSal(Double sal) {
        this.sal = sal;
    }
    
    @Column(name = "COMM")
    public Double getComm() {
        return comm;
    }
    
    public void setComm(Double comm) {
        this.comm = comm;
    }
    
    @Column(name = "DEPTNO")
    public Integer getDeptno() {
        return deptno;
    }
    
    public void setDeptno(Integer deptno) {
        this.deptno = deptno;
    }
    
}

※注意不要import錯了,都是import javax.persistence開頭的哦!

※@Table的catalog和schema全不打或取其一是ok的,但全打會出「could not load an entity:」的錯

※@Temporal(TemporalType.TIMESTAMP)是預設值可不打,其他還有兩種
TemporalType.DATE和TemporalType.TIME,主要就是取得的日期要不要有「年月日」,或是「時分秒」,或者兩個都要(預設)

※@Column預設是屬性名,而資料庫不分大小寫,如果兩個一樣可不寫

沒有留言:

張貼留言