- 浏览: 725162 次
- 性别:
- 来自: 天津
文章分类
- 全部博客 (442)
- 中间件 (20)
- hibernate (13)
- spring (20)
- 数据库 (78)
- struts (8)
- ibatis (4)
- 前端 (61)
- linux,windows (21)
- it大环境 (32)
- IDE工具 (36)
- 感悟 (6)
- java基础 (40)
- 经典面试题 (10)
- exception总结 (14)
- 软件设计 (8)
- 工具类应用及新技术 (48)
- php (2)
- 微信 (1)
- 设计模式 (2)
- 重构 (3)
- 管理 (2)
- 工作笔记 (1)
- jmx (1)
- 算法 (4)
- 多线程同步 (2)
- 代码管理工具 (5)
- 代码检测及测试 (2)
- 缓存服务 (1)
- SOA及ROA (5)
- groovy (1)
- 网络编程 (2)
- 大数据 (6)
最新评论
-
love398146779:
我当然不能全写上面了,这只是其中一部分https连接。
java 建立 https连接 -
yuenkin:
大哥,这是双向认证吗?
java 建立 https连接 -
issu:
例如以下代码能遍历字符串"Tom:M ...
<c:forTokens>标签delims截取字符 -
love398146779:
2*3*5=30,是30个以上的请求才拒绝呀。
tomcat的maxThreads、acceptCount(最大线程数、最大排队数) -
love398146779:
2台跟1台一样的效果。
zookeeper与activemq最新存储replicatedLevelDB整合
hibernate建立数据的的映射是完全可以通过eclips自动导入实现的,不过,基础还是要学的。知其解决方法,也要知其理才行~!
(~ o ~)~zZ 以下是收获:
---------------------------------------------------------------------------------------------
xml形式的实体化映射:
*.hbm.xml
<hibernate-mapping>
<class name="实体化类名" table="表名">
<id> 定义一个单主键,一个字段 属性作为实体类的主键
<composite-id> 复合主键,多个字段 一组属性作为主键的定义方式 (主键类,实现序列化接口)
<property> 字段---》属性的映射
</class>
</hibernate-mapping>
练习:
emp-->dept 多对一 实现级联,添加,删除操作
首先写好emp和dept实体化类 emp为主表实体化类,所以emp有dept类的对象作为属性
接着写映射文件.hbm.xml
emp.hbm.xml如下:
- <?xml version="1.0" encoding="utf-8"?>
- <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
- "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
- <!--
- Mapping file autogenerated by MyEclipse Persistence Tools
- -->
- <hibernate-mapping package="cn.com.vo">
- <class name="Emp" table="emp">
- <id name="empno" column="empno">
- <generator class="increment"></generator>
- </id>
- <property name="ENAME" column="ENAME"></property>
- <property name="JOB" column="JOB"></property>
- <property name="MGR" column="MGR"></property>
- <property name="HIREDATE" column="HIREDATE"></property>
- <property name="SAL" column="SAL"></property>
- <property name="COMM" column="COMM"></property>
- <many-to-one name="dept" column="deptno" outer-join="true"
- cascade="all">
- </many-to-one>
- </class>
- </hibernate-mapping>
dept.hbm.xml 如下:
- <?xml version="1.0" encoding="utf-8"?>
- <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
- "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
- <!--
- Mapping file autogenerated by MyEclipse Persistence Tools
- -->
- <hibernate-mapping package="cn.com.vo">
- <class name="Dept" table="dept">
- <id name="DEPTNO" column="DEPTNO" >
- <generator class="increment"></generator>
- </id>
- <property name="DNAME" column="DNAME"></property>
- <property name="LOC" column="LOC"></property>
- </class>
- </hibernate-mapping>
注意了:
在写pojo类时,*.hbm.xml写完之后,
还要将hibernate.cfg.xml之后加入
<mapping resource="cn/com/vo/Emp.hbm.xml" />
<mapping resource="cn/com/vo/Dept.hbm.xml" />类似这样的地址,实现pojo类在hibernate中的关系映射
(自动通过数据库导入的pojo类,eclips会自动将其地址加在hibernate.cfg.xml中
hbm2ddl.auto 这个在hibernate.cfg.xml中若是设置为true,则会根据映射关系在数据库中建立相应的table,假如数据有了~就不会建了。
cascade 有以下取值:
all : 所有操作都传递到相关联的对象
save-update 保存和更新传递到相关联的对象
delete 删除操作传递到相关联的对象
delete-orphan : 所有操作都传递到相关联的对象 并删除不再与父对象关联的对象。
-----------------------------------------------------------------------------------------------------------------------------------------
级联删除这要找到数据库里的对象
用Emp emp=(Emp)session.get(Emp.class,7935");
session.delete(emp);
这样会把emp表和相关联的dept表中的数据都删掉
-----------------------------------------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------------------------------------
从表---主表, 一对多的关系 (Onetomany)
hibernate 之中的集合有 list,map,set,bag 在一对多中经常用的时set--原理:去空值,去重复 (难怪呢)
类之间用set实现1 对n
配置上,
<one-to-many>
<set 的属性有 :>
name 属性名
table 基于关联表的一对多关系
lazy="true/false"是否使用延迟加载技术——不错!true,没有用到关联表,则不会把关联表的信息搜出来,加载到缓存中,反之则会严重影响其性能~ 平时就要检查设置为true hibernate 3.0以后基本默认都是true
inverse(true/false) 关联关系由哪一方来维护 true--会根据从表实体类维护 false--会根据主表实体类维护
out-join
fetch
orderby 对关联表排序
---
<key column="设置从表的外键字段'></key>
<one-to-many class="从表实体类"/>
dept和emp是 1对多的关系
1 将dept实体类中加入emps 的set集,然后get/set方法
只需要将dept.hbm.xml改下即可:
- <?xml version="1.0" encoding="utf-8"?>
- <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
- "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
- <!--
- Mapping file autogenerated by MyEclipse Persistence Tools
- -->
- <hibernate-mapping package="cn.com.csuinfosoft.vo">
- <class name="Dept" table="dept">
- <id name="deptno" column="deptno">
- <generator class="increment"></generator>
- </id>
- <property name="dname" column="dname"></property>
- <property name="loc" column="loc"></property>
- <set name="emps" lazy="true" >
- <key column="deptno"></key>
- <one-to-many class="Emp"/>
- </set>
- </class>
- </hibernate-mapping>
----------------------------------------------------------------------------------------------------------------------------------------------
<many-to-many> 多对多
例子:学生表 关联表 老师表
<set >的属性
name
table 中间表
<key column="中间表的与当前表所映射的外键字段">
<many-to-many culumn="中间表与关系的另一个表所建立的关联字段">
这里给出一个写在一起的many-to-many.hbm.xml
- <?xml version="1.0" encoding="utf-8"?>
- <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
- "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
- <hibernate-mapping package="cn.com.csuinfosoft.vo">
- <class name="Person" table="Person">
- <id name="personId" column="person_Id"></id>
- <property name="name" column="name"></property>
- <property name="age" column="age"></property>
- <set name="address" table="Person_Address">
- <key column="pa_personId"></key>
- <many-to-many class="Address" column="pa_addressId"></many-to-many>
- </set>
- </class>
- <class name="Address" table="Address">
- <id name="addressId" column="address_Id"></id>
- <property name="addressInfo" column="address_Info"></property>
- </class>
- </hibernate-mapping>
9.28 Hibernate 特殊表的关联 和 继承在hibernate 实现持久化的作用
1对1(外主)
1对多(中间表的)
继承,通过继承实现hibernate数据化的持久性操作
1对1关系
第一种情况:a表引用b表的主键做外键具有唯一性约束
一个人对应一个地址
person address
-------------------
p_id a_id
p_name a_name
a_id 外键+了唯一性约束
<many-to-one>
将many改成unique="true"
这个还是比较容易理解的。
第二中情况:a表引用b表的主键,在a表中既做主键,也做外键
person address
----------------
p_id a_id( 它是引用p_id的外键)
p_name a_name
<one-to-one name="person" constrained="true"></one-to-one>只对主键进行描述
<one-to-one name="关联属性"> 在hibernate机制上描述两个实体1对1的关系
在操作时基于两个标的主键进行关联操作
基于该关系生成外键约束,或在某一键上加上某一属性
将contraonted="true"基于关系生成外键约束
column 描述关联字段(外键1对1关系,需要从主表这边描述的时候)
在它的<id 属性上>
<genertor ,,
</id>
- <?xml version="1.0" encoding="utf-8"?>
- <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
- "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
- <hibernate-mapping package="cn.com.csuinfosoft.oto">
- <class name="Person" table="o_person">
- <id name="pid" column="p_id">
- <generator class="increment"></generator>
- </id>
- <property name="pname"></property>
- <one-to-one name="address"></one-to-one>
- </class>
- <class name="Address" table="o_address">
- <id name="aid" column="a_id">
- <generator class="foreign">
- <param name="property">person</param>
- </generator>
- </id>
- <property name="info"></property>
- <one-to-one name="person" constrained="true"></one-to-one>
- </class>
- </hibernate-mapping>
继承 在 hibernate中的作用
单表继承
在一个表中,通过一个标识来区分不同的数据类型,如type字段
用户有:学生,老师的例子不错啊
type属性
用
<id...>
<discrimininator column="type类型的字段名 user_type">
</discrimininator>
<property...>
<subclass name="子类的名称" discriminator-value="标识字段为何值用该子类">
<property name="teacherPhoto" column="teacher_photo"></property>
</subclass>
继承在hibernate中的强势应用。这是单表的继承。
(类之间要有继承user被student 和teacher继承,配置如上)
- <?xml version="1.0" encoding="utf-8"?>
- <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
- "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
- <!--
- Mapping file autogenerated by MyEclipse Persistence Tools
- -->
- <hibernate-mapping package="cn.com.csuinfosoft.sub">
- <class name="User" table="sub_user_info">
- <id name="userId" column="user_id">
- <generator class="increment"></generator>
- </id>
- <discriminator column="user_type"></discriminator>
- <property name="userName" column="user_name"></property>
- <property name="userAge" column="user_Age"></property>
- <subclass name="Teacher" discriminator-value="1">
- <property name="teacherPhoto" column="teacher_photo"></property>
- </subclass>
- <subclass name="Student" discriminator-value="2">
- <property name="studentPhoto" column="student_photo"></property>
- </subclass>
- </class>
- </hibernate-mapping>
关联表的继承。
用户表是双方都有的信息
学生,老师是自己独有的基础信息表
用户
|
|
----------------------------
学生 老师
配置中用<joined-subclass>---继承关联
<joined-subclass name="类名" table="表名">
<key clumn="关联外键字段"/>
<property name="" clumn=""/>
<many-to-one>..</...>
</joined-subclass>
- <?xml version="1.0" encoding="utf-8"?>
- <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
- "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
- <!--
- Mapping file autogenerated by MyEclipse Persistence Tools
- -->
- <hibernate-mapping package="cn.com.csuinfosoft.joinsub">
- <class name="User" table="j_user">
- <id name="userId" column="user_id">
- <generator class="increment"></generator>
- </id>
- <property name="userName" column="user_name"></property>
- <property name="userPassword" column="user_Password"></property>
- <joined-subclass name="Student">
- <key column="student_Id"></key>
- <property name="studentPhoto"></property>
- </joined-subclass>
- <joined-subclass name="Teacher" ><!-- table="t_teacher" -->
- <key column="teacher_Id"></key>
- <property name="teacherPhoto"></property>
- </joined-subclass>
- </class>
- </hibernate-mapping>
在上面的特殊表关联中,要体会其原理,还有对 unique="true"的理解。。这个理解真的挺重要的。
-------------------------------------------------
会用hibernate做项目和你懂hibernate完全是两个概念。。 是的,知道原理,写起代码不再是机械式的填充。
--------------------------------------------------------------------------------------------------------------------------------
hibernate 持久化对象的生命周期
session作为持久化对象 有3个状态:
1 瞬时状态--由new关键字创建生成的对象状态,这种对象只会在内存中存在
状态没有和数据库同步
session中没有持久该对象的引用。(数据对象有可能丢失)
2 持久状态--对象是由session创建生成(如session.save() session.update())
session持有该对象引用后,将其状态也入到数据库中
3 离线状态--原本为持久状态的对象,因session.close() 即 session资源的关闭或者session清空实体对象的 引用,导致该对象不再由session管理,称作离线状态
new(新生)----get/load()--》持久状态 session.load是按主键检索数据,创建持有对象,以及持久对象的代理对象,返回的是代理对象。
|
|
|
瞬时状态 ----save(),saveOrUpdate() ----》持久状态 ---evict()清除指定类型id clear()清除所有 close()-----》离线状态
离线对象---update(),saveOrUpdate(),lock()-->持久对象-----delete()--》瞬时状态
hibernate每一个类都要配置一个id,表示唯一性。那么session的表示id也只有一个,因为唯一性的存在,反之,数据的维护变的相当混乱
---------------------------------------------------------------------------------
Hibernate 检索语言 Hql
"from 类名 where 属性名=? ";将查询的结果封装成类名所对应的类实例对象
hql的关联查询:
select a.dept.deptno from Emp a 会根据实体类之间的关联,自动生成多表关联的sql
from Emp a where a.dept.dname=? hql果然强大~!
Query query=session.createQuery("from Emp a where a.dept.dname=?");
query.setString(0,"教育部");
List<Emp> result=query.list();
在hql中一旦出现select子句,它肯能查询出的结果不按照from的类名封装对象,而是将结果放在Object[]中
Query query=session.createQuery("select a.dept.dname.a.sal from Emp a where a.dept.dname=?");
query.setString(0,"教育部");
List<Object[]> result=query.list();
如果这样你用着还不是很爽,可以利用hibernate实现有参的构造函数
Query query=session.createQuery("select new Emp(a.dept.dname.a.sal) from Emp a where a.dept.dname=?");//前提Emp有这样一个构造函数。
query.setString(0,"教育部");
List<Emp> result=query.list();
------------------------hibernate的强大在于你可以根据自己的需求设计出合理的方式完成检索操作~赞一个!
hql函数的使用:
聚合函数:avg() sum() max() count()
查询关键字:distinct
集合操作函数:size(),minelement(),minindex(),maxindex()
Orderby 子句 group by 子句
例子:"from Dept a where size(a.emps)>=2";
---------------------------------------------------
连接查询
inner join 基于关联属性经行操作 inner join fetch
Query query=session.createQuery("from Dept dept inner join fetch dept.emps");
query.list();
Left outer join left outer join fecth
Right outer hoin
Fetch只对inner join 和Left join 有效,Right outer join返回的是数组
-----------------------------
Query query=session.getNamedQuery("leftjoin");//这个是在xml的配置文件中写的cdata..这个问题解决就好了
query.list();
- <?xml version="1.0" encoding="utf-8"?>
- <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
- "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
- <!--
- Mapping file autogenerated by MyEclipse Persistence Tools
- -->
- <hibernate-mapping package="cn.com.csuinfosoft.vo">
- <class name="Emp" table="emp">
- <id name="empno" column="empno">
- <generator class="increment"></generator>
- </id>
- <property name="ename" column="ename"></property>
- <property name="job" column="job"></property>
- <property name="mgr" column="mgr"></property>
- <property name="hireDate" column="hiredate"></property>
- <property name="sal" column="sal"></property>
- <property name="comm" column="comm"></property>
- <many-to-one name="dept" column="deptno" outer-join="true" cascade="all">
- </many-to-one>
- </class>
- <query name="leftjoin">
- <!--[CDATA[
- from Emp emp left join fetch emp.dept
- ]]-->
- </query>
- </hibernate-mapping>
---------------------------------------------------------------------------------------------------------------
补充的知识:
标准查询
SQL查询
附:拦截器
验证器
锁策略--乐观锁,悲观锁的操作实现
标准查询---面向对象技术//这个没有sql,或者hql语句灵活,也没他们可读性强。这种语言只能作为辅助
sql---------->对象的方法
Criteria cr=session.createCriteria(Emp.class);
cr.add(Expression.gt("sal",1000));//Expression是一个接口关于Criteria
List result=cr.list();
Emp emp=null;
for(int i=0;i<result.size();i++){
emp=(Emp)result.get(i);
}
标准查询是基于Critera.add(查询条件) 查询条件由Experssion生成对象,根据不同的条件方法调度,生成对应的查询条件 Experssion方法有很多(eq,gt,like等)
-------------------
SQl 查询
sql语句的通用性很差。不同的版本oracle会使用到不同的sql语句语法。容易出错。 了解下了
而HQL则无需考虑这些。
SQLQuery sqlQuery=session.createSQLQuery("select ename,job,sal from emp where deptno=?");
Query query=session.getNamedQuery("leftjoin");//这个是在xml的配置文件中写的cdata..
sqlQuery.setInteger(0,10);
List list=sqlQuery.list();
-----------------------
拦截器--设置在sessionFactory之上,对session的持久化操作就行拦截
EmptyInterceptor 是个抽象类,我们的类需要实现它。
加入方法用eclipse的 overwrite中找到对应的方法即可!!!
onDelete()
onLoad()
onSave()
这是继承EmptyInterceptor 的类例如MyInterceptor
那么在实现类中 加入
Configuration configuration = new Configuration().configure();
configuration.setInterceptor(new MyInterceptor())//这个是加入的。。!!!
SessionFactory sessionFactory = configuration.buildSessionFactory();
------------------------------------
验证器
验证接口--用于在数据的添加,修改时,在持久化操作之前,对数据有效性验证。
validator---validate() throws ValidationFailure
validate()可以终止原有的持久化操作。
-----------------------------------
锁策略
锁机制 ---在并发访问下,保护资源有序的被使用
乐观锁 悲观锁
Hibernate 锁策略
Hibernate 内部锁机制
LockMode.NONE 无锁机制
LockMode.WRITE hibernate 进行保存和更新时自动使用的锁机制。
LockMode.READ hibernate 读取纪录时的机制
悲观锁
整个数据处理过程中,将数据处于锁定
状态。悲观锁的实现,往往依靠数据库提供的锁机制
LockMode.UPGRADE
LockMode.UPGRADE_NOWAIT
//相当于SQL(for update 中的 wait 或者nowaite)
实现机制如下:
Criteria.setLockMode
Query.setLockMode(Strng指hql语句中实体类的别名,LockMode.UPGRADE);
例如:
Query query=session.createQuery("from Emp a");
Query.setLockMode(a,LockMode.UPGRADE_NOWAIT);
Emp emp=(Emp)session.load(Emp.class,1,LockMode.UPGRADE_NOWAIT);//悲观锁
session.lock (实例对象,LockMode.READ);
缺点:资源开销大,一般不用这种,通常推荐使用乐观锁机制
乐观锁
更加宽松的加锁机制,悲观锁对长事务而言,开销往往无法承受;避免死锁。
实现机制:
Hibernate在o/R中映射特殊字段<timestamp> 或者<version>
采用特殊字段来做判断,平时操作不等待,但是保存或者更新时会进行判断。
Version
Dirty
ALL
主要介绍 Version
官方推荐的乐观锁实现策略,广泛使用,具有经验可借鉴性
实现举例:在每一次进行读取操作时取出版本号,在进行更新时同时刷新版本号,更新时只能更新低版本的数据,从而完成锁策略。 Hibernate 的 Session 会在等待用户交互时 ,Session 断开数据库连接。在整个应用事务过程中, Hibernate 使用单例 Session 和单例类来实现。
使用方法:
<class name="UserVo" table="uservo" schema="SPRINGDEV" optimistic-lock="version">
< 主键 >
<version name="version" column="version" type="java.lang.Integer" />
同时数据库表中增加字段 version ,version无须设置,它会随着操作自动增加。
总结:在一般性的事务中,大可将锁机制抛开不用,这样不可否认增加了复杂性,你不得不面对不少的版本异常信息,只有在涉及关键业务如进行网上购物的付款等就必须进行加锁管理,当然推荐基于 version 的乐观锁管理。
-------------------------------------------------------------------------------------------------------------
hibernate 空值异常
字段 ---》属性(基本数据类型)(包装类型,字符,日期)
基本数据类型(int,double,char等)
优:性能好
缺点:不能接受空字段的值
包装类:如Double,String,Date,Integer(就是java.lang.*这种包装类)
优:能包装空值在内的所有有效数值
缺点:资源开销大
提示:如果数据封装不上pojo类,有可能就是数据类型选择的错误!
----------------------------------------------------------------------------
这样的错误:
<c:forEach var="dt" items="${requestScope.list}">
<tr>
<td>${dt.empno}</td>
<td>${dt.ename}</td>
<td>${dt.job}</td>
<td>${dt.sal}</td>
<td>${dt.dept.deptno}</td>//可以显示的,它在emp表中作为外键<many-to-one name="dept".. ><column
name="DEPTNO"/></many-to-one>
<td>${dt.dept.dname}</td>//这个不可以显示,它跟emp无任何关联。是dept独有的。会报session已经关闭。以下
有解决办法。
</tr>
</c:forEach>
session是线程不安全,不能被多个线程同时使用
web-线程->请求处理 一个请求可以对应一个session线程。
利用java.lang.ThreadLocal 会为每一个当前线程分配一个独立的存储空间
Map<key,value>会为这一个线程保存独有的线程信息
以下为代码:
--------------------------------------------------------
view plaincopy to clipboardprint?
package cn.com.csuinfosoft.hibernate;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class HibernateUtil {
private static SessionFactory sessionFactory = null;
private static ThreadLocal threadLocal = new ThreadLocal();
static {
try {
Configuration config = new Configuration().configure();
sessionFactory = config.buildSessionFactory();
} catch (Exception ex) {
ex.printStackTrace();
}
}
public static Session getSession() {
Session session = (Session)threadLocal.get();//获取当前线程对应的内存空间中,存储的对象
if(session == null) {
session = sessionFactory.openSession();
threadLocal.set(session);
}
return session;
}
public static void closeSession() {
Session session = (Session)threadLocal.get();
if(session != null) session.close();
threadLocal.set(null);
}
}
package cn.com.csuinfosoft.hibernate;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class HibernateUtil {
private static SessionFactory sessionFactory = null;
private static ThreadLocal threadLocal = new ThreadLocal();
static {
try {
Configuration config = new Configuration().configure();
sessionFactory = config.buildSessionFactory();
} catch (Exception ex) {
ex.printStackTrace();
}
}
public static Session getSession() {
Session session = (Session)threadLocal.get();//获取当前线程对应的内存空间中,存储的对象
if(session == null) {
session = sessionFactory.openSession();
threadLocal.set(session);
}
return session;
}
public static void closeSession() {
Session session = (Session)threadLocal.get();
if(session != null) session.close();
threadLocal.set(null);
}
}
//在实现类中通过 Session session=HibernateUtil.getSession()这样得到的session是在同一个请求中保持不变的
。
然后当我们需要在请求结束关闭这样个一session可以写filter文件:
-------------------------
view plaincopy to clipboardprint?
package cn.com.csuinfosoft.filter;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import cn.com.csuinfosoft.hibernate.HibernateUtil;
public class HibernateFilter implements Filter {
public void destroy() {
}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain filterChain) throws IOException, ServletException {
try {
System.out.println("============ Filter try ====== Thread:" +
Thread.currentThread().getName());
filterChain.doFilter(request, response);
} finally {
System.out.println("============ Filter finally ======Thread:" +
Thread.currentThread().getName());
HibernateUtil.closeSession(); //每次请求结束前关闭Session
}
}
public void init(FilterConfig filterConfig) throws ServletException {
}
}
package cn.com.csuinfosoft.filter;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import cn.com.csuinfosoft.hibernate.HibernateUtil;
public class HibernateFilter implements Filter {
public void destroy() {
}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain filterChain) throws IOException, ServletException {
try {
System.out.println("============ Filter try ====== Thread:" +
Thread.currentThread().getName());
filterChain.doFilter(request, response);
} finally {
System.out.println("============ Filter finally ======Thread:" +
Thread.currentThread().getName());
HibernateUtil.closeSession(); //每次请求结束前关闭Session
}
}
public void init(FilterConfig filterConfig) throws ServletException {
}
}
最后将这样一个filter配置在web.xml中,是相当容易的。
----------------------------
补充:SessionFactory可以在监听器控制下, 是要在程序卸载的时候关闭掉。
在过去所学的线程中Thread 中获得当前线程方法为currentThread()
hibernate的配置优化
<property name="jdbc.batch_size">30</property> 这个用于管理数据库批量处理的,如批量删除
<property name="jdbc.fetch_size">50</property> 在jdbc抓取数据时采用分批抓取,一次可以抓取50条
做一个简单 批量删除 实现,不是很难哦!
----------------------------------------------------------------------------------------------------------------
不懂得问题:
<class name="UserVo" table="uservo" schema="SPRINGDEV" optimistic-lock="version">
< 主键 >
<version name="version" column="version" type="java.lang.Integer" />
</class>
解释下schema="SPRINGDEV" 和optimistic-lock="version":
1)其中<class name="UserVo" table="uservo" schema="SPRINGDEV" optimistic-lock="version">中的schema="SPRINGDEV"表示数据库的用户名。如果当前链接数据库的用户名称不是SPRINGDEV的话,实际操作中还是会用SPRINGDEV这个用户来操作。这就会产生一系列问题。
2)optimistic-lock属性有如下可选取值:
? none 无乐观锁
? version 通过版本机制实现乐观锁
? dirty 通过检查发生变动过的
-------------------------------------------------------------------------------------------------------------------------
Hibernate 关闭sessionFactory :
关闭sessionFactory是应在服务器被关闭,程序被卸载时关闭,所以需要写一个sessionFactory特有的监听类,当服务器被关闭时,自动关闭sessionFactory.
写个监听类 实现ServletContextListener 在该类中关闭关闭sessionFactory ,以下就是:
- package cn.com.csuinfosoft.listener;
- import javax.servlet.ServletContextEvent;
- import javax.servlet.ServletContextListener;
- import cn.com.csuinfosoft.hibernate.HibernateUtil;
- public class HibernateListener implements ServletContextListener {
- public void contextDestroyed(ServletContextEvent arg0) {
- HibernateUtil.closeSessionFactory();
- }
- public void contextInitialized(ServletContextEvent arg0) {
- }
- }
将监听类配置在web.xml 中
<listener>
<listener-class>cn.com.csuinfosoft.listener.HibernateListener</listener-class>
</listener>
-------------------------------------------------------------------------------------
---------------------------------------------------------------以下转载的,一些关键字的注意,配合着学习:
重点学习 Hibernate fetch lazy cascade inverse 关键字
Hibernate最让人头大的就是对集合的加载形式。
书看了N次了,还是没有真正理解Hibernate。所以下午专门做了下测试,对配置文件的意思加深了认识。
假设有两个表,Photos(一) --- picture(多)Photo包含picture集合
结论1: HQL代码 > fetch(配置) > lazy (配置)
结论2: 默认 lazy="true"
结论3: fetch 和 lazy 主要是用来级联查询的, 而 cascade 和 inverse 主要是用来级联插入和修改的
fetch参数指定了关联对象抓取的方式是select查询还是join查询,select方式时先查询返回要查询的主体对象(列表),再根据关联外键id,每一个对象发一个select查询,获取关联的对象,形成n+1次查 询; 而join方式,主体对象和关联对象用一句外键关联的sql同时查询出来,不会形成多次查询。
如果你的关联对象是延迟加载的,它当然不会去查询关联对象。 另外,在hql查询中配置文件中设置的join方式是不起作用的(而在所有其他查询方式如get、criteria或再关联获取等等都是有效的),会使用select方式,除非你在hql中指定join fetch某个关联对象。fetch策略用于定义 get/load一个对象时,如何获取非lazy的对象/集合。 这些参数在Query中无效。
在某种特殊的场合下,fetch在hql中还是起作用的。
例如
现有message(回帖)-->topic(主贴)-->forum(版块) 的多级many-to-one结构:
第一级:message-->topic many-to-one配置lazy="false" fetch="join"
第二级:topic-->forum many-to-one配置lazy="false" fetch="join"
这时如果"from message",则第二级:topic-->forum中的fetch策略会起作用
查询抓取(默认的)在N+1查询的情况下是极其脆弱的,因此我们可能会要求在映射文档中定义使用连接抓取:
<set name="permissions"
fetch="join">
<key column="userId"/>
<one-to-many class="Permission"/>
</set
<many-to-one name="mother" class="Cat" fetch="join"/>
在映射文档中定义的抓取策略将会有产生以下影响:
通过get()或load()方法取得数据。
只有在关联之间进行导航时,才会隐式的取得数据(延迟抓取)。
条件查询
在映射文档中显式的声明 连接抓取做为抓取策略并不会影响到随后的HQL查询。
通常情况下,我们并不使用映射文档进行抓取策略的定制。更多的是,保持其默认值,然后在特定的事务中, 使用HQL的左连接抓取(left join fetch) 对其进行重载。这将通知 Hibernate在第一次查询中使用外部关联(outer join),直接得到其关联数据。 在条件查询 API中,应该调用 setFetchMode(FetchMode.JOIN)语句。
其实这并不能说明hql能够按照配置文件设置的join进行抓取,这时 第二级:topic-->forum 的抓取其实已经和hql没有关系了,因为前面已经产生了另一个select方式的抓取语句。
而是对象的关联获取,假如查询message时topic是设置为延迟加载的,那么在后面获取message.topic时,如topic.forum不延迟加载,那么topic-->forum会实现配置的join方式的抓取,这个显然和hql查询没有关系。
结论4: 如果你是用spring来帮你管理你的session, 并且是自动提交,延迟加载就等于没加载~_~(当然
除非你手动重新打开session然后手动Hibernate.initialize(set);然后关闭session.
结论5: cascade主要是简化了在代码中的级联更新和删除。
j结论6:老爸可以有多个孩子,一个孩子不能有多个老爸,而且老爸说的算, 孩子围着老爸转。
所以Photos老爸要有权力所以 cascade 这个关键子都是送给老爸的, 也就是级联更新,
老爸改姓了,儿子也得跟着改,呵呵。“不然,就没有零花钱咯”。
而Picture儿子整体挨骂,但是还是要维护父子之间良好的关系,对老爸百依百顺,所
以老爸就说,儿子,“关系,由你来维护(inverse="true") ,不然就不给零花钱。呵。”。
<set name="pictures" inverse="true" cascade="all">
<key>
<column name="photosid" not-null="true" />
</key>
<one-to-many class="girl.domain.Picture" />
</set>
测试代码:
Photos p = ps.getById(1);
Set<Picture> set = p.getPictures();
for(Picture pic : set){
System.out.println(pic.getId());
}
配置文件的一部分:
<set name="pictures" inverse="true" cascade="all" >
<key>
<column name="photosid" not-null="true" />
</key>
<one-to-many class="girl.domain.Picture" />
</set>
测试过程会对配置文件不断修改:并且从来不曾手动重新打开session
测试结构:
当配置条件为 lazy=true 一句查询 测试代码中没有调用getPicture() 正常
Hibernate: select photos0_.id as id0_0_, photos0_.userid as userid0_0_, photos0_.typeid as typeid0_0_, photos0_.name as name0_0_, photos0_.createtime as createtime0_0_, photos0_.description as descript6_0_0_, photos0_.faceid as faceid0_0_, photos0_.uri as uri0_0_ from super.photos photos0_ where photos0_.id=?
lazy=true 一句查询 有getPicture()
Hibernate: select photos0_.id as id0_0_, photos0_.userid as userid0_0_, photos0_.typeid as typeid0_0_, photos0_.name as name0_0_, photos0_.createtime as createtime0_0_, photos0_.description as descript6_0_0_, photos0_.faceid as faceid0_0_, photos0_.uri as uri0_0_ from super.photos photos0_ where photos0_.id=?
lazy=true 一句查询 有getPicture() 并且访问了里面的元数Picture 且有异常抛出
Hibernate: select photos0_.id as id0_0_, photos0_.userid as userid0_0_, photos0_.typeid as typeid0_0_, photos0_.name as name0_0_, photos0_.createtime as createtime0_0_, photos0_.description as descript6_0_0_, photos0_.faceid as faceid0_0_, photos0_.uri as uri0_0_ from super.photos photos0_ where photos0_.id=?
lazy="false" 两句查询 肯定没问题,因为全部数据都个查了出来 所以怎么调用都正常
Hibernate: select photos0_.id as id0_0_, photos0_.userid as userid0_0_, photos0_.typeid as typeid0_0_, photos0_.name as name0_0_, photos0_.createtime as createtime0_0_, photos0_.description as descript6_0_0_, photos0_.faceid as faceid0_0_, photos0_.uri as uri0_0_ from super.photos photos0_ where photos0_.id=?
Hibernate: select pictures0_.photosid as photosid1_, pictures0_.id as id1_, pictures0_.id as id2_0_, pictures0_.photosid as photosid2_0_, pictures0_.name as name2_0_, pictures0_.clicked as clicked2_0_, pictures0_.uploaddate as uploaddate2_0_, pictures0_.size as size2_0_, pictures0_.description as descript7_2_0_, pictures0_.uri as uri2_0_ from super.picture pictures0_ where pictures0_.photosid=?
fetch="join" 一句查询 效果 == lazy="false" 呵呵,哪个效率高,我就不知道了。。。。。。。。。。。
Hibernate: select photos0_.id as id0_1_, photos0_.userid as userid0_1_, photos0_.typeid as typeid0_1_, photos0_.name as name0_1_, photos0_.createtime as createtime0_1_, photos0_.description as descript6_0_1_, photos0_.faceid as faceid0_1_, photos0_.uri as uri0_1_, pictures1_.photosid as photosid3_, pictures1_.id as id3_, pictures1_.id as id2_0_, pictures1_.photosid as photosid2_0_, pictures1_.name as name2_0_, pictures1_.clicked as clicked2_0_, pictures1_.uploaddate as uploaddate2_0_, pictures1_.size as size2_0_, pictures1_.description as descript7_2_0_, pictures1_.uri as uri2_0_ from super.photos photos0_ left outer join super.picture pictures1_ on photos0_.id=pictures1_.photosid where photos0_.id=?
不加fetch="join" 一句查询 没有getPicture() 正常
Hibernate: select photos0_.id as id0_0_, photos0_.userid as userid0_0_, photos0_.typeid as typeid0_0_, photos0_.name as name0_0_, photos0_.createtime as createtime0_0_, photos0_.description as descript6_0_0_, photos0_.faceid as faceid0_0_, photos0_.uri as uri0_0_ from super.photos photos0_ where photos0_.id=?
不加fetch="join" 一句查询 有getPicture() 正常
Hibernate: select photos0_.id as id0_0_, photos0_.userid as userid0_0_, photos0_.typeid as typeid0_0_, photos0_.name as name0_0_, photos0_.createtime as createtime0_0_, photos0_.description as descript6_0_0_, photos0_.faceid as faceid0_0_, photos0_.uri as uri0_0_ from super.photos photos0_ where photos0_.id=?
不加fetch="join" 一句查询 有getPicture() 并且访问里面的元素Picture的ID 有异常抛出
Hibernate: select photos0_.id as id0_0_, photos0_.userid as userid0_0_, photos0_.typeid as typeid0_0_, photos0_.name as name0_0_, photos0_.createtime as createtime0_0_, photos0_.description as descript6_0_0_, photos0_.faceid as faceid0_0_, photos0_.uri as uri0_0_ from super.photos photos0_ where photos0_.id=?
来个两兵交战 fetch="join" lazy="true" 呵呵 结果,一句查询, 结构正常 所以就当lazy不存在好了。 看来fetch 是老大。、、、、、、、、、、、、、
Hibernate: select photos0_.id as id0_1_, photos0_.userid as userid0_1_, photos0_.typeid as typeid0_1_, photos0_.name as name0_1_, photos0_.createtime as createtime0_1_, photos0_.description as descript6_0_1_, photos0_.faceid as faceid0_1_, photos0_.uri as uri0_1_, pictures1_.photosid as photosid3_, pictures1_.id as id3_, pictures1_.id as id2_0_, pictures1_.photosid as photosid2_0_, pictures1_.name as name2_0_, pictures1_.clicked as clicked2_0_, pictures1_.uploaddate as uploaddate2_0_, pictures1_.size as size2_0_, pictures1_.description as descript7_2_0_, pictures1_.uri as uri2_0_ from super.photos photos0_ left outer join super.picture pictures1_ on photos0_.id=pictures1_.photosid where photos0_.id=?
发表评论
-
反向建表
2014-11-06 16:49 623<entry key="hibernate.h ... -
Hibernate 利用无状态session 解决大批量上传、修改数据缓慢的问题
2012-03-14 09:23 1525在最近的SSH项目里面需要做大量数据上传(上万条数据的inse ... -
二级缓存配置
2012-03-11 14:38 7911、首先要打开二级缓存,在hibernate.cfg.x ... -
hibernate分页
2011-09-21 20:30 734需要建立query对象,他有两个方法, Query query ... -
hibernate的锁
2011-08-15 16:40 691锁( locking ) 业务逻辑的实现过程中,往往需要保证数 ... -
clob用在dao层
2011-08-04 17:55 757public static String clob2Stri ... -
hibernate 也用找id
2011-04-18 19:07 868Connection poolConn=session.con ... -
list和iterate的区别?
2011-04-11 16:47 1070list和iterate的区别? list: 默认情况 ... -
hibernate 在j2ee中要用dual
2011-03-10 08:55 975网摘,自已试了可以,但不能在hql中加序列。 想查出序列还是 ... -
HIBERNATE事务
2011-02-28 17:01 1416<!-- 配置Hibernate的局部事务管理器,使用H ... -
Hashtable,list要用好
2010-12-23 10:30 739List list = partyerService.quer ... -
配置文件变动频繁时
2010-12-22 17:24 888项目开发中,配置文件时常在自己机器上和主机会有改动,项目中要注 ...
相关推荐
SSH之Hibernate总结 SSH(Struts、Spring、Hibernate)是Java Web开发中常见的三大框架,而Hibernate作为ORM(对象关系映射)框架,是连接Java应用程序与数据库的关键组件。本总结将围绕Hibernate的核心概念、配置...
【Hibernate总结】 Hibernate是一个强大的Java持久化框架,它封装了JDBC,负责对象持久化,作为应用程序和数据库之间的中间层。映射关系是通过配置文件维护的,这使得Hibernate能够与不同的数据库系统灵活地交互。 ...
本资源包含的"hibernate总结练习源码"提供了对Hibernate ORM框架实际应用的实例,有助于深入理解和掌握其核心概念与功能。 1. **对象关系映射(ORM)**:Hibernate 提供了一种机制,将数据库中的表映射为Java类,表...
《Hibernate总结(三)》 在本篇关于Hibernate的总结中,我们将深入探讨这个流行的Java对象关系映射(ORM)框架的关键概念和技术细节。Hibernate作为一款强大的工具,它极大地简化了Java开发人员处理数据库操作的工作...
标题:hibernate总结 描述:此文档是个人在使用Hibernate框架进行数据持久化操作时的经验积累和技巧分享。文档全面覆盖了Hibernate的各种配置方法、数据映射技术、集合类映射、对象关系映射(ORM)基础以及与J2EE...
### 学习Hibernate总结 #### 一、简介与配置 Hibernate是Java环境下一款优秀的对象关系映射(ORM)框架,它极大地简化了数据访问层(DAL)的编码工作,允许开发人员将主要精力集中在业务逻辑上而不是繁琐的SQL语句...
1. 引入Hibernate所需的JAR文件,例如在Eclipse中创建Hibernate类库。 2. 创建配置文件`hibernate.cfg.xml`,其中包含数据库连接信息、日志格式等。 3. 设计实体类,对应数据库表中的记录,并提供对应的getter和...
**总结项目实战** 在实际项目中,使用 Hibernate 可以简化数据库操作,提高开发效率。常见的应用场景包括用户管理、订单处理、商品分类等。项目实践中要注意合理设计实体关系,避免 N+1 查询问题,利用缓存优化性能...
在Java开发中,Hibernate是一个非常重要的对象关系映射(ORM)框架,它简化了数据库操作,使得开发者可以使用面向对象的方式来处理数据。本教程将深入探讨如何使用Hibernate来实现一个简单的课程管理系统,涵盖多对...
总结来说,JDBC是基础的数据库访问技术,适合进行简单的数据库操作,而Hibernate则通过提供面向对象的接口,极大地简化了数据库操作,尤其适用于复杂的业务场景。两者结合使用,可以让开发者在享受面向对象编程便利...
《Hibernate4总结文档》 Hibernate4作为一款强大的Java对象关系映射框架,简化了数据库操作,使得开发者可以更专注于业务逻辑而不是数据库层面的细节。本文将深入探讨Hibernate4的配置和使用,帮助开发者更好地理解...
总结来说,Hibernate是一个强大的ORM框架,它极大地简化了Java应用的数据库操作,提高了开发效率,并提供了高级特性如缓存、事务管理等。通过深入理解和熟练使用Hibernate,开发者可以构建更高效、更易于维护的...