Hibernate基础 I: 快速启动Hibernate

来源:互联网 发布:rar密码破解软件下载 编辑:程序博客网 时间:2024/06/11 02:10

1.  为何要写此文档

       ①项目中经常遇到ORM的相关问题,经常整理常见问题对提高对ORM的认知并无太大促进作用,所以决定以Hibernate In Action 一书为纲,阐述常见ORM问题的原因。

      ③时间管理计划中有此项安排。

2.   一些期望明确的问题:

       ①Session、SessionFactory的基本概念、意图与经典实践

       ②事务的含义、并发问题。

       ③SQL、HQL,查询效率(至此,期望每天对物理数据库设计都有所坚持)

       ④常见设计模式在Hibernate中的体现。

 

3. 一些对象的说明

       ① Session---A Hibernate Session is many things in one.It's a single-threaded nonshared object that represents a particular unit of work with database.

                           It has the persistence manage API you call to load and store objects.(The Session internals consist of a queue of SQL statements that

                            need to be synchronized with the database at some point and a map of managed persistence instances that are monitored by the session)

            [ Hibernate Session 是一个多功能的对象。它是单线程,非共享的,刻画了数据库操作独有的逻辑单元,它有持久化管理器API,调用此API可以加载和存储对象。

            (Session对象内部包含了一个SQL语句队列,这些语句用来在你(业务程序员)必须关注的数据库的时候,用来保证数据同步,而且还能对维护那些被Session监控、管理

             的持久化对象映像提供支持)]

       ② Transaction---- This Hibernate API can be used to set transaction boundaries programmatically,but it's optional(transaction boundaries aren't).Other choices

                                     are JDBC transaction demarcation,the JTA interface,or container-managed thansactions with EJBs.

             [这个Hibernate API可以通过程式来设置事务边界,是否显示的编程样式的展示事务边界是可选的,但是事务所代表的的业务本身的"事务边界"是本质化的。其他的选择

             还有JDBC事务划分、JTA接口,或者带有事务托管功能的EJB容器。]

      ③ Query----A database query can be wirtten in Hibernate's own object-oriented query language(HQL) or plain SQL,This Interface allows you to create queries,binding

                         arguments to placeholders in the query,and execute the query in various ways.

           [通过Query对象可以通过HQL、原生SQL完成查询功能。这个接口允许你创建查询,在查询中给占位符绑定参数,并且可以以多种方式执行查询]

 

4. 环境:

    Windows7+JDK7+Hibernate3

    (

             为何选用这个环境?

              ①考虑到生产环境是Flex+OSGi+BlazeDS+Activiti+Spring+Hibernate,而Flex1.5.2是最新版本,其依赖是Hibernate∈[3,4),Spring∈[3.0,3.1)

              ②Hibernate In Action一书采用Hibernate 3.x版本  

    )

    (Jar Dependencies:

          mysql-connector-java-5.1.18-bin.jar
          log4j-1.2.13.jar
          jta.jar
          hibernate-tools.jar
          hibernate3.jar
          dom4j-1.6.1.jar
          commons-logging-1.0.4.jar
          commons-collections-2.1.1.jar
          cglib-2.1.3.jar
          c3p0-0.9.0.jar
          asm-attrs.jar
          asm.jar
          antlr-2.7.6.jar

     )

    ( Bundle Dependecies: ebr.springsource.com

          +com.springsource.org.hibernate;version="[3.3.1.GA,3.3.1.GA]"
               -com.springsource.antlr;version="[2.7.7,2.7.7]"
               -com.springsource.javassist;version="[3.15.0.GA,3.15.0.GA]"
               -com.springsource.net.sf.cglib;version="[2.2.0,2.2.0]"
               -com.springsource.org.apache.commons.collections;version="[3.2.1,3.2.1]"
               +com.springsource.org.dom4j;version="[1.6.1,1.6.1]"
                  - com.springsource.javax.xml.stream;version="[1.0.1,1.0.1]"
               +com.springsource.org.jgroups;version="[2.5.1,2.5.1]"
                  -com.springsource.org.apache.commons.logging;version="[1.1.1,1.1.1]"
               +com.springsource.slf4j.api;version="[1.5.11,1.5.11]"
                  -com.springsource.slf4j.nop;version="[1.6.1,1.6.1]"
                  -com.springsource.slf4j.api;version="[1.6.1,1.6.1]"  

     )

 

     关于数据库的选择:

       此处的目的是为了温习Hibernate而不是用于生产,所以选择HSQLDB,选择他的原因:

           只需要hsqldb.jar这一个文件。

           hsql.jar file includes both database engine and the JDBC Driver required to connect to a running instance.

           (

                cd WORK_DIR

                java -classpath lib/hsql.jar org.hsqldb.Server即可启动。

                只需要简单的将mysql-connector-java-5.1.18-bin.jar替换为hsqldb.jar

            )

5. The database connection pool(数据库连接池)

    站在一个进程的角度,一般的我们越过Hibernate直接访问数据库,这就意味着我们越过了两级缓存。第一级是Session,第二级是SessionFactory.而数据库连接池的配置直接影响的是SessionFactory对象,当然也会将这种影响传递到整个应用系统。为甚么使用数据库连接池?

    Generally,it isn't advisable to create a connection each time you want to interact with the database.Instead,Java applications shoud use a pool of connections.

    Each application thread needs to do work on the database requests a connection from the pool and then returns it to the pool when all SQL operations have been

    executed. The pool maintains the connections and minimizes the cost of opening and closing connections.

    There three reasons for using a pool:

     · Acquring a new connection is expensive. Some database management systems even start a completely new server process for each connection.

      (获取一个连接的代价昂贵,一些DBMS甚至给每个连接启动一个新的服务器进程。)

     ·Maintaining many idle connections is expensive for a database management system,and the pool can optimize the usage of idle connections(or disconnect

       if there no requests).

      (为DBMS维护许多闲置的链接代价也较大,连接池可以优化闲置连接的使用(或者在无请求时就断开连接))

    · Creating prepared statements is also expensive for some drivers,and the connection pool can cache statments for a connection across requests.

      (为某些驱动创建预编译语句也是很昂贵的,连接池可以为那些夸请求的连接缓存预编译语句)

    

     [常用的连接池DBCP、C3P0、Druid(监控功能很强大)]

     常用配置有最大连接数、最小连接数、超时值(闲置连接从连接池中移除的时间间隔)、预编译语句容量、闲置测试周期

     示例:

        hibernate.c3p0.min_size=5. (This is the minimun number of JDBC connections that C3P0 keeps ready at all times)

        hibernate.c3p0.max_size=5. (This is the maximum number of connections in the pool.An Exception is thrown at runtime if this number is exhausted.)

        hibernate.c3p0.timeout=300 (You specify the timeout period (in this case,300 seconds) after which an idle connection is removed from the pool)

        hibernate.c3p0.idle_test_period=50 (A maximum number of 50 perpared statements will be cached.Caching of prepared statements is essential for best

                                                                         performance with Hibernate)

        hibernate.c3p0.idle_test_period=3000 (This is the idle time in seconds before a connection is automatically validated)

 

6. Building a SessionFactory

     SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();

    How did Hibernate know where the configuration file was located and which one to load?

    When new Configuration() is called,Hibernate searches for a file named hibernate.properties in the root of the classpath.If it's found,all hibernate.* properties

        are loaded and added to the Configuration object.

    ② When configue() is called,Hibernate searches for a file named hibernate.cfg.xml in the root of the classpath,and an exception is thrown if it can't be found.

         If settings in the XML configuration file are duplicates of the properties set eariler;The XML setting override the previous ones.

   一个经典的类

   public class HibernateUtil

   {

        private static SessionFactory sessionFactory;

        static

        {

            try

            {

               sessionFactory=new Configuration().configure().buildSessionFactory();

            }

            catch(Throwable ex)

            {

                throw new ExceptionInInitializerError(ex);   // The weapping in ExceptionInInitializerError is mandatory for static initializers.

            }

        }

       public static SessionFactory getSessionFactory()

        {

              //Alternatively ,you could look up in JNDI here.

              return sessionFactory;

        }

        public static void shutdown()

        {

             //Close caches and connection pools

             getSessionFactory().close();

        }

   }

 

7. 日志

    在学习(开发)过程中、对Hibernate语句的掌控是重要的,在运行时是一种比较浪费的行为。

    在学习(开发)过程中、对一般日志级别设置的很低如DEBUG,我个人在在运行时绝不这么做,过于浪费。

    (Log4J 日志级别:ERROR>WARN>INFO>DEBUG)

   

    <!-- SQL to stdout logging-->

    <property name="show_sql">true</property>

    <property name="format_sql">true</property>

    <property name="use_sql_comments">true</property>

   

    Log4J 输出到文件:

     #Root logger option
     log4j.rootLogger=WARN,FILE

     #Refirect log messages to file
     log4j.appender.FILE=org.apache.log4j.FileAppender
     log4j.appender.FILE.File=log.txt
     log4j.appender.FILE.Append=false
     log4j.appender.FILE.Layout=org.apache.log4j.PatternLayout
     log4j.appender.FILE.layoout.ConversionPattern=%d{yyyy-mm-dd hh:mm:ss}:%p %c:%L - %m%n   

     Log4J 输出到标准输出:

     #Root logger option
     log4j.rootLogger=WARN,stdout

     # Direct log messgaes to stdout
     log4j.appender.stdout = org.apache.log4j.ConsoleAppender 
     log4j.appender.stdout.Target=System.out
     log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
     log4j.appender.stdout.layout.ConvensionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n

 

    更多请参见: http://dolphin-ygj.iteye.com/blog/312504

    

8. Exporting the database schema

    <property name="hibernate.hbm2ddl.auto">create-drop</property>    -- 干净的数据库。

    在实验环境中可以这么做,在工作环境中如果这么做话,应用服务器重启完成之后,在DBA没找到你之前,赶快跑路,保命要紧!

   

    Ant任务形式:

    <!-- Hibernate Tools import -->

    <taskdef name="hibernatetool"

                   classname="org.hibernate.tool.ant.HibernateToolTask"

                   classpathref="project.classpath" />

   <!--Export the database schema -->

   <target name="schemaexport" depends="compile,copymetafiles"

         description="Exports a generated schema to DB and file">

         <hibernatetool destdir="${basedir}">

               <classpath path="${build.dir}" />

               <configuration configurationfile="${build.dir}/hibernate.cfg.xml" />

               <hbm2ddl

                          drop="true"

                          create="true"

                          export="true"

                          outputfilename="${project.shortname}-ddl.sql"

                          delimiter=";"

                          format="true" />

          </hibernatetool>

 

9 . 资源与运行

     原项目: http://jpwh.org/examples/

     或:  http://download.csdn.net/detail/thomasks/6230997

     运行步骤:

          切换到工作空间: 

                        d:

                        cd      D:\Hibernate\helloworld  

          开启数据库:  

                       ant startdb

          编译,拷贝配置文件,导出Schema

                       ant schemaexport 

          运行

                       ant run

          (查看数据库 

                      ant dbmanager

           )

 

10. 补充问题

         1) 如何将SQL语句输出到日志文件?

          只需在log4j中添加:

              #输出sql语句到日志 

              log4j.logger.org.hibernate.SQL=debug 

            

             #将对应的参数占位符?换成传入的参数 

             log4j.logger.org.hibernate.type=trace

      2) ant schemaexport

           java.sql.SQLException:Table not found: MESSAGES in statement[alter table MESSAGES]  error occued!

           暂未修复。

原创粉丝点击