hibernate.cfg.xml基础配置
(一)基础配置介绍
<?xml version='1.0' encoding='gb2312'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<!--声明Hibernate配置文件的开始-->
<hibernate-configuration>
<!--表明以下的配置是针对session-factory配置的,SessionFactory是Hibernate中的一个类,这个类主要负责保存HIbernate的配置信息,以及对Session的操作-->
<session-factory>
<!-- 数据库基础配置 (以下四个必须配置)-->
<!--配置数据库的驱动-->
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver </property>
<!--设置数据库的连接url本机-->
<property name="hibernate.connection.url">jdbc:mysql://localhost/hibernate </hibernate>
<!--连接数据库是用户名-->
<property name="hibernate.connection.username">root </property>
<!--连接数据库是密码-->
<property name="hibernate.connection.password">123456 </property>
<!--数据库连接池的大小-->
<property name="hibernate.connection.pool.size">20 </property>
<!--是否在后台显示执行SQL语句,开发时设置为true,便于查错-->
<property name="hibernate.show_sql">true </property>
<!-- 格式化SQL -->
<property name="hibernate.format_sql">true</property>
<!--是Hibernate使用的数据库方言,
是要用Hibernate连接那种类型的数据库服务器。
需要配置的-->
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect </property>
<!-- 自动建表
当不存在指定数据库的表的的时候, 加上这个配置可以自动创建表。当然,需要配置好映射。
create-drop 每次在创建sessionfactory的时候,执行创建表。
当调用sessionfactory的close方法的时候,删除表。
create 每次都重新建表,如果表已经存在先删除再创建
update 表不存在则创建,表存在就不创建
validate (生产环境)执行验证,当映射文件的内容与数据库的表结构不一样,则报错
-->
<property name="hibernate.hbm2ddl.auto">update</property>
<!--指Hibernate每次从数据库中取出并放到JDBC的Statement中的记录条数。
Fetch Size设的越大,读数据库的次数越少,速度越快,
Fetch Size越小,读数据库的次数越多,速度越慢
-->
<property name="jdbc.fetch_size">50 </property>
<!--指Hibernate批量插入,删除和更新时每次操作的记录数。
Batch Size越大,批量操作的向数据库发送Sql的次数越少,速度就越快,同样耗用内存就越大-->
<property name="jdbc.batch_size">23 </property>
<!--是否允许Hibernate用JDBC的可滚动的结果集。
对分页的结果集。对分页时的设置非常有帮助-->
<property name="jdbc.use_scrollable_resultset">false </property>
<!--连接数据库时是否使用Unicode编码-->
<property name="Connection.useUnicode">true </property>
<!--连接数据库时数据的传输字符集编码方式-->
<property name="connection.characterEncoding">utf-8</property>
<!--指定映射文件为“hibernate/ch1/UserInfo.hbm.xml”-->
<mapping resource="org/hibernate/entity/User.hbm.xml">
</session-factory>
(二)hibernate对连接池的支持
在hibernate.properties中有 c3p0 Connection Pool的配置
<!-- 配置连接驱动管理类
C3P0的驱动类:org.hibernate.connection.C3P0ConnectionProvider
hibernate还支持其他的连接池:
org.hibernate.connection.DriverManagerConnectionProvider
org.hibernate.connection.DatasourceConnectionProvider
org.hibernate.connection.ProxoolConnectionProvider
-->
<property name="hibernate.connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property>
<!-- 配置连接池参数信息 -->
<!-- 最小连接数 -->
<property name="hibernate.c3p0.min_size">2</property>
<!-- 最大连接数 -->
<property name="hibernate.c3p0.max_size">4</property>
<!-- 超时时间 -->
<property name="hibernate.c3p0.timeout">5000</property>
<!-- 最大执行命令个数
-->
<property name="hibernate.c3p0.max_statements">10</property>
<!-- 空闲测试时间 -->
<property name="hibernate.c3p0.idle_test_period">30000</property>
<!-- 连接不够用的时候,每次增加的连接数 -->
<property name="hibernate.c3p0.acquire_increment">2</property>
(三)hibernate二级缓存
基于应用程序级别的缓存,可以让不同的session访问。hibernate提供的二级缓存有默认的实现,且是一种可插配的缓存框架。如果用户想用二级缓存,只需要在hibernate.cfg.xml中配置即可。
也可以使用其他的缓存框架,或者自己实现缓存框架。
Hibernate的二级缓存作为一个可插入的组件在使用的时候也是可以进行配置的,但并不是所有的对象都适合放在二级缓存中。在通常情况下会将具有以下特征的数据放入到二级缓存中:
- 很少被修改的数据
- 不是很重要的数据,允许出现偶尔并发的数据
- 不会被并发访问的数据
- 参考数据
缓存的范围分为3类:
(1)事务范围(单Session即一级缓存)
事务范围的缓存只能被当前事务访问,每个事务都有各自的缓存,缓存内的数据通常采用相互关联的对象形式.缓存的生命周期依赖于事务的生命周期,只有当事务结束时,缓存的生命周期才会结束.事务范围的缓存使用内存作为存储介质,一级缓存就属于事务范围.
(2)应用范围(单SessionFactory即二级缓存)
应用程序的缓存可以被应用范围内的所有事务共享访问.缓存的生命周期依赖于应用的生命周期,只有当应用结束时,缓存的生命周期才会结束.应用范围的缓存可以使用内存或硬盘作为存储介质,二级缓存就属于应用范围.
(3)集群范围(多SessionFactory)
在集群环境中,缓存被一个机器或多个机器的进程共享,缓存中的数据被复制到集群环境中的每个进程节点,进程间通过远程通信来保证缓存中的数据的一致,缓存中的数据通常采用对象的松散数据形式.
1、二级缓存组件
Hibernate内置支持的二级缓存组件如表所示
集群缓存的概念:
当一台服务器上的执行了update方法修改了一条数据,那么只有这一台服务器上的二级缓存会同步于数据库,其他服务器上的二级缓存里面这条数据就没意义了。这个时候用OSCache缓存机制,只要有一台服务器上有数据修改了,马上会从配置文件中找到配置好的其他服务器IP地址,进行广播,告诉他们我这条数据修改了,你们也更新同步一下。
2、开启二级缓存
在hibernate.cfg.xml文件中配置
<!--****************** 【二级缓存配置】****************** -->
<!-- 开启二级缓存 -->
<property name="hibernate.cache.use_second_level_cache">true</property>
<!-- 指定使用哪一个缓存框架(默认提供的) -->
<property name="hibernate.cache.provider_class">org.hibernate.cache.HashtableCacheProvider</property>
<!-- 开启查询缓存
如果想缓存使用findall()、list()、Iterator()、createCriteria()、createQuery()等方法获得的数据结果集,必须配置此项
-->
<property name="hibernate.cache.use_query_cache">true</property>
<!-- 指定哪一些类,需要加入二级缓存 -->
<class-cache usage="read-write" class="cn.itcast.b_second_cache.Dept"/>
<class-cache usage="read-only" class="cn.itcast.b_second_cache.Employee"/>
<!-- 集合缓存[集合缓存的元素对象,也加加入二级缓存] -->
<collection-cache usage="read-write" collection="cn.itcast.b_second_cache.Dept.emps"/>
<!-- 强制Hibernate以更人性化的格式将数据存入二级缓存 -->
<property name="hibernate.cache.use_structured_entries">true</property>
<!-- Hibernate将收集有助于性能调节的统计数据 -->
<property name="hibernate.generate_statistics">true</property>
PS:也可以在映射中配置二级缓存
<class name="Dept" table="dept">
<!-- 将类加入二级缓存
缓存策略
read-only 放入二级缓存的对象,只读
nonstrict-read-write 放入二级缓存的对象,非严格的读写
read-write 放入二级缓存的对象,读写
treasactional 基于事务的策略
-->
<cache usage="read-only"/>
<!-- 还有其他映射配置... -->
<set>
<!-- 将集合加入二级缓存 -->
<cache usage="read-only"/>
<!-- 还有其他映射配置... -->
</set>
</class>
查询缓存
list()方法获取到的数据会放入缓存当中,但是再次调用却不会从缓存中获取数据。
使用查询缓存,就可以让list()方法从二级缓存中获取数据。
//这样会先去二级缓存中查找数据
Query q = session.createQuery(“from User”).setCacheable(tru
(四)Hibernate3中持久化对象的状态
1、瞬时对象(Transient Objects)
使用new操作符初始化的对象不是立刻就持久化的,他们的状态是瞬时的。
- (1) 不处于Session的缓存中,也可以说,不被任何一个Session实例关联。
- (2) 在数据库中没有对应的记录。
2、持久化对象(Persist Objects)
持久实例是任何具有数据库标识的实例。它有持久化管理器Session统一管理,持久实例是在事务中进行操作的。他们的状态在事务结束时同数据库进行同步。
- (1) 位于一个Session实例的缓存中,也可以说,持久化对象总是被一个Session实例关联。
- (2) 持久化对象和数据库中的相关记录对应。
- (3) Session在清理缓存时,会根据持久化对象的属性变化,来同步更新数据库。
3、离线对象(Detached Objects)
Session关闭之后,持久化对象就变为离线对象。离线表示这个对象不能再与数据库保持同步,他们不再受Hibernate管理。
- (1) 不再位于Session的缓存中,也可以说,游离对象不被Session关联。
- (2) 游离对象是由持久化对象转变过来的,因此在数据库中可能还存在与它对应的记录
映射文件
(一)映射文件简单介绍
<!--
映射文件:映射一个实体类的对象,描述一个兑现给最终实现可以直接保存对象数据到数据库中。
-->
<!-- 所在的包名
package 要映射对象所在的包(可选)
当不指定package属性,则下面所有类的要指定 包名+类名
auto-import="true" 默认为true,在写sql的时候,自动导入包名
如果指定为false,在写hql的时候必须要写上 包名+类名
例如, createQuery("from org.hibernate.User")
-->
<hibernate-mapping
package="org.hibernate.entity">
<!-- 类名,数据库表名
class 映射某一个对象
一个映射文件可以映射多个对象。但一般情况下,一个映射文件映射一个对象。
name 指定要要映射的对象
table 对象对应的表,如果没有指定表名,默认与对象名称一样。
-->
<class name="User" table="user">
<!-- 主键映射 -->
<id name="id">
<!--
主键的生成策略
native 自增长(会根据底层数据库自增长的方式选择identity或sequence)(oracle使用sequence)
incremental 自增长(会有并发访问的问题,一般在服务器集群环境下使用会存在问题)
identity 自增长(mysql,db2)
swquence 自增长(序列),oracle中自增长是以序列方法实现
assigned 自动主键生成策略为手动指定主键的值
uuid 指定uuid随机生成的唯一值(String值)
foreign (外键的方式,one-to-one)
-->
<generator class="native"/>
</id>
<!-- 普通字段映射
name 是实体类的的成员变量名字
column 是对应的数据库表中的列名,如果不写默认与对象的属性一致
type 指定表的字段的数据类型(可以不写),如果指定挥匹配属性的类型(指定java类型-》必须写全名,指定hibernate类型—》直接写类型名,并且全为小写)
例如 type="java.util.String" type="string"
type="java.util.Date" type="date"
length 指定字符类型的长度,默认为255
列名字不能是关键字,但可以通过 加上反引号 就可以了
例如 <property name="desc" column="`desc`" type=""></property>
-->
<property name="name" column="name"></property>
<property name="birthday" column="birthday" type=""></property>
</class>
</hibernate-mapping>
PS:
①主键生长策略
②java类型与hibernate类型的比较