Hibernate持久层框架详解

来源:互联网 发布:淘宝网的技术模式分析 编辑:程序博客网 时间:2024/05/21 14:04

本博文是本人原创,观点是本人自己提出的,如有雷同,不甚荣幸!

一、hibernate框架的前世今生

1、前世:2001年,Gavin King开始开发hibernate框架。两年之后,Gavin King带领他的team完成了hibernate框架的开发,谁也没有想到两年前对SQL一概不知的小伙子,居然会成为全世界J2EE数据库解决方案的领导者。

2、今生:Hibernate版本更新速度很快,目前为止有两个阶段性的版本:Hibernate2,Hibernate3和Hibernate4,这一点程序员从其Jar文件名便可以看出来。目前最新发布的版本是hibernate-search-4.2.0.Final。Hibernate2系列的最高版本是Hibernate2.1.8,Hibernate3系列的最高版本是hibernate-distribution-3.6.10.Final-dist版,但目前使用较多且较稳定的版本是Hibernate 3.1.3或Hibernate 3.1.2。另外,自Hibernate3发布以来,其产品线愈加成熟,相继出现了Hibernate注释、Hibernate实体管理器、Hibernate插件工具等一系列产品套件。在方便程序员使用Hibernate进行应用程序的开发的同时,也逐渐增强了Hibernate产品线的实力。


二、hibernate框架核心包以及依赖包下载

官网下载可参考百度经验给出的解决方案:https://jingyan.baidu.com/article/ce09321b40f8132bff858f83.html

为了方便大家下载,我已经在这里将该使用到的JAR包(hibernate3)下载并整理好,大家有需要的话可直接下载:http://download.csdn.net/detail/superkeeper/9890199


三、hibernate各JAR包功能简介

这里就以我的下载链接地址中的JAR包(hibernate3)为例:

1、hibernate核心包

1).hibernate3.jar:hibernate核心包,同时也是hibernate的库,我们调用的方法和接口均来自于这个JAR包。

2、hibernate依赖包

1).ant-1.6.5.jar:Ant编译工具的jar包,用来编译Hibernate源代码的。如果你不准备修改和编译Hibernate源代码,那么就没有什么用,可选的jar包 。

2).ant-antlr-1.6.5.jar:这个包中只包含org.apache.tools.ant.taskdefs.optional.ANTLR类。

3).ant-junit-1.6.5.jar:Ant junit support 可选

4).ant-launcher-1.6.5.jar:该包中的class文件是帮助建立Ant的classpath的。目前最好的方法是使用ant-launcher.jar 中的org.apache.tools.ant. launch.Launcher类来启动Ant,虽然有些应用已经加入了Ant(例如Tomcat),但是它们仍然使用传统的方法,即:用ant.jar包中的org.apache.tools.ant.Main类来启动。

5).ant-swing-1.6.5.jar:ant swing support

6).antlr-2.7.6.jar:在用hibernate3.0进行查询时,出现java.lang.NoClassDefFoundError: antlr/ANTLRException异常. 所以必须导入。

7).asm-attrs.jar:ASM 字节转换库

8).asm.jar:和cglib-2.1.3.jar有点类似

9).c3p0-0.9.0.jar:C3PO是一个数据库连接池,Hibernate可以配置为使用C3PO连接池。如果你准备用这个连接池,就需要这个jar包。

10).cglib-2.1.3.jar:CGLIB库,Hibernate用它来实现PO字节码的动态生成,非常核心的库,必须使用的jar包

11).checkstyle-all.jar:可选 

12).clearimports.jar:cleanimports是对java文件中的无用的imports作清理,并通过配置文件提供的格式对imports代码段进行格式整理。

13).commons-collections-2.1.1.jar:Apache Commons包中的一个,包含了一些Apache开发的集合类,功能比java.util.*强大。必须使用的jar包。

14).commons-logging-1.0.4.jar:用来兼容两个logger。因此用commons-logging.jar写的log程序,底层的Logger是可以切换的,你可以选择log4j,java.util.logging或者它自带的Simple Logger。不过我仍然强烈建议使用log4j,因为log4j性能很高,log输出信息时间几乎等于System.out,而处理一条log平均只需要5us。你可以在Hibernate的src目录下找到Hibernate已经为你准备好了的log4j的配置文件,你只需要到Apache 网站去下载log4j就可以了。commons-logging.jar也是必须的jar包。

15).concurrent-1.3.2.jar:线程同步工具,在使用JBoss 的树状缓存时需要用到

16).connector.jar:JCA 规范,如果你在App Server上把Hibernate配置为Connector的话,就需要这个jar。不过实际上一般App Server肯定会带上这个包,所以实际上是多余的包。

17).dom4j-1.6.1.jar:dom4j是一个Java的XML API,类似于jdom,用来读写XML文件的。dom4j是一个非常非常优秀的Java XML API,具有性能优异、功能强大和极端易用使用的特点,同时它也是一个开放源代码的软件,可以在SourceForge上找到它。在IBM developerWorks上面可以找到一篇文章,对主流的Java XML API进行的性能、功能和易用性的评测,dom4j无论在那个方面都是非常出色的。我早在将近两年之前就开始使用dom4j,直到现在。如今你可以看到越来越多的Java软件都在使用dom4j来读写XML,特别值得一提的是连Sun的JAXM也在用dom4j。这是必须使用的jar包,Hibernate用它来读写配置文件。必须要有,在启动程序时要加载这个类。

18).ehcache-1.2.jar:在Hibernate中使用它作为数据缓存的解决方案。

19).jaas.jar:JAAS是用来进行权限验证的,已经包含在JDK1.4里面了。所以实际上是多余的包。

20).jacc-1_0-fr.jar:JACC库 可选

21).javassist.jar:Javassist字节码解释器 可选

22).jaxen-1.1-beta-7.jar:Jaxen 如果想提高启动性能则去使用 可选

23).jboss-cache.jar:JBoss 的一种树状缓存实现工具

24).jboss-common.jar:Jboss 的基础包,在使用 JBoss 的树状缓存时必须有此包

25).jboss-jmx.jar:JBoss 的 JMX 实现包

26).jboss-system.jar:JBoss 的核心,包括服务器和部署引擎

27).jdbc2_0-stdext.jar:JDBC2.0的扩展包,一般来说数据库连接池会用上它。不过App Server都会带上,所以也是多余的。

28).jgroups-2.2.8.jar:可选

29).jta.jar:JTA规范,JTA(Java Transaction API)是一种高层的,与实现无关的,与协议无关的API,应用程序和应用服务器可以使用JTA来访问事务。当Hibernate使用JTA的时候需要,不过App Server都会带上,所以也是多余的。我这里必须使用,可能是因为Tomcat只是Web Server而非App Server的缘故。

30).junit-3.8.1.jar:Junit包,当你运行Hibernate自带的测试代码的时候需要,否则就不用。

31).log4j-1.2.11.jar:hibernate的日志包,必须要的

32).mysql-connector-java-3.1.13-bin.jar:数据库连接JAR包,必须要的

33).oscache-2.1.jar:OSCache:是现在最广泛缓存解决方案,采用的高性能的J2EE缓存框架, OSCache能用于任何Java应用程序。对于网页可支持分段化的缓存。JBoss,hibernate,spring等都对其有支持。

34).proxool-0.8.3.jar:是一个开源的数据库连接池套件,一般在使用数据库连接池时使用。如果不使用数据库连接池的话的就没有必要使用

35).swarmcache-1.0rc2.jar:Hibernate 可以使用的一种缓存工具。SwarmCache很小巧,但分布式是核心,采用的是失效机制。最终采用SwarmCache 实现。不是必须要用的。SwarmCache是一个简单且有效的分布式缓存,它使用IP multicast与同一个局域网的其他主机进行通讯,是特别为集群和数据驱动web应用程序而设计的。SwarmCache能够让典型的读操作大大超过写操作的这类应用提供更好的性能支持。

36).syndiag2.jar:可选

37).versioncheck.jar:版本检查工具包,用于在构建 Hibernate 的时候检查辅助 jar 包文件的版本

38).xerces-2.6.2.jar:是XML解析器,Xalan是格式化器,xml-apis实际上是JAXP。一般App Server都会带上,JDK1.4也包含了解析器,不过不是Xerces,是Crimson,效率比较差,不过Hibernate用XML只不过是读取配置文件,性能没什么紧要的,所以也是多余的。

39).xml-apis.jar:xml-apis实际上是JAXP。一般App Server都会带上,JDK1.4也包含了解析器,不过不是Xerces,是Crimson,效率比较差,不过Hibernate用XML只不过是读取配置文件,性能没什么紧要的,所以也是多余的。

以上标红色的是必须要使用的包,其他的是可选,在你有需要的功能是才使用的JAR包,说白了其他依赖包就是在给hibernate优化时使用,比如说解决缓存和增加执行效率这些。


四、hibernate框架的使用

hibernate是一个持久层框架,不仅仅是使用在WEB项目中,在Java Project中也可以使用。这里就拿Java项目来讲,hibernate框架大体上分为三个部分,配置文件、model层和Service层,配置文件是hibernate.cfg.xml,该文件位于src根目录下,model层是表关系的映射层,model层中有两种文件,一种是实体类(最好与表名一致),该实体类必须要和表中字段相对应,一个字段对应一个属性,并且要有set、get方法,另一种文件就是hibernate框架和实体类之间的映射文件,该文件的名称是实体类名称.hbm.xml,该文件根据表中字段的类型和id的自增的不同属性来指定,必须要与表中的字段类型和数量一致。Service层是编写数据库的处理逻辑,大体上有三种方式,QBC/HQL/SQL。

下面是本人贴出的实践代码:

1、MySQL中的表结构:







2、hibernate.cfg.xml配置文件

首先右击src目录,点击new--->other--->选择MyEclipse点击--->点击Xml--->点击Xml(Basic templates)


生成xml文件之后,这里应该是将头文件引入到Xml文件中,这里我省略了这个步骤,直接将下面的头信息copy到xml文件就可以。也就是说添加约束

<!DOCTYPE hibernate-configuration PUBLIC  
    "-//Hibernate/Hibernate Configuration DTD 3.0//EN"  
    "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

然后就是将MySQL的各种配置写到hibernate.cfg.xml配置文件中

<hibernate-configuration>  
    <session-factory> 
        <!-- mysql数据库驱动 -->  
        <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>  
        <!-- mysql数据库名称 -->  
        <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/frqs</property>  
        <!-- 数据库的登陆用户名 -->  
        <property name="hibernate.connection.username">root</property>  
        <!-- 数据库的登陆密码 -->  
        <property name="hibernate.connection.password">root</property>  
        <!-- 方言:为每一种数据库提供适配器,方便转换 -->
        <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>  
          
        <mapping resource="com/zzy/hibernate/model/User.hbm.xml"/>  
    </session-factory>  
</hibernate-configuration>

3、创建model层,指定实体类和表映射配置文件

实体类

public class User {
private int id;
private String UUID;
private String username;
private String password;

public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUUID() {
return UUID;
}
public void setUUID(String uUID) {
UUID = uUID;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}

实体类映射文件

创建Xml文件,引入下面的头信息约束

<!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

编写映射关系

<hibernate-mapping>  
    <class name="com.zzy.hibernate.model.User">  
        <id name="id"><!-- id是自增长类型 -->  
            <generator class="increment"/>  
        </id>
        <property name="UUID"/>
        <property name="username"/>  
        <property name="password"/>   
    </class>  
</hibernate-mapping>

4、编写Service层,Service层中是数据库操作层,相当于dao层,其中我使用三种方式的数据库操作方式。

public class ServerUtil {
/**
* 创建表的方法
* @return
*/
public static boolean crateTable(){
//默认读取hibernate.cfg.xml文件  
        Configuration cfr = new Configuration().configure();  
        
        SchemaExport export = new SchemaExport(cfr);  
        export.create(true, true); 
return true;
}
/**
* 向表中插入数据的方法
* @param user
* @return
*/
public static boolean insertData(User user){
//读取配置文件  
        Configuration cfg = new Configuration().configure();  
        //创建Session的工厂类
        SessionFactory factory = cfg.buildSessionFactory();  
        //创建Session对象
        Session session = null;  
        try{  
        //开启会话
            session = factory.openSession();  
            //开启事务  
            session.beginTransaction();  
            //将表映射对象直接保存到Session中
            session.save(user);  
            //提交事务  
            session.getTransaction().commit();  
        }catch(Exception e){  
            e.printStackTrace();  
            //回滚事务  
            session.getTransaction().rollback();  
        }finally{  
            if(session != null){  
                if(session.isOpen()){  
                    //关闭session  
                    session.close();  
                }  
            }  
        }  
        return true;
}

/**
* 全部查询表的数据,使用HQL方式
* @param name
* @return
*/
public static boolean queryUserAll(){
Configuration cfg = new Configuration().configure();
Session session = cfg.buildSessionFactory().openSession();
session.beginTransaction();
String hql = "from User"; // from 后跟的是要查询的对象,而不是表
Query query = session.createQuery(hql);
List<User> userList = query.list();
for(User user:userList){
 System.out.println("查询结果是:"+user.getUsername()+","+user.getPassword());
}
session.getTransaction().commit();
return true;
}
/**
* 按照条件查询数据,HQL方式
* @param name
* @param pwd
* @return
*/
public static boolean queryUser(String name,String pwd){
Configuration cfg = new Configuration().configure();
Session session = cfg.buildSessionFactory().openSession();
session.beginTransaction();
String hql = "from User where username=? and password=?"; // from 后跟的是要查询的对象,而不是表
Query query = session.createQuery(hql);
query.setString(0, name);
query.setString(1, pwd);
List<User> userList = query.list();
for(User user:userList){
 System.out.println("查询结果是:"+user.getId()+","+user.getUUID()+","+user.getUsername()+","+user.getPassword());
}
session.getTransaction().commit();
return true;
}
/**
* 查询所有的数据,使用QBC的方式
* @return
*/
public static boolean getDataAll(){
Configuration cfg = new Configuration().configure();
Session session = cfg.buildSessionFactory().openSession();
session.beginTransaction();
Criteria c = session.createCriteria(User.class);
List<User> userList = c.list();
for(User user:userList){
 System.out.println(user.getUsername()+","+user.getPassword()+","+user.getUUID());
}
session.getTransaction().commit();
return true;
}
/**
* 按照条件查询数据,使用QBC方式
* @param name
* @param pwd
* @return
*/
public static boolean getData(String name,String pwd){
Configuration cfg = new Configuration().configure();
Session session = cfg.buildSessionFactory().openSession();
session.beginTransaction();
Criteria c = session.createCriteria(User.class);
//有条件查询数据时,使用add方法添加限制条件。限制条件是Restrictions对象,eq是相等条件。eq方法的第一个参数是表中的字段名,也是hibernate属性名,第二个参数是要查询的值
c.add(Restrictions.eq("username", name));
//再添加一个限制条件
c.add(Restrictions.eq("password", pwd));
List<User> userList = c.list();
for(User user:userList){
 System.out.println(user.getUsername()+","+user.getPassword()+","+user.getUUID());
}
session.getTransaction().commit();
return true;
}
/**
* 查询所有数据,使用SQL方式
* @return
*/
public static boolean selectUserAll(){
Configuration cfg = new Configuration().configure();
Session session = cfg.buildSessionFactory().openSession();
session.beginTransaction();
String sql = "select * from user";
SQLQuery query = session.createSQLQuery(sql).addEntity(User.class);
List<User> list = query.list();
for(User user:list){
System.out.println(user.getUsername()+","+user.getPassword()+","+user.getUUID());
}
session.getTransaction().commit();
return true;
}
/**
* 按照条件查询数据,使用SQL的方式
* @param name
* @param pwd
* @return
*/
public static boolean selectUser(String name,String pwd){
Configuration cfg = new Configuration().configure();
Session session = cfg.buildSessionFactory().openSession();
session.beginTransaction();
String sql = "select * from user where username=? and password=?";
SQLQuery query = session.createSQLQuery(sql).addEntity(User.class);
query.setString(0, name);
query.setString(1, pwd);
List<User> list = query.list();
for(User user:list){
System.out.println(user.getUsername()+","+user.getPassword()+","+user.getUUID());
}
session.getTransaction().commit();
return true;
}
}

其实hibernate框架并不复杂,我们只需明白它的运行原理和规则就可以使用。