Hibernate学习(1--8)

来源:互联网 发布:2016网络知识竞赛 编辑:程序博客网 时间:2024/05/19 22:01

Hibernate初学  基础配置详解

 (2012-10-23 20:48:20)
转载
标签: 

hibernate基础配置

 

开发步骤

分类: Hibernate
一、简单介绍
 
 Hibernate是一种对JDBC做了轻量级封装的对象---关系映射工具,所谓轻量级封装,是指Hibernate并没有完全封装JDBCJava应用即可以通过Hibernate API访问数据库,还可以绕过Hibernate API,直接通过JDBC API来访问数据库。
 1、
 Hibernate官网下载地址http://www.hibernate.org。现在最新的是: hibernate-release-4.1.7.Final.zip
解压后的目录结构:
  Documentation:该文件夹下是开发帮助文档
  Lib:该文件夹是开发使用的库,其中该文件夹下面的required目录是开发时必须导入的JAR文件;
  Project:该文件夹是项目源码文件
2、持久化JAVA类必须遵循的原则
 
 A、为类的持久化字段声明访问方法(get/set),Hibernate对JavaBeans风格的属性实行持久化。
  B、实现一个默认的构造方法,这样的话Hibernate就可以使用Constructor.newInstance()方法来实例化对象。
  C、如果是集合类型的属性,它的类型必须定义为集合的接口,例如:List、Set
  D、提供一个标识属性(Identifier property),如果没有该属性,一些功能不起作用,比如:级联更新,session.saveOrUpdate()。
二、Hibernate开发步骤
   首先项目中应该把
required目录中的所有jar包和要连接的数据库的驱动jar包构建到Build Path中!!! 

 1、编写实体类 UserInfor.java
切记:实体类中的属性名有二个以上(含两个)的小写字母开头!!!!
  package com.entity;
import java.util.Date;
public class UserInfor {
   
    private int userId;
    private String userName;
    private int userAge;
    public UserInfor() {
        // 一定要有一个无参的构造方法,因为Hibernate都是根据他生成对象的
    }
    public UserInfor(int userid)
    {// 最好要有一个含主键的构造方法,因为在Hibernate中便于查询
        this.userId = userid;
    }
    //....下面都是get***()set***()封装属性
    }
  2、创建实体类的映射文件***.hbm.xml(与实体类同包,并且名字可以自定义,这里是:
userInfor.hbm.xml
   可以在上面解压后的Project文件夹中搜索
hbm.xml,找到示例文在加以修改即可!!!
 
  <?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.entity">

    <class name="UserInfor" table="Wuser" >
        <id name="userId" >
            <generator class="native"/>
        </id>
        <property name="userName"/>
        <property name="userAge"/>
        <property name="userBirthday"/>
    </class>
</hibernate-mapping>

 ####:说明:
具体Hibernate个元素详解请看:
http://chen25362936.blog.163.com/blog/static/2565547420101113112752675/   
    
 根元素:<hibernate-mapping>,每一个hbm.xml文件都有唯一的一个根元素,包含一些可选的属性 package:指定一个包前缀,即该xml文件的位置
      <class>定义类:根元素的子元素,用以定义一个持久化类与数据表的映射关系,如下是该元素包含的一些可选的属性--》name:持久化类(或者接口)的Java全限定名,如果这个属性不存在,则Hibernate将假定这是一个非POJO的实体映射;table:对应数据库表名
       <id>定义主键:Hibernate使用OID(对象标识符)来标识对象的唯一性,OID是关系数据库中主键在Java对象模型中的等价物,在运行时,Hibernate根据OID来维持Java对象和数据库表中记录的对应关系

1)name:持久化类的标识属性的名字

2)column:数据库表的主键这段的名字

       <generator>设置主键生成方式:该元素的作用是指定主键的生成器,通过一个class属性指定生成器对应的类。(通常与<id>元素结合使用),--native是Hibernate主键生成器的实现算法之一,由Hibernate根据底层数据库自行判断采用identity、hilo、sequence其中一种作为主键生成方式。

       <property>定义属性:用于持久化类的属性与数据库表字段之间的映射,包含如下属性:

1)name:持久化类的属性名,以小写字母开头

2)column:数据库表的字段名


3、编写Hibernate的配置文件hibernate.cfg.xml(这里的名字是固定的)

  Hibernate配置的两种方法:
属性文件:hibernate.properties
调用代码:Configuration cfg=new Configuration();
XML文件:hibernate.cfg.xml
调用代码: Configuration cfg=new Configuration().configure();


关于 hibernate.cfg.xml的样例可以到上面解压的Project/etc/下查找,在该样例下修改即可!!!!该xml文件中设置的属性名和值可以在Project/etc/hibernate.properties文件中查找到!!!

 <!DOCTYPE hibernate-configuration PUBLIC
    "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <property name="show_sql">true</property><!--控制台中显示sql语句-->
         <property name="format_sql">true</property>    <!--格式化sql语句-->

        <!-- 通过getCurrentSession创建的session会绑定到当前线程 -->
        <property name="current_session_context_class">thread</property> 

        <!--数据库连接要使用的参数-->       
        <property name="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</property>
        <property name="hibernate.connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
        <property name="hibernate.connection.username">bam1</property>
        <property name="hibernate.connection.password">bam1</property>
        <property name="hibernate.connection.url">jdbc:oracle:thin:@192.168.3.252:1521:orcl</property>
        <!--设置数据库定义语言为:更新数据库操作-->   
        <property name="hibernate.hbm2ddl.auto">update</property>


        <!--如果使用JUnit进行测试:就要加上下面这句话-->  

       <property name="javax.persistence.validation.mode">none</property>

        <!--加载映射文件:映射文件全路径###并且一定要定义在下方-->   
        <mapping resource="com/entity/Person.hbm.xml"/>
    </session-factory>
</hibernate-configuration>


 ####:说明:关于Hibernate配置文件详解请看:http://www.24xuexi.com/w/2012-02-23/98592.html)

4、测试类中操作

public  void add()
    {
      
        //第一步:读取Hibernate的配置文件  hibernamte.cfg.xml文件
        Configurationcon=new Configuration().configure();
        //第二步:创建服务注册构建器对象,通过配置对象中加载所有的配置信息
        ServiceRegistryBuilderregbulider=newServiceRegistryBuilder().applySettings(con.getProperties());
        //创建注册服务
        ServiceRegistryreg=regbulider.buildServiceRegistry();
        //第三步:创建会话工厂
        SessionFactorysessionFactory=con.buildSessionFactory(reg);
        //第四步:创建数据操作会话
        Sessionsession=sessionFactory.openSession();

        //创建对象
         */
        UserInfo user=new UserInfor();
        user.setUserAge(20);
        user.setUserBirthday(new Date());
        user.setUserName("张三");
        /*
       //创建事物
        Transactiontran=session.beginTransaction();

        //保存数据
        session.save(user);//update(object):修改;get(class,Serializable ):根据主键查询//(查询时可以不使用事物)
        //提交事物
       tran.commit();
        //关闭对话
        session.close();

      
}

Hibernate配置各种数据源详解

 (2012-10-23 22:22:53)
转载
标签: 

hibernate.cfg.xml

 

配置数据源

分类: Hibernate
Hibernate的描述文件可以是一个properties属性文件,也可以是一个xml文件。下面讲一下Hibernate.cfg.xml的配置。配置格式如下:
1. 配置数据源

在Hibernate.cfg.xml中既可以配置JDBC,也可以配置JNDI。在本小节中讲述数据源如何配置。

hibernate.cfg.xml

<?xml version=”1.0″ encoding=”UTF-8″?>
<!DOCTYPE hibernate-configuration PUBLIC
“-//Hibernate/Hibernate Configuration DTD 3.0//EN”
“http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd“>

<hibernate-configuration>

<session-factory>

<!– 各属性的配置–>

<!—为true表示将Hibernate发送给数据库的sql显示出来 –>

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

<!– SQL方言,这边设定的是MySQL –>

<property name=”dialect”>net.sf.hibernate.dialect.MySQLDialect</property>

<!– 一次读的数据库记录数 –>

<property name=”jdbc.fetch_size”>50</property>

<!– 设定对数据库进行批量删除 –>
<property name=”jdbc.batch_size”>30</property>

<!—下面为JNDI的配置 –>

<!– 数据源的名称 –>

<property name=”connection.datasource”>java:comp/env/jdbc/datasourcename</property>

<!– Hibernate的连接加载类 –>

<property name=”connection.provider_class”>org.hibernate.connection.DatasourceConnectionProvider
</property>


<property name=”dialect”>net.sf.hibernate.dialect.SQLServerDialect</property>

<!—映射文件 –>

<mapping resource=”com/amigo/pojo/User.hbm.xml”/>

<mapping resource=”com/amigo/pojo/Org.hbm.xml”/>
</session-factory>
</hibernate-configuration>

2. c3p0连接池

c3p0连接池是Hibernate推荐使用的连接池,若需要使用该连接池时,需要将c3p0的jar包加入到classpath中。c3p0连接池的配置示例如下:

hibernate.cfg.xml

<?xml version=”1.0″ encoding=”UTF-8″?>

<!DOCTYPE hibernate-configuration PUBLIC

“-//Hibernate/Hibernate Configuration DTD 3.0//EN”

“http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd“>

<hibernate-configuration>

<session-factory>

<!– 显示实际操作数据库时的SQL –>

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

<!– SQL方言,这边设定的是MySQL –>

<property name=”dialect”>net.sf.hibernate.dialect.MySQLDialect</property>

<!–驱动程序,在后续的章节中将讲述mysql、sqlserver和Oracle数据库的配置 –>

<property name=”connection.driver_class”>……</property>

<!– JDBC URL –>

<property name=”connection.url”>……</property>

<!– 数据库用户名 –>

<property name=”connection.username”>user</property>

<!– 数据库密码 –>

<property name=”connection.password”>pass</property>

<property name=”c3p0.min_size”>5</property>

<property name=”c3p0.max_size”>20</property>

<property name=”c3p0.timeout”>1800</property>

<property name=”c3p0.max_statements”>50</property>

<!– 对象与数据库表格映像文件 –>

<mapping resource=”com/amigo/pojo/User.hbm.xml”/>

<mapping resource=”com/amigo/pojo/Org.hbm.xml”/>

</session-factory>

</hibernate-configuration>

在上述配置中,Hibernate根据配置文件生成连接,再交给c3p0管理。

3. proxool连接池

proxool跟c3p0以及dbcp不一样,它是自己生成连接的,因此连接信息放在proxool配置文件中。使用它时,需要将proxool-0.8.3.jar加入到classespath中。
(关于Hibernate中配置Proxool在proxool的百度百科有详细的介绍:http://baike.baidu.com/view/2098784.htm)
配置举例如下:

hibernate.cfg.xml

<?xml version=”1.0″ encoding=”UTF-8″?>

<!DOCTYPE hibernate-configuration PUBLIC

“-//Hibernate/Hibernate Configuration DTD 3.0//EN”

“http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd“>

<hibernate-configuration>

<session-factory>

<!– 显示实际操作数据库时的SQL –>

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

<!– SQL方言,这边设定的是MySQL –>

<property name=”dialect”>net.sf.hibernate.dialect.MySQLDialect</property>

<!—proxool的配置 –>

<property name=”proxool.pool_alias”>pool1</property>

<property name=”proxool.xml”>ProxoolConf.xml</property>

<property name=”connection.provider_class”>net.sf.hibernate.connection.ProxoolConnectionProvider</property>

<!– 对象与数据库表格映像文件 –>

<mapping resource=”com/amigo/pojo/User.hbm.xml”/>

<mapping resource=”com/amigo/pojo/Org.hbm.xml”/>

</session-factory>

</hibernate-configuration>

在hibernate.cfg.xml的同目录下编写proxool的配置文件:ProxoolConf.xml,该文件的配置实例如下:

ProxoolConf.xml

<?xml version=”1.0″ encoding=”utf-8″?>
<!– the proxool configuration can be embedded within your own application’s.
Anything outside the “proxool” tag is ignored. –>
<something-else-entirely>
<proxool>
<alias>pool1</alias>
<!–proxool只能管理由自己产生的连接–>

<!– 驱动的url–>

<!– jdbc:mysql://localhost:3306/dbname?useUnicode=true&characterEncoding=GBK–>

<driver-url>… </driver-url>

<!– 驱动类,eg. com.mysql.jdbc.Driver–>

<driver-class>… </driver-class>
<driver-properties>

<!– 数据库用户名,eg. value为root–>

<property name=”user” value=”…”/>

<!– 数据库密码,eg. value为root–>

<property name=”password” value=”….”/>
</driver-properties>
<!– proxool自动侦察各个连接状态的时间间隔(毫秒),侦察到空闲的连接就马上回收,超时的销毁–>
<house-keeping-sleep-time>90000</house-keeping-sleep-time>
<!– 指因未有空闲连接可以分配而在队列中等候的最大请求数,超过这个请求数的用户连接就不会被接受–>
<maximum-new-connections>20</maximum-new-connections>
<!– 最少保持的空闲连接数–>
<prototype-count>5</prototype-count>
<!– 允许最大连接数,超过了这个连接,再有请求时,就排在队列中等候,最大的等待请求数由maximum-new-connections决定–>
<maximum-connection-count>100</maximum-connection-count>
<!– 最小连接数–>
<minimum-connection-count>10</minimum-connection-count>
</proxool>
</something-else-entirely>

4. dbcp连接池
在hibernate3.0中,已经不再支持dbcp了,hibernate的作者在hibernate.org中,明确指出在实践中发现dbcp有 BUG,在某些种情会产生很多空连接不能释放,所以抛弃了对dbcp的支持。若需要使用dbcp,开发人员还需要将commons-pool- 1.2.jar 和commons-dbcp-1.2.1.jar两个jar包加入到classpath中。dbcp与c3p0一样,都是由hibernate建立连接 的。

在hibernate2.0中的配置建立如下:

hibernate.cfg.xml

<?xml version=”1.0″ encoding=”UTF-8″?>

<!DOCTYPE hibernate-configuration PUBLIC

“-//Hibernate/Hibernate Configuration DTD 2.0//EN”

“http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd“>

<hibernate-configuration>

<session-factory>

<!– 显示实际操作数据库时的SQL –>

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

<!– SQL方言,这边设定的是MySQL –>

<property name=”dialect”>net.sf.hibernate.dialect.MySQLDialect</property>

<!–驱动程序,在后续的章节中将讲述mysql、sqlserver和Oracle数据库的配置 –>

<property name=”connection.driver_class”>……</property>

<!– JDBC URL –>

<property name=”connection.url”>……</property>

<!– 数据库用户名,eg. root –>

<property name=”connection.username”>…</property>

<!– 数据库密码, eg. root–>

<property name=”connection.password”>…</property>

<property name=”dbcp.maxActive”>100</property>

<property name=”dbcp.whenExhaustedAction”>1</property>

<property name=”dbcp.maxWait”>60000</property>

<property name=”dbcp.maxIdle”>10</property>

<property name=”dbcp.ps.maxActive”>100</property>

<property name=”dbcp.ps.whenExhaustedAction”>1</property>

<property name=”dbcp.ps.maxWait”>60000</property>

<property name=”dbcp.ps.maxIdle”>10</property>

<!– 对象与数据库表格映像文件 –>

<mapping resource=”com/amigo/pojo/User.hbm.xml”/>

<mapping resource=”com/amigo/pojo/Org.hbm.xml”/>

</session-factory>

</hibernate-configuration>

5. MySql连接配置
在hibernate中,可以配置很多种数据库,例如MySql、Sql Server和Oracle,MySql的配置举例如下:

hibernate.cfg.xml

<?xml version=”1.0″ encoding=”UTF-8″?>
<!DOCTYPE hibernate-configuration PUBLIC
“-//Hibernate/Hibernate Configuration DTD 3.0//EN”
“http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd“>

<hibernate-configuration>

<session-factory>

<!– 各属性的配置–>

<!—为true表示将Hibernate发送给数据库的sql显示出来 –>

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

<!– SQL方言,这边设定的是MySQL –>

<property name=”dialect”>net.sf.hibernate.dialect.MySQLDialect</property>

<!– 一次读的数据库记录数 –>

<property name=”jdbc.fetch_size”>50</property>

<!– 设定对数据库进行批量删除 –>
<property name=”jdbc.batch_size”>30</property>

<!–驱动程序–>

<property name=”connection.driver_class”>com.mysql.jdbc.Driver</property>

<!– JDBC URL –>

<property name=”connection.url”>jdbc:mysql://localhost/dbname?characterEncoding=gb2312</property>

<!– 数据库用户名–>

<property name=”connection.username”>root</property>

<!– 数据库密码–>

<property name=”connection.password”>root</property>

<!—映射文件 –>

<mapping resource=”com/amigo/pojo/User.hbm.xml”/>

<mapping resource=”com/amigo/pojo/Org.hbm.xml”/>
</session-factory>
</hibernate-configuration>

上面使用的驱动类是com.mysql.jdbc.Driver。需要将MySql的连接器jar包(eg. mysql-connector-java-5.0.4-bin.jar)加入到classpath中。

6. Sql Server连接配置
本小节讲述一下Sql Server数据库的hibernate连接设置,在此只给出连接部分的内容,其余部分与2.2.1.5一样,在此不再赘述。内容如下:

<!–驱动程序–>

<property name=”connection.driver_class”>net.sourceforge.jtds.jdbc.Driver</property>

<!– JDBC URL –>

<property name=”connection.url”>jdbc:jtds:sqlserver://localhost:1433;DatabaseName=dbname</property>

<!– 数据库用户名–>

<property name=”connection.username”>sa</property>

<!– 数据库密码–>

<property name=”connection.password”></property>

上例的驱动类使用的是jtds的驱动类,因此读者需要将jtds的jar包(eg. jtds-1.2.jar)加入到classpath中。

7. Oracle连接配置
来源:http://www.blogjava.net/amigoxie/archive/2007/12/29/171395.html
本小节讲述一下Sql Server数据库的hibernate连接设置,在此只给出连接部分的内容,其余部分与2.2.1.5一样,在此不再赘述。内容如下:

<!–驱动程序–>

<property name=”connection.driver_class”>oracle.jdbc.driver.OracleDriver</property>

<!– JDBC URL –>

<property name=”connection.url”>jdbc:oracle:thin:@localhost:1521:dbname</property>

<!– 数据库用户名–>

<property name=”connection.username”>test</property>

<!– 数据库密码–>

<property name=”connection.password”>test</property>

上例使用的驱动类为:oracle.jdbc.driver.OracleDriver,开发人员需要将相关的jar包(ojdbc14.jar)加入到classpath中。

二、hibernate配置属性

来源:http://blog.csdn.net/wxytx88/archive/2009/03/26/4027216.aspx

表 3.3.  Hibernate配置属性

属性名  用途
hibernate.dialect  一个Hibernate Dialect类名允许Hibernate针对特定的关系数据库生成优化的SQL.
取值 full.classname.of.Dialect

hibernate.show_sql  输出所有SQL语句到控制台. 有一个另外的选择是把org.hibernate.SQL这个log category设为debug。
eg. true | false

hibernate.format_sql  在log和console中打印出更漂亮的SQL。
取值 true | false

hibernate.default_schema  在生成的SQL中, 将给定的schema/tablespace附加于非全限定名的表名上.
取值 SCHEMA_NAME

hibernate.default_catalog  在生成的SQL中, 将给定的catalog附加于非全限定名的表名上.
取值 CATALOG_NAME

hibernate.session_factory_name  SessionFactory创建后,将自动使用这个名字绑定到JNDI中.
取值 jndi/composite/name

hibernate.max_fetch_depth  为单向关联(一对一, 多对一)的外连接抓取(outer join fetch)树设置最大深度. 值为0意味着将关闭默认的外连接抓取.
取值 建议在0到3之间取值

hibernate.default_batch_fetch_size  为Hibernate关联的批量抓取设置默认数量.
取值 建议的取值为4, 8, 和16

hibernate.default_entity_mode  为由这个SessionFactory打开的所有Session指定默认的实体表现模式.
取值 dynamic-map, dom4j, pojo

hibernate.order_updates  强制Hibernate按照被更新数据的主键,为SQL更新排序。这么做将减少在高并发系统中事务的死锁。
取值 true | false

hibernate.generate_statistics  如果开启, Hibernate将收集有助于性能调节的统计数据.
取值 true | false

hibernate.use_identifer_rollback  如果开启, 在对象被删除时生成的标识属性将被重设为默认值.
取值 true | false

hibernate.use_sql_comments  如果开启, Hibernate将在SQL中生成有助于调试的注释信息, 默认值为false.
取值 true | false

表 3.4.  Hibernate JDBC和连接(connection)属性

属性名  用途
hibernate.jdbc.fetch_size  非零值,指定JDBC抓取数量的大小 (调用Statement.setFetchSize()).
hibernate.jdbc.batch_size  非零值,允许Hibernate使用JDBC2的批量更新.
取值 建议取5到30之间的值

hibernate.jdbc.batch_versioned_data  如果你想让你的JDBC驱动从executeBatch()返回正确的行计数 , 那么将此属性设为true(开启这个选项通常是安全的). 同时,Hibernate将为自动版本化的数据使用批量DML. 默认值为false.
eg. true | false

hibernate.jdbc.factory_class  选择一个自定义的Batcher. 多数应用程序不需要这个配置属性.
eg. classname.of.Batcher

hibernate.jdbc.use_scrollable_resultset  允许Hibernate使用JDBC2的可滚动结果集. 只有在使用用户提供的JDBC连接时,这个选项才是必要的, 否则Hibernate会使用连接的元数据.
取值 true | false

hibernate.jdbc.use_streams_for_binary  在JDBC读写binary (二进制)或serializable (可序列化) 的类型时使用流(stream)(系统级属性).
取值 true | false

hibernate.jdbc.use_get_generated_keys  在数据插入数据库之后,允许使用JDBC3 PreparedStatement.getGeneratedKeys() 来获取数据库生成的key(键)。需要JDBC3+驱动和JRE1.4+, 如果你的数据库驱动在使用Hibernate的标 识生成器时遇到问题,请将此值设为false. 默认情况下将使用连接的元数据来判定驱动的能力.
取值 true|false

hibernate.connection.provider_class  自定义ConnectionProvider的类名, 此类用来向Hibernate提供JDBC连接.
取值 classname.of.ConnectionProvider

hibernate.connection.isolation  设置JDBC事务隔离级别. 查看java.sql.Connection来了解各个值的具体意义, 但请注意多数数据库都不支持所有的隔离级别.
取值 1, 2, 4, 8

hibernate.connection.autocommit  允许被缓存的JDBC连接开启自动提交(autocommit) (不建议).
取值 true | false

hibernate.connection.release_mode  指定Hibernate在何时释放JDBC连接. 默认情况下,直到Session被显式关闭或被断开连接时,才会释放JDBC连接. 对于应用程序服务器的JTA数据源, 你应当使用after_statement, 这样在每次JDBC调用后,都会主动的释放连接. 对于非JTA的连接, 使用after_transaction在每个事务结束时释放连接是合理的. auto将为JTA和CMT事务策略选择after_statement, 为JDBC事务策略选择after_transaction.
取值 auto (默认) | on_close | after_transaction | after_statement

注意,这些设置仅对通过SessionFactory.openSession得到的Session起作用。对于通过 SessionFactory.getCurrentSession得到的Session,所配置的CurrentSessionContext实现控制 这些Session的连接释放模式。请参阅第 2.5 节 “上下文相关的(Contextual)Session”。

hibernate.connection.<propertyName>  将JDBC属性propertyName传递到DriverManager.getConnection()中去.
hibernate.jndi.<propertyName>  将属性propertyName传递到JNDI InitialContextFactory中去.

表 3.5.  Hibernate缓存属性

属性名  用途
hibernate.cache.provider_class  自定义的CacheProvider的类名.
取值 classname.of.CacheProvider

hibernate.cache.use_minimal_puts  以频繁的读操作为代价, 优化二级缓存来最小化写操作. 在Hibernate3中,这个设置对的集群缓存非常有用, 对集群缓存的实现而言,默认是开启的.
取值 true|false

hibernate.cache.use_query_cache  允许查询缓存, 个别查询仍然需要被设置为可缓存的.
取值 true|false

hibernate.cache.use_second_level_cache  能用来完全禁止使用二级缓存. 对那些在类的映射定义中指定<cache>的类,会默认开启二级缓存.
取值 true|false

hibernate.cache.query_cache_factory  自定义实现QueryCache接口的类名, 默认为内建的StandardQueryCache.
取值 classname.of.QueryCache

hibernate.cache.region_prefix  二级缓存区域名的前缀.
取值 prefix

hibernate.cache.use_structured_entries  强制Hibernate以更人性化的格式将数据存入二级缓存.
取值 true|false

表 3.6.  Hibernate事务属性

属性名  用途
hibernate.transaction.factory_class  一个TransactionFactory的类名, 用于Hibernate Transaction API (默认为JDBCTransactionFactory).
取值 classname.of.TransactionFactory

jta.UserTransaction  一个JNDI名字,被JTATransactionFactory用来从应用服务器获取JTA UserTransaction.
取值 jndi/composite/name

hibernate.transaction.manager_lookup_class  一个TransactionManagerLookup的类名 – 当使用JVM级缓存,或在JTA环境中使用hilo生成器的时候需要该类.
取值 classname.of.TransactionManagerLookup

hibernate.transaction.flush_before_completion  如果开启, session在事务完成后将被自动清洗(flush)。 现在更好的方法是使用自动session上下文管理。请参见第 2.5 节 “上下文相关的(Contextual)Session”。
取值 true | false

hibernate.transaction.auto_close_session  如果开启, session在事务完成后将被自动关闭。 现在更好的方法是使用自动session上下文管理。请参见第 2.5 节 “上下文相关的(Contextual)Session”。
取值 true | false

表 3.7.  其他属性

属性名  用途
hibernate.current_session_context_class  为”当前” Session指定一个(自定义的)策略。关于内置策略的详情,请参见第 2.5 节 “上下文相关的(Contextual)Session” 。
eg. jta | thread | managed | custom.Class

hibernate.query.factory_class  选择HQL解析器的实现.
取值 org.hibernate.hql.ast.ASTQueryTranslatorFactory or org.hibernate.hql.classic.ClassicQueryTranslatorFactory

hibernate.query.substitutions  将Hibernate查询中的符号映射到SQL查询中的符号 (符号可能是函数名或常量名字).
取值 hqlLiteral=SQL_LITERAL, hqlFunction=SQLFUNC

hibernate.hbm2ddl.auto  在SessionFactory创建时,自动检查数据库结构,或者将数据库schema的DDL导出到数据库. 使用 create-drop时,在显式关闭SessionFactory时,将drop掉数据库schema.
取值 validate | update | create | create-drop

hibernate.cglib.use_reflection_optimizer  开启CGLIB来替代运行时反射机制(系统级属性). 反射机制有时在除错时比较有用. 注意即使关闭这个优化, Hibernate还是需要CGLIB. 你不能在hibernate.cfg.xml中设置此属性.
取值 true | false

3.4.1.  SQL方言
你应当总是为你的数据库将hibernate.dialect属性设置成正确的 org.hibernate.dialect.Dialect子类. 如果你指定一种方言, Hibernate将为上面列出的一些属性使用合理的默认值, 为你省去了手工指定它们的功夫.

表 3.8.  Hibernate SQL方言 (hibernate.dialect)

RDBMS 方言
DB2 org.hibernate.dialect.DB2Dialect
DB2 AS/400 org.hibernate.dialect.DB2400Dialect
DB2 OS390 org.hibernate.dialect.DB2390Dialect
PostgreSQL org.hibernate.dialect.PostgreSQLDialect
MySQL org.hibernate.dialect.MySQLDialect
MySQL with InnoDB org.hibernate.dialect.MySQLInnoDBDialect
MySQL with MyISAM org.hibernate.dialect.MySQLMyISAMDialect
Oracle (any version) org.hibernate.dialect.OracleDialect
Oracle 9i/10g org.hibernate.dialect.Oracle9Dialect
Sybase org.hibernate.dialect.SybaseDialect
Sybase Anywhere org.hibernate.dialect.SybaseAnywhereDialect
Microsoft SQL Server org.hibernate.dialect.SQLServerDialect
SAP DB org.hibernate.dialect.SAPDBDialect
Informix org.hibernate.dialect.InformixDialect
HypersonicSQL org.hibernate.dialect.HSQLDialect
Ingres org.hibernate.dialect.IngresDialect
Progress org.hibernate.dialect.ProgressDialect
Mckoi SQL org.hibernate.dialect.MckoiDialect
Interbase org.hibernate.dialect.InterbaseDialect
Pointbase org.hibernate.dialect.PointbaseDialect
FrontBase org.hibernate.dialect.FrontbaseDialect
Firebird org.hibernate.dialect.FirebirdDialect

三、PO.hbm.xml属性详解

1. <meta>元素的属性

属性                                                描述
class-description                            指定描述类的javaDoc
field-description                            指定描述类的属性javaDoc
interface                                    如果为true,表明生成接口而非类,默认false
implements                                   指定类所实现的接口
extends                                      指定继承的父类名
generated-class                              重新指定生成的类名
scope-class                                  指定类的修饰符,默认public
scope-set                                    指定set方法的修饰符,默认public
scope-get                                    指定get方法的修饰符,默认public
scope-field                                  指定类的属性的修饰符,默认private
use-in-toString                              如果为true,表示在toString()方法中包含此属性
gen-property                                 如果为false,不会在java类中生成此属性,默认true
finder-method                                指定find方法名
2. <column>元素属性
name                 设定字段名字
length               设定字段长度
not-null             如为true,指名该字段不允许为null,默认false
unique               如为true,指名该字段具有唯一约束,默认false
index                给一个或多个字段建立索引
unique-key           为多个字段设定唯一约束
foreign-key          为外键约束命名,在<many-to-many><one-to-one><key><many-to-one>元素中包含
foreign-key属性,在双向关联中,inverse属性为true的一端不能设置foreign-key
sql-type             设定字段sql类型
check                设定sql检查约束
3. 用于控制insert or update 语句的映射属性

<property>元素的insert属性                  如为false,在insert中不包含该字段,默认为true
<property>元素的update属性                  如为false,在update中不包含该字段,默认为true
<class>元素的mutable属性                    如为false,等价于所有字段的update属性为false,默认为true
<property>元素的dunameic-insert属性         如为true,表明动态生成insert语句,只有不为null,才会包含insert语句中,默认false
<property>元素的dunameic-update属性         如为true,表明动态生成update语句,只有不为null,才会包含insert语句中,默认false
<class>元素的dunameic-insert属性            如为true,表明等价于所有字段动态生成insert语句,只有不为null,才会包含insert语句 中                                               ,默认false
<class>元素的dunameic-update属性            如为true,表明等价于所有字段动态生成update语句,只有不为null,才会包含insert语句 中                             ,默认false

4. Hibernate提供的内置标识符生成器
increment       适用于代理主键,自动递增,增1(只能是long,int,short)
identity        适用于代理主键,底层数据库自动增长字段类型(数据库需支持,只能是long,int,short)
(oralce)sequence    适用于代理主键,根据底层数据库的序列来生成标识符(数据库支持序列,只能是long,int,short)
hilo            适用于代理主键,根据high/low算法来生成.Hibernate把特定表的字段作为high值,在默认情况下选用hibernate_unique_key表的next_hi字段
(mysql,mssql)native 适用于代理主键,根据数据库自动生成标识符支持能力,来选择identity,sequence,hilo
uuid.hex        适用于代理主键,采用128位UUID(universal unique identification)算法来生成标识.此算法能在网络环境中生成唯一的字符串标识符,
(不建议使用,字符串类型比整形类型的主键占用更多的空间)
assigned        适用于自然主键,由java程序负责生成.

5. <hibernate-mapping>
<class name=”项目路径” table=”库中对应表名” schema=”dbo” catalog=”netoa”>
<meta attribute=”class-description”>指定描述类的javaDoc</meta>
<meta attribute=”class-scope”>指名类的修饰类型</meta>
<meta attribute=”extends”>指定继承类</meta>
<id name=”bgrkbh” type=”long”>
<column name=”BGRKBH” precision=”15″ scale=”0″ sql-type=”库中类型” check=”BGRKBH>10″/>
<meta attribute=”scope-set”>指定类,类属性的getxxx(),setxxx()方法的修饰符
包括:static,final,abstract,public,protected,private
</meta>
<generator />
</id>
<property name=”Class.fileName” type=”long”>
<column name=”YSLX” precision=”精度” scale=”刻度” not-null=”默认false” sql-type=”数据库中类型”/>
附加属性不会影响Hibernate的运行行为
<meta attribute=”field-description”>指定描述类的javaDoc</meta>
指定描述类属性的javaDoc
</property>
</class>
</hibernate-mapping>
注意:
1 Session的commit()和flush()方法的区别,flush()方法进行清理缓存的操作,执行一系列的SQL语句,但不会提交事务;
commit()方法会先调用flush(),然后提交事务.提交事务意味着对数据库所作的更新被永久保存下来.

2 Session的setFlushMode()方法用于设定清理缓存的时间点.FlushMode类定义了三种不同的清理模式

清理缓存的模式        Session的查询方法                Session的commit()方法       Session的flush()方法
FlushMode.AUTO           清理                                  清理                                   清理
FlushMode.COMMIT         不清理                             清理                                清理
FlushMode.NEVER          不清理                             不清理                              清理

3 Hibernate应用中java对象的状态
临时状态 (transient):刚刚用new语句创建,还没被持久化,不处与Session的缓存中,处于临时状态的java对象被称为临时对象.
持久化状态(persistent):已经被持久化,加入session的缓存中.处于持久化状态的java对象被称为持久化对象.
游离状态(detached):已经被持久化,但不在处于session的缓存中.处于游离状态的java对象被称为游离对象.
(注意:::::)持久化类与持久化对象是不同的概念.持久化类的实例可以处于临时状态,持久化状态和游离状态.其中处于
持久化状态的实例 被称为持久化状态.

6. 临时对象的特性:
1 不处于缓存中,也可以说,不被任何一个Session实例关联
2 在数据中没有对应的纪录.

在此情况下,java对象进入临时状态
1 当通过new创建一个对象时,此时不和数据库中的任何纪录的

ex:对象的状态转化过程

程序代码                                                            对象的生命周期              对象的状态
tx=session.beginTransaction();
Object obj=new Object(“tow”,new HashSet());      开始生命周期                临时状态

session.save(obj);                                                  处于生命周期              转化为持久状态

Long id=obj.getId();
obj=null;
Object obj2=(Object)session.load(Object.class,id); 处于生命周期             处于持久化状态
tx.commit();

session.close();                                                    处于生命周期              转变成游离状态

System.out.print(obj2.getName());                         处于生命周期               处于游离状态

obj2=null;                                                              结束生命周期              结束生命周期

7. cascade属性:

cascade属性值                                             描述
none                                    在保存更新时,忽略其他关联对象,他是cascade默认属性
save-update                             当通过Session的save(),update()以及saveOrUpdate()方法来保存
或更新当前对象时,及联保存所有关联的新建的临时对象,并且及联更新所有关联的游离对象
delete                                  当通过session的delete()方法删除当前对象时,及联删除所有对象
all                                     包含save-update及delete行为,此外对当前对象执行evict()或lock
()操作时,也会对所有关联的持久化对象执行evict()或lock()操作
delete-orphan                           删除所有和当前对象解除关联关系的对象
all-delete-orphan                       包含all和delete-orphan

8.  Hibernate映射类型,对应的java基本类型及对应的标准SQL类型类型类型:

映射类型          java 类型                                                             标准 sql 类型

integer         int or Integer                                                           INTEGER
long long or java.lang.Long                                           BIGINT
short short or java.lang.Short                                        SMALLINT
float float or java.lang.Float                                            FLOAT
double double or java.lang.Double                                 DOUBLE
big_decimal     java.math.BigDecimal                                         NUMERIC
character       java.lang.String                                                   CHAR(1)
string          java.lang.String                                                      VARCHAR
byte byte or java.lang.Byte                                            TINYINT
boolean boolean or java.lang.Boolean                              BIT
yes_no          boolean or java.lang.Boolean                          CHAR(1)(‘Y’ or ’N')
true_false      boolean or java.lang.Boolean                         CHAR(1)(‘Y’ or ’N')
date            java.util.Date or java.sql.Date                              DATE
time            java.util.Date or java.sql.Time                              TIME
timestamp       java.util.Date or java.sql.TimeStamp                 TIMESTAMP
calendar        java.util.Calendar                                              TIMESTAMP
calendar_date   java.util.Calendar                                           DATE
binary          byte[]                                                               VARBINARY( or BLOB)
text            java.lang.String                                                 CLOB
serializable    java.io.Serializable                                        VARBINARY (or BLOB)
clob            java.sql.Clob                                                   CLOB
blob            java.sql.Blob                                                  BLOB
class java.lang.Class                                              VARCHAR
locale          java.util.Locale                                              VARCHAR
timezone        java.util.TimeZone                                      VARCHAR
currency        java.util.Currency                                           VARCHAR

转自:http://magicpear.comxa.com/hibernate-detailed-configuration.html

Hibernate学习(二)Hibernate的核心接口

 (2012-10-24 19:48:44)
转载
标签: 

hibernate的核心接口

 

configuration

 

sessionfactory

 

session

transaction

分类: Hibernate
Hibernate作为持久成中间件,它的具体实现对与上层调用是透明的,即上层通过接口来调用Hibernate的具体实现,所以对于入门级别的讨论来说,自然应该先从接口开始了。
 
所有的Hibernate应用都会访问它的5个核心接口,分别如下:
Configuration接口:
SessionFactory接口:
Session接口:
Transaction接口:
Query和Criteria接口:
 Configuration接口,SessionFactory接口,Session接口,Transaction接口, Query他们之间的关系,请参看:http://blog.sina.com.cn/s/blog_7ffb8dd5010142hu.html中的测试类
分别简单介绍一下:
1、Configuration接口
Configuration用于配置并启动Hibernate。Hibernate应用通过Configuration的实例来指定对象-关系映射文件, 或通过Configuration动态配置Hibernate的属性,然后通过Configuration来创建相应的SessionFactory实 例。Configuration实例是什么时候指定ORM文件的地址的呢?我们可以查看Configuration的源代码,它的configure()方法是这样实现的:

public Configuration configure() throws HibernateException {

       configure( "/hibernate.cfg.xml" );//此处指定了ORM文件的位置

       return this;

   }

原来它是在这里指定了ORM文件的位置,这就是为什么Hibernate总是默认到classpath下去寻找hibernate.cfg.xml 文件的原因了。实际上我们还可以通过configure(String resource)来动态的指定配置文件,只不过通常我们都是采用的默认设置罢了。这样的话我们的配置文件就都被读取了,同时配置文件中通 过<mapping>元素引入的映射文件也被读取了。

 
2、SessionFactory接口
一个SessionFactory对应一个数据源,它是个重量级对象,不可随意生成多个实例。对于一般的单数据库应用来说,只需要一个 SessionFactory就足够了。当然如果有多个数据库的话,还是需要为每个数据库生成对应的SessionFactory?一般而言,一个SessionFactory对象就代表一个数据库存储源。它是线程安全的,同一 个实例可以被应用中的多个线程共享。由此我们看出SessionFactory具备如下两个特点:

1.  线程安全。整个应用共用一个SessionFactory实例。
2.  重量级。在SessionFactory中存放了Hibernate配置信息以及映射元素据信息,这些都需要很大的缓存。

一般来说,SessionFactory的主要作用就是创建Session对象,所有的线程都是从SessionFactory中获取Session对象来处理客户请求的。


也许你会很好奇,SessionFactory为什么是重量级对象呢?我也同样好奇,通过查看Hibernate的源码,发现 SessionFactory存放了大量预定义的SQL语句以及映射元数据,所以自然需要很大的缓存了,同时需要一定的CPU时间来计算生成。想想 Hibernate的这个设计是很有意义的,因为有了Mapping文件,很多SQL语句就已经确定了,只需要动态生成一次就可以了,这个设计也是为了提 高持久化的效率。
 
3、Session接口
从SessionFactory中可以获得Session实例。
Session接口是Hibernate应用中使用最广泛的接口了,它是持久化管理器,提供添加、更新、删除、加载、查询对象Session的每个方法都值得我们去研究和探讨,不过最常用的还是save、saveOrUpdate、update、delete、createQuery等方法了,关于Session是如何作用的以及它的工作原理在以后的实践中再一步一步的进行学习和探讨!!Session不是线程安 全的,所以应避免多个线程共享同一个Session实例。Session是轻量级对象,它的创建和销毁不需要太多资源,这意味着在应用中可以经常创建和销 毁Session对象。
Session有一个缓存,称之为Hibernate的一级缓存,它存放当前工作单元加载的持久化对象,每个Session都有自己的缓存,缓存中的对象只能被当前工作单元访问。
 
4、Transaction接口
Transaction是Hibernate的数据库事务接口,它对底层道德事务接口进行了封装,底层事务接口包括:
    JDBC API
   JTA(Java Transaction API)
   CORBA(Common Object Requet Broker Architecture) API
Hibernate应用可以通过一致Transaction接口来声明事务边界,这有助于应用可以在不同的环境或容器中移植。具体的事务实现使用在Hibernate.properties中进行指定。
 
5、Query和Criteria接口(也叫条件查询接口)
这两个是Hibernate的查询接口,用于向数据库查询对象,以及控制执行查询的过程。Query实例包装了一个HQL(Hibernate Query Language)来查询。Criteria接口完全封装了基于字符串形式的查询语句,比Query更面向对象,Criteria更擅长执行动态查询。
标准化对象查询(Criteria Query):以对象的方式进行查询,将查询语句封装为对象操作。优点:可读性好,符合Java 程序员的编码习惯。缺点:不够成熟,不支持投影(projection)或统计函数(aggregation)
Hibernate语言查询(Hibernate Query Language,HQL):它是完全面向对象的查询语句,查询功能非常强大,具备继承、多态和关联等特性 。Hibernate官方推荐使用HQL进行查询。

 
以上为5个核心接口,当然Hibernate不仅仅只有这5个接口了,还有回调接口、映射类型接口、可扩展的接口等等,但这些接口不同于以上的5个核心接口,因为这些接口在一般的Hibernate中不一定能用到,所以暂不提及,在以后的高级应用中再做详述吧。

Hibernate学习(三):Session的缓存及对象的状态

 (2012-10-24 20:47:28)
转载
标签: 

session的缓存

 

瞬时状态(transient)

 

持久化状态(persisten

脱管状态(detached)

分类: Hibernate

一.Session的缓存

       Java是纯面向对象的语言,因此不可能像C语言那样直接操纵内存,例如声明一段可用的内存空间。在Java里面,缓存通常是指Java对象的属性占用的 内存空间,通常是一些集合类型的属性。在session接口的实现类SessionImpl中定义了一系列的Java集合,这些Java集合就构成了 Session的缓存。
       使用缓存的一个很明显的好处就是可以减少数据库访问的频率,提高应用程序的性能,因为从内存中读取数据显然要比从数据库中查询快多了。

二.Hibernate中Java对象的状态

在一个Hibernate应用中,Java对象可以处于以下三个状态之一:

1.瞬时状态(Transient):也叫临时状态,处于这个状态的对象还被没有纳入Hibernate的缓存管理体系,跟任何session都不关联,在数据库中也没有对应的记录。超过作用域会被JVM垃圾回收器回收,一般是new出来且与session没有关联的对象。
2.持久化状态(Persistent)处于这个状态的对象位于Session的缓存中,并且和数据库中的一条数据记录相对应。并且相关联的session没有关闭,事务没有提交,持久对象状态发生改变,在事务提交时会影响到数据库(hibernate能检测到)。
3.脱管状态(Detached):也叫游离状态,处于这个状态的对象不再位于Session的缓存中,当前没有session与之关联;托管对象状态发生改变,hibernate不能检测到。它与临时对象的最大区别在于,游离对象在数据库中还可能存在一条与它对应的记录

          上述3个状态之间是可以相互转化的,而且我们所说的状态都是针对某一个session实例而言的,比方说,对象A对于session1而言是处于持久化状态的,因为它处于session1的缓存中,但是对于session2而言对象A并不在它的缓存中,因此它是处于游离状态的。
          对于这几个状态的理解花费了我一定的时间,因为总是有一些稀奇古怪的念头在我脑海中产生。比如说,对于临时状态的定义,如果我新建一个对象,然后人为的让 它属性的值和数据库中的一条记录对应,包括id的取值都一样。此时它能否说是处于游离状态呢?因为它和一条记录想对应呀。实际上这些情况都是由于一些不和 规范的操作而产生的。在Hibernate应用中,无论Java对象处于临时状态、持久化状态还是游离状态,应用程序都不应该修改它的OIDOID(也就是实体类中的主键属性)的值应该由Hibernate来维护和负责,实际上Hibernate在同步缓存中的对象与数据库中的记录时,都是通过OID来进行关联和映射的,如果应用程序人为的修改了对象的OID,就会导致一些莫名其妙的错误,而且这样也不利于数据的同步。
             至于对象之间的状态转化,如下图:

Hibernate学习(三):Session的缓存及对象的状态
有关更详细的讲解,请参看:http://blog.renren.com/share/222980861/1421652349

Hibernate学习(四):session.save()

 (2012-10-24 21:12:46)
转载
标签: 

session.save()

 

杂谈

分类: Hibernate

一切的一切都要从数据的插入开始,没有数据的插入就没有数据来进行更新、删除和修改。在Hibernate中使用最频繁的用来插入数据的方法就是save()方法了。在Hibernate的官方API中对save方法的注释很简单:将指定的临时对象持久化,并首先指定一个标识符,也就是我们所说的OID,但是如果OID的生成策略是assigned的时候除外

注释虽然很简单,但是却向我们披露了足够的信息。我们从输入、操作、输出对它进行分析。

1.输入:一个处于临时状态的对象。这并不是说我们不能使用持久化对象和游离对象做参数,只是说这样操作不合规范。就像男人穿裙子一样,不是说你不能穿,只是这样不合常理而已。

2.操作:首先根据指定的OID生成策略给临时对象生成一个OID,一般来说此时临时对象的OIDNULL,除非你使用了assign策略或者人为的指定了一个OID,但是事实证明这时没有用的,所以在进行插入操作时,我们不应该认为的指定主键的值(OID);接着把这个对象置入缓存中,使它成为持久化对象;最后,计划一个insert语句,注意,只是计划,并没有执行,只有当Session清理缓存时才执行sql语句。

3.输出:一个持久化对象和一条sql语句,这个说法不是很准确,这样说只是为了便于理解而已。


前面我们说人为指定OID是没有用的,可以通过如下的代码片段来进行验证:

Customer customer=new Customer();

    customer.setId(3L);

    session.save(customer);

System.out.println(customer.getId());

结果表明,程序最后输出的ID是根据标识符生成器生成的。另外还要注意的一点就是,当对象处于持久化状态时,不能再随意修改它的OID,否则Session在清理缓存时会抛出异常,如:

Customer customer=new Customer();

    session.save(customer);

customer.setId(3L);

tx.commit();

此时程序抛出如下异常:org.hibernate.HibernateException: identifier of an instance of cn.edu.hust.cm.mypack.Customer was altered from 7 to 3

我还做了如下一个实验,代码片段如下:

Customer customer=new Customer();

    session.save(customer);

session.save(customer);

tx.commit();

第一次调用save()方法时customer处于临时状态,而第二次调用save()方法是时它已经处于持久化状态了,事实证明第二次的save操作完全是多余的,Hibernate并没有为它再计划一个insert语句。

Hibernate学习(五):session.update

 (2012-10-24 21:25:56)
转载
标签: 

session.update

 

hibernate

 

杂谈

分类: Hibernate

关于Session接口的update方法主要有如下几点要注意:

1.输入参数

一般而言,传递给update的对象要是处于游离状态的对象。如果传一个持久化对象,那么update方法就是多余的,因为Hibernate的脏检查机制会自动根据对象属性值的变化向数据库发送一条update语句;如果传入的对象处于临时状态,那么此时Hibernate应该会抛出异常。因为Hibernate在更新数据时会根据对象的OID去数据库查找相应的记录并更新之,而在数据库中是没有记录与这个临时对象相关联的,因此Hibernate会抛出异常当然如果你人为的给临时对象指定一个OID就该另当别论了,如下所示代码片段:

…………………………………………

Customer customer=new Customer();

customer.setId(3L);

customer.setName(“Cindyelf”);

session.update(customer);

…………………………………………

这段代码会导致如下的sqlupdate Customer set name=’Cindyelf’ where  id=3;当然如果数据库不存在id3的那行记录,Hibernate就会抛出异常。而给临时对象指定OID是不合规范的操作,应尽量避免。也就是说不管传入是什么状态对象,数据库中必须要有一条记录与这个对象的OID相对应,否则抛出异常。

2.操作

执行update方法的时候,Hibernate会首先把传入的对象放入Session的缓存中,使之持久化,然后计划执行一个update语句。Hibernate在生成sql语句的时候会根据对象的当前属性值来组装sql语句,也就是说,不管程序中修改了多少次属性值,在执行时只会执行一条update一句。

此外,在update的官方API中特意强调了一点,“如果在session的缓存中有一个持久化对象和所要更新的对象具有相同的OID,那么Hibernate会抛出异常”。下面的代码片段演示了这个错误:

…………………………………………

Customer customer=new Customer();

session1.save(customer);

…………………………………………

…………………………………………

Customer customer1=(Customer)session2.load(Customer.class,new Long(6))

session2.update(customer);

…………………………………………

如上所示,我在session1中持久化了一个Customer对象,它的OID6,然后我在session2load一个OID6的对象customer1,然后在session2updatecustomer也是持久化的,注意,对于session2而已,customer1此时处于持久化状态,因为它处于session2的缓存中。因为custom和custom1这两个持久化对象拥有相同的OID,此时程序会报如下错误a different object with the same identifier value was already associated with the session

本文出自 “java之路” 博客,请务必保留此出处http://2402766.blog.51cto.com/2392766/615900

Hibernate学习(六):session.delete以及对象状态转换图

 (2012-10-24 21:46:58)
转载
标签: 

session.delete

 

杂谈

分类: Hibernate

delelte方法从某种程度上来说和update方法很类似,特别是对传入实例的要求,只要所传入实例的OID在数据库中有对应的记录即可,否则Hibaernate就会抛出异常。我们还是从对象能够处于的3个状态来一一阐述。

1.传入实例是临时状态。一般来说这是不规范的操作,当然你必须要人为的给它指定OID,而且这个OID必须和数据库中的一条记录对应。

2.传入实例是游离状态。前面我们说过,游离状态与临时状态的最大区别就是在数据库中可能存在一条记录与之对应,因此如果这个游离的实例不存在与之对应的数据库记录,Hibernate就会抛出异常。

3.传入实例是持久化状态。嘿嘿,这种情况就不用说了吧。

总之,对于游离状态而言,delete方法从数据库中删除与它对应的记录(前提是有这条记录,否则异常);对于持久化对象而言,delete方法从数据库中删除与它对应的对象,并且把它从session的缓存中删除,此时状态变为临时状态。

下图简单的展示了对象的状态变化图:

图中各个方法的详细说明可以在Hibernate发布包中的api文档中找到,这里就不赘述了,^_^

Hibernate学习(七):session.flush与transaction.commit

 (2012-10-24 21:57:39)
转载
标签: 

session.flush

 

杂谈

分类: Hibernate

sessionsave方法为例来看一个简单、完整的事务流程,如下是代码片段:

…………………………………………………………………………

Session session = sessionFactory.openSession();

Transaction tx = session.beginTransaction();

session.save(customer);//之前已实例化好了的一个对象

tx.commit();

…………………………………………………………………………

示例很简单,就是向数据库中插入一条顾客信息,这是一个最简单的数据库事务。在这个简单的过程中,Hibernate为我们做了一些什么事情呢?为了更好的观察,我们将Hibernateshow_sql属性设置为true,然后运行我们的程序,控制台打印出如下信息:

Hibernate: select max(ID) from CUSTOMER

Hibernate: insert into CUSTOMER (NAME, EMAIL, PASSWORD, PHONE, ADDRESS, SEX, IS_MARRIED, description, BIRTHDAY, REGISTERED_TIME, ID) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)

这里也许看不出什么端倪来,现在在session.save(customer)后面加一行代码,输出这个customerOIDSystem.out.println(customer.getId()),再次运行程序,控制台输出为:

Hibernate: select max(ID) from CUSTOMER

22

Hibernate: insert into CUSTOMER (NAME, EMAIL, PASSWORD, PHONE, ADDRESS, SEX, IS_MARRIED, description, BIRTHDAY, REGISTERED_TIME, ID) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)

OIDinsert语句之前输出,这可以说明两个问题:1.insert语句并不是在执行save的时候发送给数据库的;2.insert语句是在执行commit的时候发送给数据库的。结合前面我们所说过的:执行save的时候,Hibernate会首先把对象放入缓存,然后计划一条insert语句。一个基本的插入流程就出来了:

1.  判断所要保存的实例是否已处于持久化状态,如果不是,则将其置入缓存;

2.  根据所要保存的实例计划一条insert sql语句,注意只是计划,并不执行;

3.  事务提交时执行之前所计划的insert语句;

后台还打印出了select max(ID) from CUSTOMER,这主要是为了给customer赋予一个OID,因为一般情况下临时对象的OIDNULL

接着我们做两个测试:

1.  tx.commit();注释掉,此时控制台没有打印出insert语句;

2.  tx.commit()换成session.flush,此时控制太打印出了insert语句,但是数据库中并没有添加新的记录;

通过查阅HibernateAPI可以知道flush方法的主要作用就是清理缓存,强制数据库

Hibernate缓存同步,以保证数据的一致性。它的主要动作就是向数据库发送一系列的sql语句,并执行这些sql语句,但是不会向数据库提交。而commit方法则会首先调用flush方法,然后提交事务。这就是为什么我们仅仅调用flush的时候记录并未插入到数据库中的原因,因为只有提交了事务,对数据库所做的更新才会被保存下来。因为commit方法隐式的调用了flush,所以一般我们都不会显示的调用flush方法。

本文出自 “java之路” 博客,请务必保留此出处http://2402766.blog.51cto.com/2392766/615969

Hibernate学习(八):检索方式

 (2012-10-24 22:00:33)
转载
标签: 

检索方式

 

杂谈

分类: Hibernate

Hibaernate中提供了丰富的检索(查询)方式,因为项目中涉及到查询特别是复杂查询的时候基本上用的都市iBatis,所以一直都没怎么用Hibaernate自带的查询方法。总的说来Hibernate有如下集中查询方式:

1.根据OID检索某条指定的记录,典型方法如session.load()session.get()

      2HQL检索方式。HQLHibernate Query Language的所写,形式类似SQL语句,它是完全面向对象的查询语句,查询功能非常强大,具备继承、多态和关联等特性 。Hibernate官方推荐使用HQL进行查询。而SQL是面向关系的查询语句。使用这种检索方式的典型方法是session.createQuery(String hql),在Hibernate2.0中还有一个session.find方法也是采用的这种检索方式,不过已淘汰了;

3QBC检索方式。使用Criteria接口的API来检索对象。它封装了基于字符串形式的查询语句,提供了更加面向对象的接口。以对象的方式进行查询,将查询语句封装为对象操作。优点:可读性好,符合Java 程序员的编码习惯。缺点:不够成熟,不支持投影(projection)或统计函数(aggregation)

4.原生SQL检索。使用本地数据库的SQL查询语句。Hibernate会负责把检索到的JDBC ResultSet结果集映射为持久化对象图。典型方法如session.createSQLQuery(String sql)

第一种检索方式使用的已经很普遍了,而且也十分简单,下面主要看后三种检索方式。

一.HQL检索方式

代码片段如下:

…………………………………………………………………………………………

Query query=session.createQuery(“from Customer as c where c.name=:name”);

 

query.setString(“name”,”CMTobby”);

 

List result=query.list();

…………………………………………………………………………………………

一个典型的HQL检索可以分为3个步骤:

1.创建一个Query类型的对象,它包含一个HQL语句;如上面红底的代码,注意from后面跟的是类名而不是表名;

2.动态绑定参数(如果使用了动态参数的话)。动态绑定参数有两种方式:命名参数绑定和位置参数绑定。上例中采用的命名参数绑定,形式是“冒号:参数名”。还有一种位置参数绑定,如下:

Query query=session.createQuery(“from Customer as c where c.name=?”);

query.setString(0,”CMTobby”);

这个方式同JDBC中的预编译方式相似。当同时使用命名参数和位置参数时,位置参数必须出现在命名参数之前,否则运行出错如下面的代码:

Query query=session.createQuery(“from Customer as c where c.name=:name and c.sex=?”);

query.setString(0,”F”);

query.setString(“name”,”CMTobby”);

运行时会报错:cannot define positional parameter after any named parameters have been defined

3.调用list()方法执行查询语句。

二.QBC检索方式

代码片段如下:

…………………………………………………………………………………………

Criteria criteria=session.createCriteria(Customer.class);

 

Criterion criterion1=Expression.eq("sex", "F");

Criterion criterion2=Expression.like("name", "%sb1%");

criteria.add(criterion1);

criteria.add(criterion2);

 

Result list= criteria.list();

…………………………………………………………………………………………

一个典型的QBC可以分为如下几个步骤:

1.创建一个Criteria类型的对象。上面的红色代码所示。这里我们可以看出QBC是面向对象的,并且显然不支持多表的联合查询,因为它是针对某个持久化类进行的。

2.指定查询条件,如上面的绿色代码所示。每一个Criterion类型的对象代表一个查询条件,把所有的Criterion类型对象增加到Criteria中,Criteria可以看成是一个Criterion的集合,在英文中Criteria就是Criterion的复数形式,因此了解点e文对于我们理解程序还是有帮助的,^_^。指定查询条件我们使用的是Expression类,它继承自Restrictions类,它里面定义了很多设定查询条件的方法,详细情况可以看它的API文档。

3.调用list()方法执行查询语句。

三.使用原生SQL检索(Native SQL)

一个典型的代码如下所示:

…………………………………………………………………………………………

Query query=session.createSQLQuery(“selct * from CUSTOMORS where name=:name”);

   

query.setString(“name”,”CMTobby”);

 

List result=query.list();

…………………………………………………………………………………………

 

    这种检索方式和HQL检索方式非常类似,只不过查询语句的风格不同而已,就不详细说明了。

本文出自 “java之路” 博客,请务必保留此出处http://2402766.blog.51cto.com/2392766/617211



0 0