在JavaEE中使用Hibernate框架
我们必须要了解一些Hibernate基础对象,如下:
配置对象
配置对象是你在任何 Hibernate 应用程序中创造的第一个 Hibernate 对象,并且经常只在应用程序初始化期间创造。它代表了 Hibernate 所需一个配置或属性文件。配置对象提供了两种基础组件。
数据库连接:由 Hibernate 支持的一个或多个配置文件处理。这些文件是 hibernate.properties 和 hibernate.cfg.xml。
类映射设置:这个组件创造了 Java 类和数据库表格之间的联系。
SessionFactory 对象
配置对象被用于创造一个 SessionFactory 对象,使用提供的配置文件为应用程序依次配置 Hibernate,并允许实例化一个会话对象。SessionFactory 是一个线程安全对象并由应用程序所有的线程所使用。SessionFactory 是一个重量级对象所以通常它都是在应用程序启动时创造然后留存为以后使用。每个数据库需要一个 SessionFactory 对象使用一个单独的配置文件。所以如果你使用多种数据库那么你要创造多种 SessionFactory 对象。
Session 对象
一个会话被用于与数据库的物理连接。Session 对象是轻量级的,并被设计为每次实例化都需要与数据库的交互。持久对象通过 Session 对象保存和检索。Session 对象不应该长时间保持开启状态因为它们通常情况下并非线程安全,并且它们应该按照所需创造和销毁。
Transaction 对象
一个事务代表了与数据库工作的一个单元并且大部分 RDBMS 支持事务功能。在 Hibernate 中事务由底层事务管理器和事务(来自 JDBC 或者 JTA)处理。这是一个选择性对象,Hibernate 应用程序可能不选择使用这个接口,而是在自己应用程序代码中管理事务。
Query 对象
Query 对象使用 SQL 或者 Hibernate 查询语言(HQL)字符串在数据库中来检索数据并创造对象。一个查询的实例被用于连结查询参数,限制由查询返回的结果数量,并最终执行查询。
Criteria 对象
Criteria 对象被用于创造和执行面向规则查询的对象来检索对象。
调用一个java方法需要正确的传递方法参数,那么使用框架就是引用别人封装好的jar包,按照别人规定好的方式进行配置并调用jar包里的各种方法。只要是合格的Java程序员都会引用jar包,只是不知道Hibernate官方提供的jar包哪些是必须引用的,哪些是扩展的。Hibernate官方提供了对jar包的说明,这里不再赘述。关键是怎样写好官方规定的配置文件,这是使用框架的重点
下面展示怎样使用Hibernate框架,关键是配置文件
(重点一:)Hibernate 需要事先知道在哪里找到映射信息,这些映射信息定义了 Java 类怎样关联到数据库表。(重点二:)Hibernate 也需要一套相关数据库和其它相关参数的配置设置。所有这些信息通常是作为一个标准的 Java 属性文件提供的,名叫 hibernate.properties。又或者是作为 XML 文件提供的,名叫 hibernate.cfg.xml。
我们将考虑 hibernate.cfg.xml 这个 XML 格式文件,来决定在我的例子里指定需要的 Hibernate 应用属性。这个 XML 文件中大多数的属性是不需要修改的。这个文件保存在应用程序的类路径的根目录里。
下面逐个贴出项目中各个文件的内容供大家参考
普通的pojo,没啥好说的
public class Employee {
private int id;
private String firstName;
private String lastName;
private int salary; public Employee() {}
public Employee(int id,String fname, String lname, int salary) {
this.id = id;
this.firstName = fname;
this.lastName = lname;
this.salary = salary;
}
public int getId() {
return id;
}
//省略getter、setter方法
}
Employee类
(重点一:)数据库表和对象之间的映射关系
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping>
<class name="com.wenji.entity.Employee" table="HTCPP.EMPLOYEE">
<meta attribute="class-description">
This class contains the employee detail.
</meta>
<id name="id" type="int" column="id">
</id>
<property name="firstName" column="first_name" type="string"/>
<property name="lastName" column="last_name" type="string"/>
<property name="salary" column="salary" type="int"/>
</class>
</hibernate-mapping>
映射文件
一个对象/关系型映射一般定义在 XML 文件中。映射文件指示 Hibernate 如何将已经定义的类或类组与数据库中的表对应起来。
尽管有些 Hibernate 用户选择手写 XML 文件,但是有很多工具可以用来给先进的 Hibernate 用户生成映射文件。这样的工具包括 XDoclet, Middlegen 和 AndroMDA。
让我们来考虑我们之前定义的 POJO 类,它的对象将延续到下一部分定义的表中。
create table EMPLOYEE(
ID INTEGER not null,
FIRST_NAME VARCHAR2(10),
LAST_NAME VARCHAR2(10),
SALARY INTEGER
)
你需要以格式 <classname>.hbm.xml
保存映射文件。我们保存映射文件在 Employee.hbm.xml 中。让我们来详细地看一下在映射文件中使用的一些标签:
- 映射文件是一个以
<hibernate-mapping>
为根元素的 XML 文件,里面包含所有<class>
标签。 <class>
标签是用来定义从一个 Java 类到数据库表的特定映射。Java 的类名使用 name 属性来表示,数据库表明用 table 属性来表示。<meta>
标签是一个可选元素,可以被用来修饰类。<id>
标签将类中独一无二的 ID 属性与数据库表中的主键关联起来。id 元素中的 name 属性引用类的性质,column 属性引用数据库表的列。type 属性保存 Hibernate 映射的类型,这个类型会将从 Java 转换成 SQL 数据类型。- 在 id 元素中的
<generator>
标签用来自动生成主键值。设置 generator 标签中的 class 属性可以设置 native 使 Hibernate 可以使用 identity, sequence 或 hilo 算法根据底层数据库的情况来创建主键。 <property>
标签用来将 Java 类的属性与数据库表的列匹配。标签中 name 属性引用的是类的性质,column 属性引用的是数据库表的列。type 属性保存 Hibernate 映射的类型,这个类型会将从 Java 转换成 SQL 数据类型。
还有一些其它属性和元素可用在映射文件中。
(重点二:)数据库各项参数配置
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-configuration SYSTEM
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"> <hibernate-configuration>
<session-factory>
<property name="hibernate.dialect">org.hibernate.dialect.Oracle9Dialect</property>
<property name="hibernate.connection.driver_class">oracle.jdbc.driver.OracleDriver</property> <!-- Assume test is the database name -->
<property name="hibernate.connection.url"> jdbc:oracle:thin:@localhost:1521:orcl</property>
<property name="hibernate.connection.username">system</property>
<property name="connection.password">123456</property>
<property name="show_sql">true</property> <!-- List of XML mapping files -->
<mapping resource="com/wenji/mapping/Employee.hbm.xml"/> </session-factory>
</hibernate-configuration>
hibernate.dialect:这个属性使 Hibernate 应用为被选择的数据库生成适当的 SQL。
hibernate.connection.driver_class:JDBC 驱动程序类。
hibernate.connection.url:数据库实例的 JDBC URL。
hibernate.connection.username:数据库用户名。
hibernate.connection.password:数据库密码。
hibernate.connection.pool_size:限制在 Hibernate 应用数据库连接池中连接的数量。
hibernate.connection.autocommit:允许在 JDBC 连接中使用自动提交模式。
调用jar包封装的方法
package com.wenji.test; import java.util.List;
import java.util.Date;
import java.util.Iterator; import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration; import com.wenji.entity.Employee; public class ManageEmployee {
private static SessionFactory factory;
public static void main(String[] args) {
try{
// 调用Configuration类的buildSessionFactory()方法:
factory = new Configuration().configure().buildSessionFactory();
}catch (Throwable ex) {
System.err.println("Failed to create sessionFactory object." + ex);
throw new ExceptionInInitializerError(ex);
}
ManageEmployee ME = new ManageEmployee(); /* Add few employee records in database */
// Integer empID1 = ME.addEmployee(1,"Zara", "Ali", 1000);
// Integer empID2 = ME.addEmployee(2,"Daisy", "Das", 5000);
// Integer empID3 = ME.addEmployee(3,"John", "Paul", 10000); /* List down all the employees */
ME.listEmployees(); /* Update employee's records */
// ME.updateEmployee(empID1, 5000); /* Delete an employee from the database */
// ME.deleteEmployee(empID2); /* List down new list of the employees */
// ME.listEmployees();
}
/* Method to CREATE an employee in the database */
public Integer addEmployee(int id,String fname, String lname, int salary){
Session session = factory.openSession();
Transaction tx = null;
Integer employeeID = null;
try{
tx = session.beginTransaction();
Employee employee = new Employee(id,fname, lname, salary);
employeeID = (Integer) session.save(employee);
tx.commit();
}catch (HibernateException e) {
if (tx!=null) tx.rollback();
e.printStackTrace();
}finally {
session.close();
}
return employeeID;
}
/* Method to READ all the employees */
public void listEmployees( ){
Session session = factory.openSession();
Transaction tx = null;
try{
tx = session.beginTransaction();
List employees = session.createQuery("FROM Employee").list();
for (Iterator iterator =
employees.iterator(); iterator.hasNext();){
Employee employee = (Employee) iterator.next();
System.out.print("First Name: " + employee.getFirstName());
System.out.print(" Last Name: " + employee.getLastName());
System.out.println(" Salary: " + employee.getSalary());
}
tx.commit();
}catch (HibernateException e) {
if (tx!=null) tx.rollback();
e.printStackTrace();
}finally {
session.close();
}
}
/* Method to UPDATE salary for an employee */
public void updateEmployee(Integer EmployeeID, int salary ){
Session session = factory.openSession();
Transaction tx = null;
try{
tx = session.beginTransaction();
Employee employee =
(Employee)session.get(Employee.class, EmployeeID);
employee.setSalary( salary );
session.update(employee);
tx.commit();
}catch (HibernateException e) {
if (tx!=null) tx.rollback();
e.printStackTrace();
}finally {
session.close();
}
}
/* Method to DELETE an employee from the records */
public void deleteEmployee(Integer EmployeeID){
Session session = factory.openSession();
Transaction tx = null;
try{
tx = session.beginTransaction();
Employee employee =
(Employee)session.get(Employee.class, EmployeeID);
session.delete(employee);
tx.commit();
}catch (HibernateException e) {
if (tx!=null) tx.rollback();
e.printStackTrace();
}finally {
session.close();
}
}
}
测试方法
会话
Session 用于获取与数据库的物理连接。 Session 对象是轻量级的,并且设计为在每次需要与数据库进行交互时被实例化。持久态对象被保存,并通过 Session 对象检索找回。
该 Session 对象不应该长时间保持开放状态,因为它们通常不能保证线程安全,而应该根据需求被创建和销毁。Session 的主要功能是为映射实体类的实例提供创建,读取和删除操作。这些实例可能在给定时间点时存在于以下三种状态之一:
- 瞬时状态: 一种新的持久性实例,被 Hibernate 认为是瞬时的,它不与 Session 相关联,在数据库中没有与之关联的记录且无标识符值。
- 持久状态:可以将一个瞬时状态实例通过与一个 Session 关联的方式将其转化为持久状态实例。持久状态实例在数据库中没有与之关联的记录,有标识符值,并与一个 Session 关联。
- 脱管状态:一旦关闭 Hibernate Session,持久状态实例将会成为脱管状态实例。
若 Session 实例的持久态类别是序列化的,则该 Session 实例是序列化的。一个典型的事务应该使用以下语法:
Session session = factory.openSession();
Transaction tx = null;
try {
tx = session.beginTransaction();
// do some work
...
tx.commit();
}
catch (Exception e) {
if (tx!=null) tx.rollback();
e.printStackTrace();
}finally {
session.close();
}
如果 Session 引发异常,则事务必须被回滚,该 session 必须被丢弃。
Session 接口提供了很多方法,但在示例中仅展示几个重要方法。可以查看 Hibernate 文件,查询与 Session 及 SessionFactory 相关的完整方法目录
到现在为止,你已经看到 Hibernate 如何使用 XML 映射文件来完成从 POJO 到数据库表的数据转换的,反之亦然。Hibernate 注释是无需使用 XML 文件来定义映射的最新方法。你可以额外使用注释或直接代替 XML 映射元数据。
Hibernate 注释是一种强大的来给对象和关系映射表提供元数据的方法。所有的元数据被添加到 POJO java 文件代码中,这有利于用户在开发时更好的理解表的结构和 POJO。
如果你想让你的应用程序移植到其它 EJB 3 的 ORM 应用程序中,您必须使用注释来表示映射信息,但是如果想要得到更大的灵活性,那么你应该使用基于 XML 的映射。
Hibernate 注释的环境设置
首先你必须确定你使用的是 JDK 5.0,否则你需要升级你的 JDK 至 JDK 5.0,来使你的主机能够支持注释。
其次,你需要安装 Hibernate 注释包,可以从 sourceforge 行下载:(下载 Hibernate 注释) 并且从 Hibernate 注释发布中拷贝 hibernate-annotations.jar, lib/hibernate-comons-annotations.jar 和 lib/ejb3-persistence.jar 到你的 CLASSPATH。
项目结构如下,和之前的项目结构相比,少了Employee.hbm.xml,这个xml文件是用来描述数据库表与java对象的映射关系的,那么这个文件被谁替代了呢?
下面逐个贴出项目中各个文件的内容供大家参考
package com.wenji.entity; import javax.persistence.*; @Entity
@Table(name = "htcpp.EMPLOYEE")
public class Employee {
@Id
@Column(name = "id")
private int id; @Column(name = "first_name")
private String firstName; @Column(name = "last_name")
private String lastName; @Column(name = "salary")
private int salary; public Employee() {}
public Employee(int id,String fname, String lname, int salary) {
this.id = id;
this.firstName = fname;
this.lastName = lname;
this.salary = salary;
}
//省略getter、setter方法
}
@Entity 注释
EJB 3 标准的注释包含在 javax.persistence 包,所以我们第一步需要导入这个包。第二步我们对 Employee 类使用 @Entity 注释,标志着这个类为一个实体 bean,所以它必须含有一个没有参数的构造函数并且在可保护范围是可见的。
@Table 注释
@table 注释允许您明确表的详细信息保证实体在数据库中持续存在。
@table 注释提供了四个属性,允许您覆盖的表的名称,目录及其模式,在表中可以对列制定独特的约束。现在我们使用的是表名为 EMPLOYEE。
@Id 和 @GeneratedValue 注释
每一个实体 bean 都有一个主键,你在类中可以用 @Id 来进行注释。主键可以是一个字段或者是多个字段的组合,这取决于你的表的结构。
默认情况下,@Id 注释将自动确定最合适的主键生成策略,但是你可以通过使用 @GeneratedValue 注释来覆盖掉它。strategy 和 generator 这两个参数我不打算在这里讨论,所以我们只使用默认键生成策略。让 Hibernate 确定使用哪些生成器类型来使代码移植于不同的数据库之间。
@Column Annotation
@Column 注释用于指定某一列与某一个字段或是属性映射的细节信息。您可以使用下列注释的最常用的属性:
name 属性允许显式地指定列的名称。
length 属性为用于映射一个值,特别为一个字符串值的列的大小。
nullable 属性允许当生成模式时,一个列可以被标记为非空。
unique 属性允许列中只能含有唯一的内容
hibernate.cfg.xml文件和之前相比,注释掉了映射文件的信息
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-configuration SYSTEM
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"> <hibernate-configuration>
<session-factory>
<property name="hibernate.dialect">org.hibernate.dialect.Oracle9Dialect</property>
<property name="hibernate.connection.driver_class">oracle.jdbc.driver.OracleDriver</property> <!-- Assume test is the database name -->
<property name="hibernate.connection.url"> jdbc:oracle:thin:@localhost:1521:orcl</property>
<property name="hibernate.connection.username">system</property>
<property name="connection.password">123456</property>
<property name="show_sql">true</property> <!-- List of XML mapping files -->
<!-- <mapping resource="com/wenji/mapping/Employee.hbm.xml"/> --> </session-factory>
</hibernate-configuration>
和之前的示例方法相比,只有创建factory的方式变了,其他的都一样
package com.wenji.test; import java.util.List;
import java.util.Date;
import java.util.Iterator; import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration; import com.wenji.entity.Employee; public class ManageEmployee {
private static SessionFactory factory;
public static void main(String[] args) {
try{
factory = new AnnotationConfiguration().
configure().
//addPackage("com.xyz") //add package if used.
addAnnotatedClass(Employee.class).
buildSessionFactory();
}catch (Throwable ex) {
System.err.println("Failed to create sessionFactory object." + ex);
throw new ExceptionInInitializerError(ex);
}
ManageEmployee ME = new ManageEmployee(); /* Add few employee records in database */
// Integer empID1 = ME.addEmployee("Zara", "Ali", 1000);
// Integer empID2 = ME.addEmployee("Daisy", "Das", 5000);
// Integer empID3 = ME.addEmployee("John", "Paul", 10000); /* List down all the employees */
ME.listEmployees(); /* Update employee's records */
// ME.updateEmployee(empID1, 5000); /* Delete an employee from the database */
// ME.deleteEmployee(empID2); /* List down new list of the employees */
// ME.listEmployees();
}
/* Method to CREATE an employee in the database */
public Integer addEmployee(String fname, String lname, int salary){
Session session = factory.openSession();
Transaction tx = null;
Integer employeeID = null;
try{
tx = session.beginTransaction();
Employee employee = new Employee();
employee.setFirstName(fname);
employee.setLastName(lname);
employee.setSalary(salary);
employeeID = (Integer) session.save(employee);
tx.commit();
}catch (HibernateException e) {
if (tx!=null) tx.rollback();
e.printStackTrace();
}finally {
session.close();
}
return employeeID;
}
/* Method to READ all the employees */
public void listEmployees( ){
Session session = factory.openSession();
Transaction tx = null;
try{
tx = session.beginTransaction();
List employees = session.createQuery("FROM Employee").list();
for (Iterator iterator =
employees.iterator(); iterator.hasNext();){
Employee employee = (Employee) iterator.next();
System.out.print("First Name: " + employee.getFirstName());
System.out.print(" Last Name: " + employee.getLastName());
System.out.println(" Salary: " + employee.getSalary());
}
tx.commit();
}catch (HibernateException e) {
if (tx!=null) tx.rollback();
e.printStackTrace();
}finally {
session.close();
}
}
/* Method to UPDATE salary for an employee */
public void updateEmployee(Integer EmployeeID, int salary ){
Session session = factory.openSession();
Transaction tx = null;
try{
tx = session.beginTransaction();
Employee employee =
(Employee)session.get(Employee.class, EmployeeID);
employee.setSalary( salary );
session.update(employee);
tx.commit();
}catch (HibernateException e) {
if (tx!=null) tx.rollback();
e.printStackTrace();
}finally {
session.close();
}
}
/* Method to DELETE an employee from the records */
public void deleteEmployee(Integer EmployeeID){
Session session = factory.openSession();
Transaction tx = null;
try{
tx = session.beginTransaction();
Employee employee =
(Employee)session.get(Employee.class, EmployeeID);
session.delete(employee);
tx.commit();
}catch (HibernateException e) {
if (tx!=null) tx.rollback();
e.printStackTrace();
}finally {
session.close();
}
}
}
测试方法
在JavaEE中使用Hibernate框架的更多相关文章
- javaEE中的hibernate配置笔记
0 从web.xml出发 项目中用Spring整合Hibernate,Spring贯穿整个项目,所以先看看Spring在哪一步整合了Hibernate.先看部分web.xml. 在context-pa ...
- 在JavaEE中使用Mybatis框架
MyBatis 使用简单的 XML 或注解用于配置和原始映射,将接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java 对象)映射成数据库中的记录.每个MyB ...
- 粗浅看Struts2和Hibernate框架
----------------------------------------------------------------------------------------------[版权申明: ...
- (转)Hibernate框架基础——Java对象持久化概述
http://blog.csdn.net/yerenyuan_pku/article/details/52732990 Java对象持久化概述 应用程序的分层体系结构 基于B/S的典型三层架构 说明 ...
- JavaWeb_(Spring框架)在Struts+Hibernate框架中引入Spring框架
spring的功能:简单来说就是帮我们new对象,什么时候new对象好,什么时候销毁对象. 在MySQL中添加spring数据库,添加user表,并添加一条用户数据 使用struts + hibern ...
- ECLIPSE/JAVAWEB (二)三大框架之Hibernate框架 持续更新中...
(一)发展历史 在Struts框架中使用jdbc连接来读写数据库,我们最常见的就是打开数据库连接.使用复杂的sql语句进行读写.关闭连接,获得的数据又需要转换或封装后往外传,这是一个非常繁琐的过程. ...
- hibernate框架中注意的几个问题
使用hibernate框架中,session.createSQLQuery创建sql语句的时候遇到的问题 1. select e.id,d.id from emp e,dept d where e. ...
- 关于HttpSession 和 Hibernate框架中 session异同点的简单解析
快速理解: HttpSession中的session是一个容器用来盛基于会话机制的信息. 比喻:我把钱放进银行的保险柜里. 解析:我的钱就是我的信息,ID等 银行的保险柜就是session容器. Hi ...
- 在Eclipse中使用Struts和Hibernate框架搭建Maven Web项目
前言 学习使用Java还是2012年的事情,刚开始学习的Java的时候,使用的是MyEclipse工具和SSH框架.初学者适合使用MyEclipse,因为他将struts.Spring和Hiberna ...
随机推荐
- linux学习笔记整理(八)
第九章 文件的归档和压缩本节所讲内容:9.1 tar命令进行文件的归档和压缩9.2 zip管理压缩文件9.3 了解gzip-bzip2- xz管理压缩文件-file-sort查看文件 9.1 tar命 ...
- django如何语法高亮模块
首先,django的语法高亮必须配合markdown模块使用. 注意事项: 确保在渲染文本时添加了 markdown.extensions.codehilite 拓展 确保安装了 Pygments. ...
- logistic回归和最大熵
回顾发现,李航的<统计学习方法>有些章节还没看完,为了记录,特意再水一文. 0 - logistic分布 如<统计学习方法>书上,设X是连续随机变量,X服从logistic分布 ...
- mysql查询表结果排序
要求:将数据表tab1中DeviceName为‘XI003’,'DO107'的数据放在查询结果的前面,同时对其他查询结果进行降序排序 sql语句: SELECT DISTINCT DeviceName ...
- Java消息中间件入门笔记 - ActiveMQ篇
入门 消息中间件带来的好处: 1)解耦:系统解耦 2)异步:异步执行 3)横向扩展 4)安全可靠 5)顺序保证 栗子: 通过服务调用让其它系统感知事件发生 系统之间高耦合 程序执行效率低 通过消息中间 ...
- 北京教育软件创业公司招 .net工程师
北京教育软件创业公司,招 .net工程师,月工资2万左右,有合适的朋友帮忙推荐下,要求水平稍高一些的.产品目前用Winform开发的.创始人两个清华,一个北大.老板在美国待了七年回来的,爱人在清华教书 ...
- H5 文字属性的缩写
05-文字属性的缩写 abc我是段落 <!DOCTYPE html> <html lang="en"> <head> <meta char ...
- A. Chess Placing
链接 [https://codeforces.com/contest/985/problem/A] 题意 给你一个偶数n,输入n/2个数,代表棋子的位置,有一个1*n的棋盘是黑白相间的 问你使得所有棋 ...
- vscode中php断点调试方法!
一.PHP的代码断点调试 1.打开vscode的首选项设置,添加"php.validate.executablePath": "D:\\newXampp\\php\\ph ...
- Mysql的使用,常用的SQL语句
一.启动mysql服务 启动mysql服务: systemctl start mysqld.service root用户登录mysql: 修改root 密码: alter user 'root'@'l ...