Hibernate相关小知识点
2014-03-19 22:35
337 查看
Hibernate相关小知识点
1、Hibernate框架主键生成方式
这里需要选择主键生成方式,主要有以下几种:
1) assigned:通过程序添加。
2) sequence:通过Oracle的序列生成主键值
3) native:通过数据库表中自带的关键字生成主键值,例如:MySQL,SQLServer,DB2,HSQL等
4) increment:自增长,通过程序实现自增长功能。
5) UUID:生成一个32的位随机值作为主键。
具体如下:
1)assigned:
由应用程序负责生成主键标识符,往往使用在数据库中没有代理主键,使用的主键与业务相关的情况,如:<id name="id" column="id" type=" java.lang.Integer">
<generator class="assigned"/>
</id>
这种主键的生成方式不建议使用,在数据库表设计时就应该使用代理主键(surrogate key),不应使用自然主键(natural key具有业务含义),在没有指定<generator>标签时,默认就是assigned主键的生成方式,在插入数据的时候主键由用户自己添加,hibernate也不管
2)sequence:
在ORACLE等数据库中使用sequence生成主键。sequence的特点是于数据库的相关性
a) 先在数据库中建立好序列:CREATE SEQUENCE news_seq;
b) 修改配置文件
<id name="id" type="java.lang.Integer">
<column name="ID" precision="8" scale="0" />
<!--
主键生成方式
-->
<generator class="sequence">
<param name="sequence">news_seq</param>
</generator>
</id>
3 )native:
由hibernate根据不同的数据库方言,自动选择不同的主键生成方式,native的优点是与底层性无关,便于不同数据库之间的移植,由hibernate根据不同数据库选择主键的生成方式
4)increment:
当向数据库中插入新的纪录时,主键会自动增长1。increment主键生成方式的特点是与底层数据库无关性,大部分数据库如 Mysql,MSSQL 和ORACLE等都支持increament生成方式。increment方式的不足之处是只能有一个hibernate进程访问数据库,若是多个线程并发对数据库表进行写操作时,可能出现相同的主键值,发生主键重复的冲突,因此多线程并发操作时,不应该使用此方法
5)uuid.hex:
采用基于128位的算法生成唯一值,并编制成32位长度的唯一字符串作为主键值,uuid.hex的优点是支持大部分数据库,缺点就是要占用较大的存储空间
2、Hibernate中提供了三种查询方式:
1) Session的查询:按主键查询查询,方法为get或load
2) Query的查询:使用HQL语句或SQL语句完成查询
3) Criteria的查询:通过方法和类中属性的关系,来设置查询条件,完成查询。(不常用)
3、Session中get和load方法的区别?
1) 如果没有查询到数据,get会返回null,而load则直接提示错误。
2) 使用load查询时,可能会出现以下错误,因为load方式使用的是懒汉式加载方法。执行load方法时,不立刻查询数据库。当用到查询出的对象的属性时,才加载数据。
使用load时会出现以下这种错误:
org.hibernate.LazyInitializationException: could not initialize proxy - no Session
解决这个异常的方法:
1) 不关连接
2) 不用load,就使用get就可以了。
4、Session操作过程中的pojo对象存在三种状态:
1) 瞬时态:该对象在数据库中没有对应的数据
2) 持久态:数据库中存在该对象对应的数据,同时操作该对象的Session也存在。
3) 游离态:数据库中包含该对象对应的数据,但操作此对象的Session已经不存在或被关闭了。
三种状态之间的转换:
瞬时 à 持久:save(),saveOrUpdate()
持久 à 瞬时:delete()
持久 à 游离:close()
游离 à 持久:update(),saveOrUpdate()
针对持久态对象,Hibernate还存在以下两个特点:
1) 持久态对象,在同一Session中只存在同一个。
a) 如果连接不关闭,多次查询同一条数据,只返回同一个对象,也就是只查询一次数据库。
b) 此功能也被称为一级缓存,但实际开发中实用性很低。
2) 修改持久态对象的属性,可以自动同步到数据库对应的数据中。
a) 当修改了一个持久态对象的属性,而且提交了事务,则数据库自动调用更新操作,也一起修改。
b) 当登陆后,要求将当前系统时间,作为最后登陆时间保存到数据库中时,可以使用。
5、简单的几个HQL语句
DELETEFROM News AS n WHERE n.id = ?
UPDATE News AS n SET n.title = ?,n.content= ? WHERE n.id = ?"
SELECT n.id AS id,n.titleAS title FROM News AS n
FROM Person ad p innerjoin p.myEvent e with p.id=e.id
6、hibernate集合映射inverse和cascade
<!--在Province表中存在一个名称为cities的Set集合-->
<setname="cities"inverse="true">
<!--关联外键是PROVINCE_ID-->
<key>
<columnname="PROVINCE_ID"precision="8"scale="0"/>
</key>
<!--表示当前类(Province)与City类存在一对多关系-->
<one-to-manyclass="org.liky.primary.pojo.City"/>
</set>
Inverse=”true”表示:关联关系反转,也就是关联关系由对方进行维护。关联关系在这里指的是外键字段province_id,该字段是city表的,也就是说修改city表,才可以修改这个字段,也就可以说city表维护着关联关系。对于Province来说,对方就是city,也就是说关联关系由对方(city)来维护。
cascade指的是Hibernate中配置的级联操作。
<set name="courses"table="USER_COURSE" cascade="all" schema="SUNXUN">
配置上这个以后,当用户选择课程时,不光处理中间表,同时对课程也进行一样的操作
7、一级缓存和二级缓存
在之前,使用Session的get或load查询同一对象时,存在一级缓存,但由于连接需要关闭,而且需求一般不会有某一个用户反复查询同一数据,因此使用性不强,基本用不到。
而Hibernate还提供了SessionFactory级别的二级缓存,这个缓存默认并没有打开,需要手工通过配置打开,而且默认也只支持按主键查询功能。
为了解决查询多条数据的缓存问题,Hibernate还提供了Query查询缓存。
二级缓存功能的实现并不是由Hibernate自己独立完成的,需要依赖于一些第三方数据插件来完成,结合的最好的插件是ehcache,除了这个缓存插件还支持oscache
使用缓存的步骤:
1)在hibernate.cfg.xml中加入以下属性配置
a) 设置缓存支持类: property 文本框中写cache.provider_class
value 文本框中写org.hibernate.cache.EhCacheProvider
b) 打开二级缓存功能: property 文本框中写cache.use_second_level_cache
value 文本框中写true
c) 使用Query查询缓存:property 文本框中写cache.use_query_cache
value 文本框中写true
2)在需要进行缓存的pojo的映射文件中加入以下配置
<class name="org.liky.pojo.News" table="NEWS" schema="PP">
<cache usage="read-only"/>
a) 这里的read-only表示缓存的类型,分为以下四种:
i. Read-only:只读缓存,数据不允许进行修改操作,如果修改,则直接报错
ii. Read-write:可读写缓存,数据允许修改,当数据库数据修改时,缓存立刻重新生成。
iii. Nonstrict-read-write:不严格的可读写缓存,数据允许修改,但数据库改变后,缓存不变,而是在一定时间后再与数据库同步。
iv. Transactional:支持事务的缓存,但现在不用了,合并到read-write中了。
3)需要将缓存核心配置文件加入到项目的src目录下。
<ehcache>
<!--
硬盘保存缓存数据的临时目录.
-->
<diskStore path="java.io.tmpdir"/>
<!--
maxInMemory - 限制内存中允许保存的对象最大数量.
eternal - 缓存数据是否永久保存,一直不销毁,建议false
timeToIdleSeconds - 空闲释放时间.
timeToLiveSeconds - 缓存的生命时间,配合不严格可读写使用的.
overflowToDisk - 如果数据量过大,是否将溢出数据保存到硬盘上.
-->
<defaultCache
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="300"
overflowToDisk="true"
/>
</ehcache>
现在已经完成了二级缓存的配置,支持按主键查询的缓存功能。
测试时,会提示错误,缺少支持jar包,这里需要找到一个commons-logging.jar支持包。
这种缺少包的错误,可以根据缺少的类明,在 http://www.findjar.com 中查找对应的支持包,并下载。
如果想使用Query查询缓存,还需要在编写DAO时,设置Query对象的属性,允许使用该功能。
public List<News> findAll(int pageNo,int pageSize, String keyword,
String column) throws Exception {
String hql = "FROM NewsAS n WHERE n." + column +" LIKE ?";
Query query = HibernateSessionFactory.getSession().createQuery(hql);
query.setCacheable(true);
query.setString(0, "%" + keyword +"%");
query.setFirstResult((pageNo - 1) * pageSize);
query.setMaxResults(pageSize);
return query.list();
}
8、Hibernate提高性能的方法有哪些?
1)使用缓存
2)使用懒汉式
3)SQL语句
4)Fetch=”select”
Oracle数据库提高性能的方法有哪些?
1)创建Index索引
2)创建View视图
3)SQL语句内大写
4)比较时尽量使用>=和<=,而不是>和<
5)日期类型不要直接比较,可以转换成long类型进行比较。
1、Hibernate框架主键生成方式
这里需要选择主键生成方式,主要有以下几种:
1) assigned:通过程序添加。
2) sequence:通过Oracle的序列生成主键值
3) native:通过数据库表中自带的关键字生成主键值,例如:MySQL,SQLServer,DB2,HSQL等
4) increment:自增长,通过程序实现自增长功能。
5) UUID:生成一个32的位随机值作为主键。
具体如下:
1)assigned:
由应用程序负责生成主键标识符,往往使用在数据库中没有代理主键,使用的主键与业务相关的情况,如:<id name="id" column="id" type=" java.lang.Integer">
<generator class="assigned"/>
</id>
这种主键的生成方式不建议使用,在数据库表设计时就应该使用代理主键(surrogate key),不应使用自然主键(natural key具有业务含义),在没有指定<generator>标签时,默认就是assigned主键的生成方式,在插入数据的时候主键由用户自己添加,hibernate也不管
2)sequence:
在ORACLE等数据库中使用sequence生成主键。sequence的特点是于数据库的相关性
a) 先在数据库中建立好序列:CREATE SEQUENCE news_seq;
b) 修改配置文件
<id name="id" type="java.lang.Integer">
<column name="ID" precision="8" scale="0" />
<!--
主键生成方式
-->
<generator class="sequence">
<param name="sequence">news_seq</param>
</generator>
</id>
3 )native:
由hibernate根据不同的数据库方言,自动选择不同的主键生成方式,native的优点是与底层性无关,便于不同数据库之间的移植,由hibernate根据不同数据库选择主键的生成方式
4)increment:
当向数据库中插入新的纪录时,主键会自动增长1。increment主键生成方式的特点是与底层数据库无关性,大部分数据库如 Mysql,MSSQL 和ORACLE等都支持increament生成方式。increment方式的不足之处是只能有一个hibernate进程访问数据库,若是多个线程并发对数据库表进行写操作时,可能出现相同的主键值,发生主键重复的冲突,因此多线程并发操作时,不应该使用此方法
5)uuid.hex:
采用基于128位的算法生成唯一值,并编制成32位长度的唯一字符串作为主键值,uuid.hex的优点是支持大部分数据库,缺点就是要占用较大的存储空间
2、Hibernate中提供了三种查询方式:
1) Session的查询:按主键查询查询,方法为get或load
2) Query的查询:使用HQL语句或SQL语句完成查询
3) Criteria的查询:通过方法和类中属性的关系,来设置查询条件,完成查询。(不常用)
3、Session中get和load方法的区别?
1) 如果没有查询到数据,get会返回null,而load则直接提示错误。
2) 使用load查询时,可能会出现以下错误,因为load方式使用的是懒汉式加载方法。执行load方法时,不立刻查询数据库。当用到查询出的对象的属性时,才加载数据。
使用load时会出现以下这种错误:
org.hibernate.LazyInitializationException: could not initialize proxy - no Session
解决这个异常的方法:
1) 不关连接
2) 不用load,就使用get就可以了。
4、Session操作过程中的pojo对象存在三种状态:
1) 瞬时态:该对象在数据库中没有对应的数据
2) 持久态:数据库中存在该对象对应的数据,同时操作该对象的Session也存在。
3) 游离态:数据库中包含该对象对应的数据,但操作此对象的Session已经不存在或被关闭了。
三种状态之间的转换:
瞬时 à 持久:save(),saveOrUpdate()
持久 à 瞬时:delete()
持久 à 游离:close()
游离 à 持久:update(),saveOrUpdate()
针对持久态对象,Hibernate还存在以下两个特点:
1) 持久态对象,在同一Session中只存在同一个。
a) 如果连接不关闭,多次查询同一条数据,只返回同一个对象,也就是只查询一次数据库。
b) 此功能也被称为一级缓存,但实际开发中实用性很低。
2) 修改持久态对象的属性,可以自动同步到数据库对应的数据中。
a) 当修改了一个持久态对象的属性,而且提交了事务,则数据库自动调用更新操作,也一起修改。
b) 当登陆后,要求将当前系统时间,作为最后登陆时间保存到数据库中时,可以使用。
5、简单的几个HQL语句
DELETEFROM News AS n WHERE n.id = ?
UPDATE News AS n SET n.title = ?,n.content= ? WHERE n.id = ?"
SELECT n.id AS id,n.titleAS title FROM News AS n
FROM Person ad p innerjoin p.myEvent e with p.id=e.id
6、hibernate集合映射inverse和cascade
<!--在Province表中存在一个名称为cities的Set集合-->
<setname="cities"inverse="true">
<!--关联外键是PROVINCE_ID-->
<key>
<columnname="PROVINCE_ID"precision="8"scale="0"/>
</key>
<!--表示当前类(Province)与City类存在一对多关系-->
<one-to-manyclass="org.liky.primary.pojo.City"/>
</set>
Inverse=”true”表示:关联关系反转,也就是关联关系由对方进行维护。关联关系在这里指的是外键字段province_id,该字段是city表的,也就是说修改city表,才可以修改这个字段,也就可以说city表维护着关联关系。对于Province来说,对方就是city,也就是说关联关系由对方(city)来维护。
cascade指的是Hibernate中配置的级联操作。
<set name="courses"table="USER_COURSE" cascade="all" schema="SUNXUN">
配置上这个以后,当用户选择课程时,不光处理中间表,同时对课程也进行一样的操作
7、一级缓存和二级缓存
在之前,使用Session的get或load查询同一对象时,存在一级缓存,但由于连接需要关闭,而且需求一般不会有某一个用户反复查询同一数据,因此使用性不强,基本用不到。
而Hibernate还提供了SessionFactory级别的二级缓存,这个缓存默认并没有打开,需要手工通过配置打开,而且默认也只支持按主键查询功能。
为了解决查询多条数据的缓存问题,Hibernate还提供了Query查询缓存。
二级缓存功能的实现并不是由Hibernate自己独立完成的,需要依赖于一些第三方数据插件来完成,结合的最好的插件是ehcache,除了这个缓存插件还支持oscache
使用缓存的步骤:
1)在hibernate.cfg.xml中加入以下属性配置
a) 设置缓存支持类: property 文本框中写cache.provider_class
value 文本框中写org.hibernate.cache.EhCacheProvider
b) 打开二级缓存功能: property 文本框中写cache.use_second_level_cache
value 文本框中写true
c) 使用Query查询缓存:property 文本框中写cache.use_query_cache
value 文本框中写true
2)在需要进行缓存的pojo的映射文件中加入以下配置
<class name="org.liky.pojo.News" table="NEWS" schema="PP">
<cache usage="read-only"/>
a) 这里的read-only表示缓存的类型,分为以下四种:
i. Read-only:只读缓存,数据不允许进行修改操作,如果修改,则直接报错
ii. Read-write:可读写缓存,数据允许修改,当数据库数据修改时,缓存立刻重新生成。
iii. Nonstrict-read-write:不严格的可读写缓存,数据允许修改,但数据库改变后,缓存不变,而是在一定时间后再与数据库同步。
iv. Transactional:支持事务的缓存,但现在不用了,合并到read-write中了。
3)需要将缓存核心配置文件加入到项目的src目录下。
<ehcache>
<!--
硬盘保存缓存数据的临时目录.
-->
<diskStore path="java.io.tmpdir"/>
<!--
maxInMemory - 限制内存中允许保存的对象最大数量.
eternal - 缓存数据是否永久保存,一直不销毁,建议false
timeToIdleSeconds - 空闲释放时间.
timeToLiveSeconds - 缓存的生命时间,配合不严格可读写使用的.
overflowToDisk - 如果数据量过大,是否将溢出数据保存到硬盘上.
-->
<defaultCache
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="300"
overflowToDisk="true"
/>
</ehcache>
现在已经完成了二级缓存的配置,支持按主键查询的缓存功能。
测试时,会提示错误,缺少支持jar包,这里需要找到一个commons-logging.jar支持包。
这种缺少包的错误,可以根据缺少的类明,在 http://www.findjar.com 中查找对应的支持包,并下载。
如果想使用Query查询缓存,还需要在编写DAO时,设置Query对象的属性,允许使用该功能。
public List<News> findAll(int pageNo,int pageSize, String keyword,
String column) throws Exception {
String hql = "FROM NewsAS n WHERE n." + column +" LIKE ?";
Query query = HibernateSessionFactory.getSession().createQuery(hql);
query.setCacheable(true);
query.setString(0, "%" + keyword +"%");
query.setFirstResult((pageNo - 1) * pageSize);
query.setMaxResults(pageSize);
return query.list();
}
8、Hibernate提高性能的方法有哪些?
1)使用缓存
2)使用懒汉式
3)SQL语句
4)Fetch=”select”
Oracle数据库提高性能的方法有哪些?
1)创建Index索引
2)创建View视图
3)SQL语句内大写
4)比较时尽量使用>=和<=,而不是>和<
5)日期类型不要直接比较,可以转换成long类型进行比较。
相关文章推荐
- Hibernate框架的相关知识点及面试题
- Hibernate学习笔记之相关知识点整理
- hibernate框架的核心对象和相关知识点
- hibernate框架的核心对象和相关知识点
- Hibernate总结(三)——相关知识点
- Hibernate相关知识点总结
- fedora 系统、服务启动相关知识点总结
- ios相关知识点积累(一)
- 由static关键字引发的知识点学习和在类中的使用相关注意事项
- SpringMVC注解配置Swagger2步骤及相关知识点
- hibernate的相关知识
- 项目生命周期相关知识点理解
- hibernate 相关链接
- Java同步、异步相关知识点
- storyboard相关知识点-零散记录
- 信息论与编码相关知识点
- Hibernate知识点总结大全
- hibernate对查询的几个知识点
- 一道练习题引申出来的知识点(六) ADO.NET常用命令 以及相关概念
- WKWebview相关知识点记录