Top

JAVA Hibernate DAY01

  1. Hibernate基本使用
  2. Hibernate映射类型
  3. 在NETCTOSS中引入Hibernate
  4. 使用Hibernate重构资费DAO

1 Hibernate基本使用

1.1 问题

使用Hibernate实现对员工表的增、删、改、查。

1.2 方案

Hibernate使用步骤:

  1. 导入Hibernate包,以及数据库驱动包。
  2. 引入Hibernate主配置文件hibernate.cfg.xml。
  3. 创建实体类。
  4. 创建映射关系文件。
  5. 使用Hibernate常用API执行增删改查操作。

1.3 步骤

实现此案例需要按照如下步骤进行。

步骤一:准备工作

创建员工表EMP,建表语句如下:

CREATE TABLE EMP(
  ID			NUMBER(4) CONSTRAINT EMP_ID_PK PRIMARY KEY,
  NAME		VARCHAR(50)  NOT NULL,
  AGE		NUMBER(11),
  SALARY		NUMBER(7,2),
  MARRY 		CHAR(1),
  BIRTHDAY 	DATE,
  LAST_LOGIN_TIME	DATE
  );

CREATE SEQUENCE emp_seq;

创建一个WEB项目,名为HibernateDay01。

步骤二:导包

导入Hibernate开发包,以及数据库驱动包,完成后项目的包结构如下图:

图-1

步骤三:引入Hibernate主配置文件

将Hibernate主配置文件hibernate.cfg.xml复制到项目中,放在src根路径下。并在主配置文件中配置好数据库连接信息,以及Hibernate框架参数,代码如下:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
		"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
		"/hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
	<session-factory>
		<!--数据库连接信息,根据自己的数据库进行配置 -->
		<property name="connection.url">
			jdbc:oracle:thin:@localhost:1521:xe
		</property>
		<property name="connection.username">lhh</property>
		<property name="connection.password">123456</property>
		<property name="connection.driver_class">
			oracle.jdbc.OracleDriver
		</property>
		
		<!-- Hibernate配置信息 -->
		<!-- dialect方言,用于配置生成针对哪个数据库的SQL语句 -->
		<property name="dialect">
			<!--方言类,Hibernate提供的,用于封装某种特定数据库的方言 -->
			org.hibernate.dialect.OracleDialect
		</property>
		<!-- Hibernate生成的SQL是否输出到控制台 -->
		<property name="show_sql">true</property>
		<!--将SQL输出时是否格式化 -->
		<property name="format_sql">true</property>
		
	</session-factory>
</hibernate-configuration>

步骤四:创建实体类

创建包com.tarena.entity,并在该包下创建员工表对应的实体类Emp.java,用于封装员工表的数据,代码如下:

packagecom.tarena.entity;

importjava.sql.Date;
importjava.sql.Timestamp;

public class Emp {

	private Integer id;
	private String name;
	private Integer age;
	private Double salary;
	private Boolean marry;
	private Date birthday;
	private Timestamp lastLoginTime;

	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;
	}

	public Integer getAge() {
		return age;
	}

	public void setAge(Integer age) {
		this.age = age;
	}

	public Double getSalary() {
		return salary;
	}

	public void setSalary(Double salary) {
		this.salary = salary;
	}

	public Boolean getMarry() {
		return marry;
	}

	public void setMarry(Boolean marry) {
		this.marry = marry;
	}

	public Date getBirthday() {
		return birthday;
	}

	public void setBirthday(Date birthday) {
		this.birthday = birthday;
	}

	public Timestamp getLastLoginTime() {
		returnlastLoginTime;
	}

	public void setLastLoginTime(Timestamp lastLoginTime) {
		this.lastLoginTime = lastLoginTime;
	}

}

步骤五:创建映射关系文件

在com.tarena.entity包下,创建员工实体类的映射关系文件,名为Emp.hbm.xml,并在该文件中配置实体类和表的关系,以及类中属性和表中字段的关系,代码如下:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
	"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
	"/hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
	<!--配置实体类和表的关系 -->
	<class name="com.tarena.entity.Emp" table="emp">
		<!--配置主键属性和字段的关系 -->
		<id name="id" type="java.lang.Integer" column="id">
			<!--用来指明主键的生成方式 -->
			<generator class="sequence">
				<!--指定用于生成主键的sequence -->
				<param name="sequence">emp_seq</param>
			</generator>
		</id>
		
		<!--配置实体类中属性与表中字段的关系 -->
		<property name="name" 
			type="java.lang.String" column="name"/>
		<property name="age" 
			type="java.lang.Integer" column="age"/>
		<property name="salary" 
			type="java.lang.Double" column="salary"/>
		<property name="birthday" 
			type="java.sql.Date" column="birthday"/>
		<property name="lastLoginTime" 
			type="java.sql.Timestamp" column="last_login_time"/>
	</class>
</hibernate-mapping>

注意,先不要配置布尔型属性marry,后面会单独讲解布尔型属性的配置及使用。

步骤六:声明映射关系文件

在主配置文件hibernate.cfg.xml中,声明映射关系文件Emp.hbm.xml,代码如下:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
		"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
		"/hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
	<session-factory>
		<!--数据库连接信息,根据自己的数据库进行配置 -->
		<property name="connection.url">
			jdbc:oracle:thin:@localhost:1521:xe
		</property>
		<property name="connection.username">lhh</property>
		<property name="connection.password">123456</property>
		<property name="connection.driver_class">
			oracle.jdbc.OracleDriver
		</property>
		
		<!-- Hibernate配置信息 -->
		<!-- dialect方言,用于配置生成针对哪个数据库的SQL语句 -->
		<property name="dialect">
			<!--方言类,Hibernate提供的,用于封装某种特定数据库的方言 -->
			org.hibernate.dialect.OracleDialect
		</property>
		<!-- Hibernate生成的SQL是否输出到控制台 -->
		<property name="show_sql">true</property>
		<!--将SQL输出时是否格式化 -->
		<property name="format_sql">true</property>
		
#cold_bold		<!--声明映射关系文件 -->
#cold_bold		<mapping resource="com/tarena/entity/Emp.hbm.xml" />
	</session-factory>
</hibernate-configuration>

步骤七:创建Session工具类

创建HibernateUtil工具类,用于创建Session对象,代码如下:

packagecom.tarena.util;

importorg.hibernate.Session;
importorg.hibernate.SessionFactory;
importorg.hibernate.cfg.Configuration;

public class HibernateUtil {

	private static SessionFactorysessionFactory;
	
	static {
		// 加载Hibernate主配置文件
		Configuration conf = new Configuration();
		conf.configure("/hibernate.cfg.xml");
		sessionFactory = conf.buildSessionFactory();
	}

	/**
	 * 创建session
	 */
	public static Session getSession() {
		returnsessionFactory.openSession();
	}
	
	public static void main(String[] args) {
		System.out.println(getSession());
	}

}

步骤八:练习使用Hibernate对员工表进行增删改查

创建包com.tarena.test,并在该包下创建一个JUNIT测试类,并在类中使用Hibernate写出对EMP表的增删改查的方法,代码如下:

packagecom.tarena.test;

importjava.sql.Date;
importjava.sql.Timestamp;
importjava.util.List;
importorg.hibernate.HibernateException;
importorg.hibernate.Query;
importorg.hibernate.Session;
importorg.hibernate.Transaction;
importorg.junit.Test;
importcom.tarena.entity.Emp;
importcom.tarena.util.HibernateUtil;

/**
 *	演示Hibernate的基本使用
 */
public class TestEmp {

	/**
	 * 新增emp
	 */
	@Test
	public void add() {
		// 模拟要新增的emp
		Emp e = new Emp();
		e.setName("ggg");
		e.setAge(29);
		e.setMarry(false);
		e.setSalary(8000.00);
		e.setBirthday(Date.valueOf("1983-10-20"));
		e.setLastLoginTime(
			new Timestamp(System.currentTimeMillis()));

		// 获取session
		Session session = HibernateUtil.getSession();
		// 开启事务
		Transaction ts = session.beginTransaction();
		try {
			// 执行新增
			session.save(e);
			// 提交事务
			ts.commit();
		} catch (HibernateException e1) {
			e1.printStackTrace();
			// 回滚事务
			ts.rollback();
		} finally {
			session.close();
		}
	}

	/**
	 * 根据ID查询emp
	 */
	@Test
	public void findById() {
		Session session = HibernateUtil.getSession();
		Empemp = (Emp) session.get(Emp.class, 201);
		System.out.println(emp.getName());
		System.out.println(emp.getBirthday());
		System.out.println(emp.getLastLoginTime());
		session.close();
	}

	/**
	 * 修改emp
	 */
	@Test
	public void update() {
		Session session = HibernateUtil.getSession();
		// 查询要修改的数据
		Empemp = (Emp) session.get(Emp.class, 42);
		// 开启事务
		Transaction ts = session.beginTransaction();
		try {
			// 模拟修改数据
			emp.setName("ee");
			emp.setAge(20);
			// 执行修改
			session.update(emp);
			// 提交事务
			ts.commit();
		} catch (HibernateException e) {
			e.printStackTrace();
			// 回滚事务
			ts.rollback();
		} finally {
			// 关闭连接
			session.close();
		}
	}

	/**
	 * 删除emp
	 */
	@Test
	public void delete() {
		Session session = HibernateUtil.getSession();
		Empemp = (Emp) session.get(Emp.class, 148);
		Transaction ts = session.beginTransaction();
		try {
			session.delete(emp);
			ts.commit();
		} catch (HibernateException e) {
			e.printStackTrace();
			ts.rollback();
		} finally {
			session.close();
		}
	}

	/**
	 * 查询全部emp
	 */
	@Test
	public void findAll() {
		String hql = "from Emp";
		Session session = HibernateUtil.getSession();
		Query query = session.createQuery(hql);
		List<Emp>emps = query.list();
		for (Emp e : emps) {
			System.out.println(e.getName());
		}
		session.close();
	}

}

步骤九:测试

以JUNIT方式运行上面的每一个测试方法,并观察控制台输出的SQL。

1.4 完整代码

以下是本案例的完整代码。

其中建表语句完整代码如下:

CREATE TABLE EMP(
  ID			NUMBER(4) CONSTRAINT EMP_ID_PK PRIMARY KEY,
  NAME		VARCHAR(50)  NOT NULL,
  AGE		NUMBER(11),
  SALARY		NUMBER(7,2),
  MARRY 		CHAR(1),
  BIRTHDAY 	DATE,
  LAST_LOGIN_TIME	DATE
  );

CREATE SEQUENCE emp_seq;

主配置文件hibernate.cfg.xml完整代码如下:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
		"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
		"/hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
	<session-factory>
		<!-- 数据库连接信息,根据自己的数据库进行配置 -->
		<property name="connection.url">
			jdbc:oracle:thin:@localhost:1521:xe
		</property>
		<property name="connection.username">lhh</property>
		<property name="connection.password">123456</property>
		<property name="connection.driver_class">
			oracle.jdbc.OracleDriver
		</property>
		
		<!-- Hibernate配置信息 -->
		<!-- dialect方言,用于配置生成针对哪个数据库的SQL语句 -->
		<property name="dialect">
			<!-- 方言类,Hibernate提供的,用于封装某种特定数据库的方言 -->
			org.hibernate.dialect.OracleDialect
		</property>
		<!-- Hibernate生成的SQL是否输出到控制台 -->
		<property name="show_sql">true</property>
		<!-- 将SQL输出时是否格式化 -->
		<property name="format_sql">true</property>
		
		<!--声明映射关系文件 -->
		<mapping resource="com/tarena/entity/Emp.hbm.xml" />
	</session-factory>
</hibernate-configuration>

实体类Emp.java完整代码如下:

packagecom.tarena.entity;

importjava.sql.Date;
importjava.sql.Timestamp;

public class Emp {

	private Integer id;
	private String name;
	private Integer age;
	private Double salary;
	private Boolean marry;
	private Date birthday;
	private Timestamp lastLoginTime;

	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;
	}

	public Integer getAge() {
		return age;
	}

	public void setAge(Integer age) {
		this.age = age;
	}

	public Double getSalary() {
		return salary;
	}

	public void setSalary(Double salary) {
		this.salary = salary;
	}

	public Boolean getMarry() {
		return marry;
	}

	public void setMarry(Boolean marry) {
		this.marry = marry;
	}

	public Date getBirthday() {
		return birthday;
	}

	public void setBirthday(Date birthday) {
		this.birthday = birthday;
	}

	public Timestamp getLastLoginTime() {
		returnlastLoginTime;
	}

	public void setLastLoginTime(Timestamp lastLoginTime) {
		this.lastLoginTime = lastLoginTime;
	}

}

映射关系文件Emp.hbm.xml完整代码如下:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
	"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
	"/hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
	<!-- 配置实体类和表的关系 -->
	<class name="com.tarena.entity.Emp" table="emp">
		<!-- 配置主键属性和字段的关系 -->
		<id name="id" type="java.lang.Integer" column="id">
			<!-- 用来指明主键的生成方式 -->
			<generator class="sequence">
				<!-- 指定用于生成主键的sequence -->
				<param name="sequence">emp_seq</param>
			</generator>
		</id>
		
		<!-- 配置实体类中属性与表中字段的关系 -->
		<property name="name" 
			type="java.lang.String" column="name"/>
		<property name="age" 
			type="java.lang.Integer" column="age"/>
		<property name="salary" 
			type="java.lang.Double" column="salary"/>
		<property name="birthday" 
			type="java.sql.Date" column="birthday"/>
		<property name="lastLoginTime" 
			type="java.sql.Timestamp" column="last_login_time"/>
	</class>
</hibernate-mapping>

HibernateUtil完整代码如下:

packagecom.tarena.util;

importorg.hibernate.Session;
importorg.hibernate.SessionFactory;
importorg.hibernate.cfg.Configuration;

public class HibernateUtil {

	private static SessionFactorysessionFactory;
	
	static {
		// 加载Hibernate主配置文件
		Configuration conf = new Configuration();
		conf.configure("/hibernate.cfg.xml");
		sessionFactory = conf.buildSessionFactory();
	}

	/**
	 * 创建session
	 */
	public static Session getSession() {
		returnsessionFactory.openSession();
	}
	
	public static void main(String[] args) {
		System.out.println(getSession());
	}

}

JUNIT测试类代码如下:

packagecom.tarena.test;

importjava.sql.Date;
importjava.sql.Timestamp;
importjava.util.List;
importorg.hibernate.HibernateException;
importorg.hibernate.Query;
importorg.hibernate.Session;
importorg.hibernate.Transaction;
importorg.junit.Test;
importcom.tarena.entity.Emp;
importcom.tarena.util.HibernateUtil;

/**
 *	演示Hibernate的基本使用
 */
public class TestEmp {

	/**
	 * 新增emp
	 */
	@Test
	public void add() {
		// 模拟要新增的emp
		Emp e = new Emp();
		e.setName("ggg");
		e.setAge(29);
		e.setMarry(false);
		e.setSalary(8000.00);
		e.setBirthday(Date.valueOf("1983-10-20"));
		e.setLastLoginTime(
			new Timestamp(System.currentTimeMillis()));

		// 获取session
		Session session = HibernateUtil.getSession();
		// 开启事务
		Transaction ts = session.beginTransaction();
		try {
			// 执行新增
			session.save(e);
			// 提交事务
			ts.commit();
		} catch (HibernateException e1) {
			e1.printStackTrace();
			// 回滚事务
			ts.rollback();
		} finally {
			session.close();
		}
	}

	/**
	 * 根据ID查询emp
	 */
	@Test
	public void findById() {
		Session session = HibernateUtil.getSession();
		Empemp = (Emp) session.get(Emp.class, 301);
		System.out.println(emp.getName());
		System.out.println(emp.getBirthday());
		System.out.println(emp.getLastLoginTime());
		session.close();
	}

	/**
	 * 修改emp
	 */
	@Test
	public void update() {
		Session session = HibernateUtil.getSession();
		// 查询要修改的数据
		Empemp = (Emp) session.get(Emp.class, 301);
		// 开启事务
		Transaction ts = session.beginTransaction();
		try {
			// 模拟修改数据
			emp.setName("eee");
			emp.setAge(20);
			// 执行修改
			session.update(emp);
			// 提交事务
			ts.commit();
		} catch (HibernateException e) {
			e.printStackTrace();
			// 回滚事务
			ts.rollback();
		} finally {
			// 关闭连接
			session.close();
		}
	}

	/**
	 * 删除emp
	 */
	@Test
	public void delete() {
		Session session = HibernateUtil.getSession();
		Empemp = (Emp) session.get(Emp.class, 301);
		Transaction ts = session.beginTransaction();
		try {
			session.delete(emp);
			ts.commit();
		} catch (HibernateException e) {
			e.printStackTrace();
			ts.rollback();
		} finally {
			session.close();
		}
	}

	/**
	 * 查询全部emp
	 */
	@Test
	public void findAll() {
		String hql = "from Emp";
		Session session = HibernateUtil.getSession();
		Query query = session.createQuery(hql);
		List<Emp>emps = query.list();
		for (Emp e : emps) {
			System.out.println(e.getName());
		}
		session.close();
	}

}

2 Hibernate映射类型

2.1 问题

使用Hibernate预定义类型配置属性和字段的映射关系。

2.2 方案

将项目HibernateDay01中,Emp.hbm.xml里面每个属性的配置,其type用Hibernate预定义类型来重构。由于Hibernate预定义类型支持布尔值,因此在该配置文件中追加marry属性的配置。

2.3 步骤

实现此案例需要按照如下步骤进行。

步骤一:重构Emp.hbm.xml

重构Emp.hbm.xml,将各个属性的type由Java类型改为Hibernate预定义类型,同时追加marry属性,并使用布尔型来配置该属性,代码如下:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
	"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
	"/hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
	<!--配置实体类和表的关系 -->
	<class name="com.tarena.entity.Emp" table="emp">
		<!--配置主键属性和字段的关系 -->
#cold_bold		<id name="id" type="integer" column="id">
			<!--用来指明主键的生成方式 -->
			<generator class="sequence">
				<!--指定用于生成主键的sequence -->
				<param name="sequence">emp_seq</param>
			</generator>
		</id>
		
		<!--配置实体类中属性与表中字段的关系 -->
#cold_bold		<property name="name" 
#cold_bold			type="string" column="name"/>
#cold_bold		<property name="age" 
#cold_bold			type="integer" column="age"/>
#cold_bold		<property name="salary" 
#cold_bold			type="double" column="salary"/>
#cold_bold		<property name="birthday" 
#cold_bold			type="date" column="birthday"/>
#cold_bold		<property name="lastLoginTime" 
#cold_bold			type="timestamp" column="last_login_time"/>
#cold_bold		<property name="marry"
#cold_bold			type="yes_no" column="marry"/>
	</class>
</hibernate-mapping>

步骤二:测试

再次以JUNIT方式执行测试代码中的每个方法,看控制台输出结果是否正确。

2.4 完整代码

以下是本案例的完整代码。

其中Emp.hbm.xml完整代码如下:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
	"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
	"/hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
	<!-- 配置实体类和表的关系 -->
	<class name="com.tarena.entity.Emp" table="emp">
		<!-- 配置主键属性和字段的关系 -->
		<id name="id" type="integer" column="id">
			<!-- 用来指明主键的生成方式 -->
			<generator class="sequence">
				<!-- 指定用于生成主键的sequence -->
				<param name="sequence">emp_seq</param>
			</generator>
		</id>
		
		<!-- 配置实体类中属性与表中字段的关系 -->
		<property name="name" 
			type="string" column="name"/>
		<property name="age" 
			type="integer" column="age"/>
		<property name="salary" 
			type="double" column="salary"/>
		<property name="birthday" 
			type="date" column="birthday"/>
		<property name="lastLoginTime" 
			type="timestamp" column="last_login_time"/>
		<property name="marry"
			type="yes_no" column="marry"/>
	</class>
</hibernate-mapping>

其他代码不变,此处不再重复。

3 在NETCTOSS中引入Hibernate

3.1 问题

将Hibernate框架引入到NETCTOSS。

3.2 方案

将Hibernate框架引入到NETCTOSS,以保证在项目中可以使用Hibernate来进行数据库访问。根据Hibernate的使用步骤,我们需要在项目中引入Hibernate开发包、主配置文件,并创建HibernateUtil工具类。

3.3 步骤

实现此案例需要按照如下步骤进行。

步骤一:导包

在NETCTOSS项目中,导入Hibernate开发包,导入后项目的包结构如下图:

图-2

步骤二:引入主配置文件

将Hibernate主配置文件引入到项目中,放于src根路径下,该文件可以从HibernateDay01项目中直接复制过来,并将声明映射关系文件部分代码去掉,代码如下:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
		"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
		"/hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
	<session-factory>
		<!--数据库连接信息,根据自己的数据库进行配置 -->
		<property name="connection.url">
			jdbc:oracle:thin:@localhost:1521:xe
		</property>
		<property name="connection.username">lhh</property>
		<property name="connection.password">123456</property>
		<property name="connection.driver_class">
			oracle.jdbc.OracleDriver
		</property>
		
		<!-- Hibernate配置信息 -->
		<!-- dialect方言,用于配置生成针对哪个数据库的SQL语句 -->
		<property name="dialect">
			<!--方言类,Hibernate提供的,用于封装某种特定数据库的方言 -->
			org.hibernate.dialect.OracleDialect
		</property>
		<!-- Hibernate生成的SQL是否输出到控制台 -->
		<property name="show_sql">true</property>
		<!--将SQL输出时是否格式化 -->
		<property name="format_sql">true</property>
		
	</session-factory>
</hibernate-configuration>

步骤三:创建HibernateUtil工具类

在com.netctoss.util包下,创建HibernateUtil工具类,该类可以直接从HibernateDay01项目中复制过来,代码如下:

packagecom.netctoss.util;

importorg.hibernate.Session;
importorg.hibernate.SessionFactory;
importorg.hibernate.cfg.Configuration;

public class HibernateUtil {

	private static SessionFactorysessionFactory;
	
	static {
		// 加载Hibernate主配置文件
		Configuration conf = new Configuration();
		conf.configure("/hibernate.cfg.xml");
		sessionFactory = conf.buildSessionFactory();
	}

	/**
	 * 创建session
	 */
	public static Session getSession() {
		returnsessionFactory.openSession();
	}
	
	public static void main(String[] args) {
		System.out.println(getSession());
	}

}

3.4 完整代码

下面是本案例的完整代码。

其中主配置文件完整代码如下:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
		"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
		"/hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
	<session-factory>
		<!-- 数据库连接信息,根据自己的数据库进行配置 -->
		<property name="connection.url">
			jdbc:oracle:thin:@localhost:1521:xe
		</property>
		<property name="connection.username">lhh</property>
		<property name="connection.password">123456</property>
		<property name="connection.driver_class">
			oracle.jdbc.OracleDriver
		</property>
		
		<!-- Hibernate配置信息 -->
		<!-- dialect方言,用于配置生成针对哪个数据库的SQL语句 -->
		<property name="dialect">
			<!-- 方言类,Hibernate提供的,用于封装某种特定数据库的方言 -->
			org.hibernate.dialect.OracleDialect
		</property>
		<!-- Hibernate生成的SQL是否输出到控制台 -->
		<property name="show_sql">true</property>
		<!-- 将SQL输出时是否格式化 -->
		<property name="format_sql">true</property>
		
	</session-factory>
</hibernate-configuration>

HibernateUtil工具类完整代码如下:

packagecom.netctoss.util;

importorg.hibernate.Session;
importorg.hibernate.SessionFactory;
importorg.hibernate.cfg.Configuration;

public class HibernateUtil {

	private static SessionFactorysessionFactory;
	
	static {
		// 加载Hibernate主配置文件
		Configuration conf = new Configuration();
		conf.configure("/hibernate.cfg.xml");
		sessionFactory = conf.buildSessionFactory();
	}

	/**
	 * 创建session
	 */
	public static Session getSession() {
		returnsessionFactory.openSession();
	}
	
	public static void main(String[] args) {
		System.out.println(getSession());
	}

}

4 使用Hibernate重构资费DAO

4.1 问题

使用Hibernate重构资费DAO的实现类。

4.2 方案

使用Hibernate的增删改查API,重构资费DAO的实现类。

4.3 步骤

实现此案例需要按照如下步骤进行。

步骤一:创建资费的映射关系文件

在com.netctoss.entity包下,创建资费的映射关系文件,名为Cost.hbm.xml,代码如下:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
	"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
	"/hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
	<class name="com.netctoss.entity.Cost" table="cost">
		<id name="id" type="integer" column="id">
			<!--用来指明主键的生成方式 -->
			<generator class="sequence">
				<param name="sequence">cost_seq</param>
			</generator>
		</id>
		
		<property name="name" 
			type="string" column="name" />
		<property name="baseDuration" 
			type="integer" column="base_duration" />
		<property name="baseCost" 
			type="double" column="base_cost" />
		<property name="unitCost" 
			type="double" column="unit_cost" />
		<property name="status" 
			type="string" column="status" />
		<property name="descr" 
			type="string" column="descr" />
		<property name="createTime" 
			type="date" column="creatime" />
		<property name="startTime" 
			type="date" column="startime" />
		<property name="costType" 
			type="string" column="cost_type" />
	</class>
</hibernate-mapping>

步骤二:声明映射关系文件

在hibernate.cfg.xml中声明映射关系文件,代码如下:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
		"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
		"/hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
	<session-factory>
		<!--数据库连接信息,根据自己的数据库进行配置 -->
		<property name="connection.url">
			jdbc:oracle:thin:@localhost:1521:xe
		</property>
		<property name="connection.username">lhh</property>
		<property name="connection.password">123456</property>
		<property name="connection.driver_class">
			oracle.jdbc.OracleDriver
		</property>
		
		<!-- Hibernate配置信息 -->
		<!-- dialect方言,用于配置生成针对哪个数据库的SQL语句 -->
		<property name="dialect">
			<!--方言类,Hibernate提供的,用于封装某种特定数据库的方言 -->
			org.hibernate.dialect.OracleDialect
		</property>
		<!-- Hibernate生成的SQL是否输出到控制台 -->
		<property name="show_sql">true</property>
		<!--将SQL输出时是否格式化 -->
		<property name="format_sql">true</property>
		
#cold_bold		<!--在配置文件中关联映射文件 -->
#cold_bold		<mapping resource="com/netctoss/entity/Cost.hbm.xml" />
	</session-factory>
</hibernate-configuration>

步骤三:使用Hibernate重构CostDaoImpl

使用HibernateUtil的增删改查API,来重构CostDaoImpl,代码如下:

packagecom.netctoss.dao;

importjava.util.List;
importorg.hibernate.HibernateException;
importorg.hibernate.Query;
importorg.hibernate.Session;
importorg.hibernate.Transaction;
importcom.netctoss.entity.Cost;
importcom.netctoss.util.HibernateUtil;

/**
 *	当前阶段学习重点是Struts2,对于DAO的实现就模拟实现了。
 *	同学们可以使用JDBC/MyBatis自行实现该DAO。
 */
public class CostDaoImpl implements ICostDao {

	@Override
	public List<Cost>findAll() {
#cold_bold		String hql = "from Cost";
#cold_bold		Session session = HibernateUtil.getSession();
#cold_bold		Query query = session.createQuery(hql);
#cold_bold		List<Cost> list = query.list();
#cold_bold		session.close();
#cold_bold		return list;
	}

	@Override
	public void delete(int id) {
#cold_bold		Cost cost = new Cost();
#cold_bold		cost.setId(id);
#cold_bold
#cold_bold		Session session = HibernateUtil.getSession();
#cold_bold		Transaction ts = session.beginTransaction();
#cold_bold		try {
#cold_bold			session.delete(cost);
#cold_bold			ts.commit();
#cold_bold		} catch (HibernateException e) {
#cold_bold			e.printStackTrace();
#cold_bold			ts.rollback();
#cold_bold		} finally {
#cold_bold			session.close();
#cold_bold		}
	}

	@Override
	public Cost findByName(String name) {
		// 模拟根据名称查询资费数据,假设资费表中只有一条名为tarena的数据
		if("tarena".equals(name)) {
			Cost c = new Cost();
			c.setId(97);
			c.setName("tarena");
			c.setBaseDuration(99);
			c.setBaseCost(9.9);
			c.setUnitCost(0.9);
			c.setDescr("tarena套餐");
			c.setStatus("0");
			c.setCostType("2");
			return c;
		}
		return null;
	}

	@Override
	public Cost findById(int id) {
#cold_bold		Session session = HibernateUtil.getSession();
#cold_bold		Cost cost = (Cost) session.get(Cost.class, id);
#cold_bold		session.close();
#cold_bold		return cost;
	}

}

注:目前我们还没学习有条件的查询,因此先不重构findByName方法。

步骤四:测试

重新部署项目,并重启tomcat,访问资费模块,对其各功能进行测试。

4.4 完整代码

下面是本案例的完整代码。

其中映射关系文件完整代码如下:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
	"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
	"/hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
	<class name="com.netctoss.entity.Cost" table="cost">
		<id name="id" type="integer" column="id">
			<!-- 用来指明主键的生成方式 -->
			<generator class="sequence">
				<param name="sequence">cost_seq</param>
			</generator>
		</id>
		
		<property name="name" 
			type="string" column="name" />
		<property name="baseDuration" 
			type="integer" column="base_duration" />
		<property name="baseCost" 
			type="double" column="base_cost" />
		<property name="unitCost" 
			type="double" column="unit_cost" />
		<property name="status" 
			type="string" column="status" />
		<property name="descr" 
			type="string" column="descr" />
		<property name="createTime" 
			type="date" column="creatime" />
		<property name="startTime" 
			type="date" column="startime" />
		<property name="costType" 
			type="string" column="cost_type" />
	</class>
</hibernate-mapping>

主配置文件完整代码如下:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
		"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
		"/hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
	<session-factory>
		<!-- 数据库连接信息,根据自己的数据库进行配置 -->
		<property name="connection.url">
			jdbc:oracle:thin:@localhost:1521:xe
		</property>
		<property name="connection.username">lhh</property>
		<property name="connection.password">123456</property>
		<property name="connection.driver_class">
			oracle.jdbc.OracleDriver
		</property>
		
		<!-- Hibernate配置信息 -->
		<!-- dialect方言,用于配置生成针对哪个数据库的SQL语句 -->
		<property name="dialect">
			<!-- 方言类,Hibernate提供的,用于封装某种特定数据库的方言 -->
			org.hibernate.dialect.OracleDialect
		</property>
		<!-- Hibernate生成的SQL是否输出到控制台 -->
		<property name="show_sql">true</property>
		<!-- 将SQL输出时是否格式化 -->
		<property name="format_sql">true</property>
		
		<!-- 在配置文件中关联映射文件 -->
		<mapping resource="com/netctoss/entity/Cost.hbm.xml" />
	</session-factory>
</hibernate-configuration>

CostDaoImpl完整代码如下:

packagecom.netctoss.dao;

importjava.util.List;
importorg.hibernate.HibernateException;
importorg.hibernate.Query;
importorg.hibernate.Session;
importorg.hibernate.Transaction;
importcom.netctoss.entity.Cost;
importcom.netctoss.util.HibernateUtil;

/**
 *	当前阶段学习重点是Struts2,对于DAO的实现就模拟实现了。
 *	同学们可以使用JDBC/MyBatis自行实现该DAO。
 */
public class CostDaoImpl implements ICostDao {

	@Override
	public List<Cost>findAll() {
		String hql = "from Cost";
		Session session = HibernateUtil.getSession();
		Query query = session.createQuery(hql);
		List<Cost> list = query.list();
		session.close();
		return list;
	}

	@Override
	public void delete(int id) {
		Cost cost = new Cost();
		cost.setId(id);

		Session session = HibernateUtil.getSession();
		Transaction ts = session.beginTransaction();
		try {
			session.delete(cost);
			ts.commit();
		} catch (HibernateException e) {
			e.printStackTrace();
			ts.rollback();
		} finally {
			session.close();
		}
	}

	@Override
	public Cost findByName(String name) {
		// 模拟根据名称查询资费数据,假设资费表中只有一条名为tarena的数据
		if("tarena".equals(name)) {
			Cost c = new Cost();
			c.setId(97);
			c.setName("tarena");
			c.setBaseDuration(99);
			c.setBaseCost(9.9);
			c.setUnitCost(0.9);
			c.setDescr("tarena套餐");
			c.setStatus("0");
			c.setCostType("2");
			return c;
		}
		return null;
	}

	@Override
	public Cost findById(int id) {
		Session session = HibernateUtil.getSession();
		Cost cost = (Cost) session.get(Cost.class, id);
		session.close();
		return cost;
	}

}