- 浏览: 495533 次
- 性别:
- 来自: 上海
文章分类
- 全部博客 (271)
- json (6)
- hibernate (12)
- javascript (25)
- session cookie (2)
- struts2 (12)
- 数据库 (23)
- spring (25)
- freemarker (2)
- 其它 (17)
- ibatis (5)
- Web Service (5)
- java基础 (54)
- hessian (2)
- lucene (7)
- DWR (1)
- 导出excel (1)
- CSS (1)
- java 邮件 (5)
- SSH转载 (5)
- 文件断点 上传 (8)
- jQuery (7)
- ant (2)
- tuscany (5)
- maven (7)
- rsa (2)
- tomcat (2)
- svn (3)
- comet (2)
- log4j (2)
- linux (4)
- hadoop (1)
- 设计模式 (4)
- ssh (2)
- git (3)
- quartz (1)
- dubbo (2)
- mysql (2)
- 注解 (1)
- easyui (1)
- tree (1)
- 堆栈 (1)
- 泛型 (1)
- eclipse (1)
- annotation (1)
- mvc (3)
- shiro (1)
- Nexus (1)
- jackson (1)
- itext (1)
- mina (1)
- nio (1)
- ehcache (2)
- memcached (1)
- restful (2)
- mongodb (1)
- solr (1)
- zookeeper (1)
- redis (1)
- vpn (0)
- elastic (2)
- xxl-job (1)
最新评论
-
g_tao:
作者你好,你这个例子中服务端是跑在tomcat中吗
阿里巴巴dubbo处理文件上传下载 -
g_tao:
作者你好,能把整个项目给我发一份吗?guotao114@126 ...
阿里巴巴dubbo处理文件上传下载 -
tanmingjuntan:
楼上 本文提供的代码样例 和 你之前提供的例子有出入好多都没 ...
使用HttpURLConnection.setChunkedStreamingMode(10*1024);的时候,不同的参数导致文件上传损坏 -
dreamoftch:
dannielhome 写道请问下这个upload.exe是什 ...
断点文件上传流程 -
dannielhome:
请问下这个upload.exe是什么东西呢
断点文件上传流程
================映射关系设置=====================
http://jyjiao2007.iteye.com/blog/760554
关系映射:对象之间的对应数量关系
单、双的数据库表是一样的,只是程序中不同
无论是1对1,还是多对多,还是一对多,只要是双向的,一定要设置mappedby,以及要存对象的时候,要设置好对象之间的关联关系。
1. 1 对 1:(双向外键关联的意思:在程序中两边都设置对方的引用,但是在数据库中一样的,注意设置 mappedBy属性)
1.1 单(主键、外键)
外键关联:@OneToOne
属性:fetch,cascade…
@JoinColumn(name=”wife”)
1.2 双(主键、外键)
外键关联:互有引用
@OneToOne(mappedBy=”wife”)
规律:凡是双向关联,必设mappedBy
2. 多对1:(数据库中两张表,并在多的那个表中加上1的外键)
2.1单:
在程序中在多方类中增加单方类的引用,并在引用对象的get方法上增加 @Many2One
2.2双:
1) 在多方类(User) 的单方引用的get方法上设置:@Many2One
2) 在单方类(group)的多方类引用哈希表对象的get方法上设置一个主解:
@One2Many(mappedBy=”group”)
3. 1对多:(数据库表中有三张表,还生成了一张中间表(默认当成多对多))
3.1 单:在单方类中增加多的引用的HashSet<User>
@One2Many 注解
@JoinColumn(name=”groupId”)
Ps:感觉不太好理解。。。
3.2双
5. 多对多:
5.1 单:
在数据库中增加一张中间关联表,有两个字段:两个表的id,且这两个id构成联合主键、每个id分别为其中一张表的主键作为外键。
@ManyToMany
5.2 双:
6. 集合映射:
7. 继承关系映射:
8. 组合映射(不太理解)
1)除去Wife中主键字段 以及相应的get、set方法,去除该类的@Entity的注解
2)在Husband 类中的getWife()方法上增加 @Embedded 注解
3) hibernate.ctg.xml中去掉Wife的mapping class 标签
9. 联合主键:
10. 简化问题
1) 怎么写Annotation
2) 如何写CRUD
11. Hibernate中的级联操作(关联关系中的CRUD)
默认情况下的基本写法:
Java代码 收藏代码
User u = new User();
u.setName(“user”);
Group g = new Group(“g”);
g.setName(“g”);
u.setGroup(g);
Session session = sessionFactory.getCurrenSession(); Session.beginTrasation();
Session.save(g); (g: detached 状态)
Session.save(u);
Session.getTransation().commit();
使用Spring中的机制的写法:直接存user即可
需要做的是: @ManyToOne( cascade={CascadeType.ALL} )
@OneToMany(mappedBy=”group” ,cascade = {CascadeType.ALL} )….
(从多的一方操作比较方便)
铁律:
1. 双向关系在程序中要在多方设置双向关联:
@ManyToOne( cascade={CascadeType.ALL} ),不然会出错
2. 如果是1对多的双向关系中,需要在单方设置:@OneToMany(mappedBy=” “)
ALL | MERGE| PERSIST | REFRESH | REMOVE
ALL: 对于一个对象任何的持久化操作(增删改查)都会级联到另一个对象
REFRESH:
PERSIST:保存的时候级联
REMOVE:删除的时候级联
不设置 cascade属性将不产生任何级联
级联读操作:
示例程序:
Session s = sessionFactory.getCurrentSession();
s.beginTransation();
//由于@ManyToOne默认会 把1 给取出来,不必设//cascade属性
User u = (User) s.get(User.class , 1);
s.getTransation().commit();
@OneToMany 默认不会级联取出其中对象(取出group对象时默认不会将其所有User对象取出)
cascade属性只负责cud;
fetch:负责 get、load等读取 {FetchType.LAZY, FetchType.EAGER}
l Eager 加载 和 lazy 加载的区别:
eager 加载: 会将需要加载的类(user)以及其关联的对象(group)一起放入内存中。如果session关闭了仍能处理其关联的对象(group)
lazy 加载: 只有当要访问关联的对象(user)时,才从数据库中取得。如果session关闭后被关联的对象不在内存中,此时是无法再取得被关联对象(group) 的。
-------------------------------------------------------------------------------------------------------
Load的时候 fetchType为 LAZY和EAGER的区别:
LAZY: 先从数据库中取出user对象的信息,再取出group对象的信息
级联更新操作
@ManyToOne(cascade = {CascadeType.ALL})
级联删除操作:
l 取消在多方删除对象时级联删除单方对象:
或者:
l 在单方级联删除多方:
1. 一般情况下默认级联删除
2. 取消在单方删除情况下删除多方对象
利用HQL进行精确控制
=================几个问题=======================================
1. 什么是SessionFactory 以及 SessionFactory的取得:
1.1 SessionFactory是由Spring容器来管理的、用来创建Session对象的单例类
1.2 取得SessionFactory对象:
Java代码 收藏代码
public class SessionFactoryTest{
private static SessionFactory sessionFactroy;
public static SessionFactory getSessionFactory(){
sessionFactory = AnnotationConfiguration.configure().buildSessionFactory();
return sessionFactory;
}
}
2. SessionFactory 的 getCurrentSession()方法 和 openSession()方法 的区别:
1) 用途: 界定事务边界(getCurrentSession从上下文中找,如果有就用已有的;如果没有,创建新的session)
2) 用法: 事务提交时是否自动 close session
上下文: 必须配置 current_session_context_class属性的值: jta| thread| managed| custom.Class
thread:即在当前线程中获取 session
3. session
一次数据库会话。
从session中可以取得一个数据库连接,因此每次新建一个session的同时获得也了一个数据库连接
session负责实现对数据库的增、删、改、查操作
API:
1. beginTransaction()
2. getTransaction().commit()
3. save(Object object) 三种状态
5. load()
6. get()
7. update()
8. delete() 参考三种状态
9. saveOrUpdate()
10. clear()
11. flush()
5. hibernate 中三种状态
transient : 对象没有持久化到数据库中,也没有放到session的缓存中
persistent : 对象既持久化到数据库中了,也放到session的缓存中了
detached: 对象在持久化在数据库中,但已经不在session的缓存中了,因为session已经关闭了
三种状态的区分:对象是否在数据库中 对象是否在缓存(session中的hashmap)中
6. 关系映射
七种关系:参考映射关系设置部分
7. 性能优化
hibernate一级缓存、二级缓存和查询缓存简介:
1) 什么是缓存
2) 什么是一级缓存,session级别缓存
session缓存:一级缓存
3) 什么是二级缓存,SessionFactory 级别的缓存,可以跨越session存在
二级缓存由第三方提供
二级缓存又称为:SessionFactory级别的缓存(每个应用只有一个SessionFactory)
5) 打开二级缓存
l 适合放在二级缓存的对象:
经常被访问
不会经常改动
数量不多
l 打开的步骤:
第一步:hibernate.cfg.xml 设定:
第二步: @Cache注解
6) load 默认使用二级缓存,iterate 默认使用二级缓存
7) list 默认往二级缓存加数据,但是查询的时候不使用
8) 如果要 query用二级缓存,需要打开查询缓存
重复查询(查询语句)使用的缓存,两个不同的查询不能使用二级缓存
打开二级缓存:
测试代码:
9)缓存算法
8. O/R Mapping模型:
a) 映射模型
jpa annotation
hibernate annotation extension
hibernate xml
jpa xml
b) 编程接口
jpa
hibernate
c) 数据查询语言
sql
hql
ejbql(jpql)
============= ===重点学习提纲===================================
参考:http://wxg6203.iteye.com/blog/766947
Hibernate是目前最流行的开源对象关系映射(ORM)框架。Hibernate采用低侵入式的设计,也即完全采用普通的Java对象(POJO),而不必继承Hibernate的某个基类,或实现Hibernate的某个接口。Hibernate是面向对象的程序设计语言和关系数据库之间的桥梁,Hibernate允许程序开发者采用面向对象的方式来操作关系数据库。
因为我们知道hibernate它能支持透明持久化从这个角度来看它没有侵入性 所谓侵入性它没有侵入hibernate任何的API所以它叫轻量级框架,轻量级框架的好处是没有侵入性 另外的一个好处是为测试带来了好处,测试非常简单 测试就行我们写普通的java应用程序一样不需要什么环境只需要几个jar包就可以了写个main函数一侧就可以了 它没有侵入性和测试非常简单 这是它流行的一个原因。
hibernate的优缺点
优点:1、程序更加面向对象;
2、提高了生产率;
3、方便移植(修改配置文件);
4、无侵入性。
缺点:
1、效率比JDBC略差;
2、不适合批量操作。
3、只能配置一种关联关系
Hibernate有四种查询方案
1、get,load方法,根据id查找对象
2、HQL--hibernate query language(查询对象:Query)
3、Criteria--标准查询语言(查询对象:Criteria,查询条件:Criterion)
4、通过sql来查(查询对象:SQLQuery)
具体
Query/Criteria:
1.Query接口封装了Hibernate强大的对象查询能力,同时也支持数据库的更新操作
2.提供了动态查询的参数绑定功能
3.提供list(),iterator(),scroll()等对象导航方法
4.提供uiqueResult()方法获取单独的对象
5.提供executeUpdate()方法来执行DML语句
6.提供了可移植的分页查询方法
Session:
1、save,presist保存数据,persist在事务外不会产生insert语句。
2、delete,删除对象
3、update,更新对象,如果数据库中没有记录,会出现异常,脱管对象如属性改变需要保存,则调用update方法
4、get,根据ID查,会立刻访问数据库
5、load,根据ID查,(返回的是代理,不会立即访问数据库)
6、saveOrUpdate,merge(根据ID和version的值来确定是否是save或update),调用merge你的对象还是托管的。当不知该对象的状态时可调用该方法
小贴士:瞬时对象id无值,脱管对象有值,hibernate通过该方式判断对象的状态
7、lock(把对象变成持久对象,但不会同步对象的状态)
hibernate的工作原理
1.配置好hibernate的配置文件和与类对应的配置文件后,启动服务器
2.服务器通过实例化Configuration对象,读取hibernate.cfg.xml文件的配置内容,并根据相关的需求建好表或者和表建立好映射关系
3.通过实例化的Configuration对象就可以建立sessionFactory实例,进一步,通过sessionFactory实例可以创建 session对象
4.得到session之后,便可以对数据库进行增删改查操作了,除了比较复杂的全文搜索外,简单的操作都可以通过hibernate封装好的 session内置方法来实现
5.此外,还可以通过事物管理,表的关联来实现较为复杂的数据库设计
优点:hibernate相当于java类和数据库表之间沟通的桥梁,通过这座桥我们就可以做很多事情了
Hibernate 的初始化.
1)创建Configeration类的实例。
它的构造方法:将配置信息(Hibernate config.xml)读入到内存。
一个Configeration 实例代表Hibernate 所有Java类到Sql数据库映射的集合。
2)创建SessionFactory实例
把Configeration 对象中的所有配置信息拷贝到SessionFactory的缓存中。
SessionFactory的实例代表一个数据库存储员源,创建后不再与Configeration 对象关联。
3)调用SessionFactory创建Session的方法
1】用户自行提供JDBC连接。
Connection con=dataSource.getConnection();
Session s=sessionFactory.openSession(con);
2】让SessionFactory提供连接
Session s=sessionFactory.openSession();
状态转换
临时状态 (transient)
1】不处于Session 缓存中
2】数据库中没有对象 录
Java如何进入临时状态
1】通过new语句刚创建一个对象时
2】当调用Session 的delete()方法,从Session 缓存中删除一个对象时。
持久化状态(persisted)
1】处于Session 缓存中
2】持久化对象数据库中有对象记录
3】Session 在特定时刻会保持二者同步
Java如何进入持久化状态
1】Session 的save()把临时-》持久化状态
2】Session 的load(),get()方法返回的对象
3】Session 的find()返回的list集合中存放的对象
4】Session 的update(),saveOrupdate()使游离-》持久化
游离状态(detached)
1】不再位于Session 缓存中
2】游离对象由持久化状态转变而来,数据库中可能还有对应记录。
Java如何进入持久化状态-》游离状态
1】Session 的close()方法
2】Session 的evict()方法,从缓存中删除一个对象。提高性能。少用。
具体如图:
缓存
主要有session缓存(一级缓存)和sessionfactory缓存(内置缓存和外置缓存(也叫二级缓存))
Session的缓存是内置的,不能被卸载,也被称为Hibernate的第一级缓存(Session的一些集合属性包含的数据)。在第一级缓存中,持久化类的每个实例都具有唯一的OID。
SessionFactory的缓存又可以分为两类:
内置缓存(存放SessionFactory对象的一些集合属性包含的数据,SessionFactory的内置缓存中存放了映射元数据和预定义SQL语句,映射元数据是映射文件中数据的拷贝,而预定义SQL语句是在Hibernate初始化阶段根据映射元数据推导出来,SessionFactory的内置缓存是只读的,应用程序不能修改缓存中的映射元数据和预定义SQL语句,因此SessionFactory不需要进行内置缓存与映射文件的同步。)
外置缓存:SessionFactory的外置缓存是一个可配置的插件。在默认情况下,SessionFactory不会启用这个插件。外置缓存的数据是数据库数据的拷贝,外置缓存的介质可以是内存或者硬盘。SessionFactory的外置缓存也被称为Hibernate的第二级缓存。
缓存的范围分为三类。
1 事务范围:缓存只能被当前事务访问。
2 进程范围:缓存被进程内的所有事务共享。
3 集群范围:在集群环境中,缓存被一个机器或者多个机器的进程共享。
持久化层可以提供多种范围的缓存。如果在事务范围的缓存中没有查到相应的数据,还可以到进程范围或集群范围的缓存内查询,如果还是没有查到,那么只有到数据库中查询。事务范围的缓存是持久化层的第一级缓存,通常它是必需的;进程范围或集群范围的缓存是持久化层的第二级缓存,通常是可选的。
在进程范围或集群范围的缓存,即第二级缓存,会出现并发问题。因此可以设定以下四种类型的并发访问策略,每一种策略对应一种事务隔离级别。
事务型、读写型、非严格读写型、只读型
什么样的数据适合存放到第二级缓存中?
1 很少被修改的数据
2 不是很重要的数据,允许出现偶尔并发的数据
3 不会被并发访问的数据
4 参考数据
不适合存放到第二级缓存的数据?
1 经常被修改的数据
2 财务数据,绝对不允许出现并发
3 与其他应用共享的数据。
Hibernate的二级缓存策略的一般过程如下:
1) 条件查询的时候,总是发出一条select * from table_name where …. (选择所有字段)这样的SQL语句查询数据库,一次获得所有的数据对象。
2) 把获得的所有数据对象根据ID放入到第二级缓存中。
3) 当Hibernate根据ID访问数据对象的时候,首先从Session一级缓存中查;查不到,如果配置了二级缓存,那么从二级缓存中查;查不到,再查询数据库,把结果按照ID放入到缓存。
4) 删除、更新、增加数据的时候,同时更新缓存。
注意几个关键字的含义
inverse="true"表示此表不维护表之间的关系,由另外的表维护。
inverse属性默认是false的,就是说关系的两端都来维护关系。
false代表由己方来维护关系,true代表由对方来维护关系。在一个关系中,只能由一方来维护关系,否则会出问题(解疑中会讲到);同时也必须由一方来维护关系,否则会出现双方互相推卸责任,谁也不管。
可以这样理解,cascade定义的是关系两端对象到对象的级联关系;而inverse定义的是关系和对象的级联关系。
Cascade属性的可能值有
all: 所有情况下均进行关联操作,即save-update和delete。
none: 所有情况下均不进行关联操作。这是默认值。
save-update: 在执行save/update/saveOrUpdate时进行关联操作。
delete: 在执行delete 时进行关联操作。
all-delete-orphan: 当一个节点在对象图中成为孤儿节点时,删除该节点。比如在一个一对多的关系中,Student包含多个book,当在对象关系中删除一个book时,此book即成为孤儿节点。
主键生成策略
increment,identity,sequence,hilo,native,uuid,foreign,assigned,seqhilo,uuid.hex,uuid.string
面试题:
1.Hibernate有哪几种查询数据的方式
2.load()和get()的区别
3.Hibernate工作原理及为什么要用?
4.Hibernate是如何延迟加载?
5.Hibernate中怎样实现类之间的关系?(如:一对多、多对多的关系)
6. 说下Hibernate的缓存机制
7. Hibernate的查询方式
8. 如何优化Hibernate?
------------------------------------------------------------------------------------------------------------------
1.在数据库中条件查询速度很慢的时候,如何优化?
2.在Hibernate中进行多表查询,每个表中各取几个字段,也就是说查询出来的结果集并没有一个实体类与之对应,如何解决这个问题?
3.session.load()和session.get()的区别
4.Session在加载实体对象时,将经过的过程:
5.Hibernate的主键生成机制
=====================Hibernate笔试题==========================
(1)一般情况下,关系数据模型与对象模型之间有哪些匹配关系(多选)
A)表对应类
B)记录对应对象
C)表的字段对应类的属性
D)表之间的参考关系对应类之间的依赖关系
(2)以下关于SessionFactory的说法哪些正确?(多选)
A)对于每个数据库事务,应该创建一个SessionFactory对象
B)一个SessionFactory对象对应一个数据库存储源。
C)SessionFactory是重量级的对象,不应该随意创建。如果系统中只有一个数据库存储源,只需要创建一个。
D)SessionFactory的load()方法用于加载持久化对象
(3)Customer类中有一个Set类型的orders属性,用来存放Order订单对象,在Customer.hbm.xml文件中,用哪个元素映射orders属性?
A)<set> B)<one-to-many> C)<many-to-one> D)<property>
(4)<set>元素有一个cascade属性,如果希望Hibernate级联保存集合中的对象,casecade属性应该取什么值?(单选)
A)none
B)save
C)delete
D)save-update
(5)以下哪些属于Session的方法?
A)load()
B)save()
C)delete()
D)update()
E)open()
F)close()
(6)以下程序的打印结果是什么?(单选)
tx = session.beginTransaction();
Customer c1=(Customer)session.load(Customer.class,new Long(1));
Customer c2=(Customer)session.load(Customer.class,new Long(1));
System.out.println(c1==c2);
tx.commit();
session.close();
A)运行出错,抛出异常
B)打印false
C)打印true
(7)以下程序代码对Customer的name属性修改了两次:
tx = session.beginTransaction();
Customer customer=(Customer)session.load(Customer.class,
new Long(1));
customer.setName(\"Jack\");
customer.setName(\"Mike\");
tx.commit();
执行以上程序,Hibernate需要向数据库提交几条update语句?(单选)
A)0 B)1 C)2 D)3
(8)在持久化层,对象分为哪些状态?(多选)
A)临时状态
B)独立状态
C)游离状态
D)持久化状态
(9)对于以下程序,Customer对象在第几行变为持久化状态?(单选)
Customer customer=new Customer(); //line1
customer.setName(\"Tom\"); //line2
Session session1=sessionFactory.openSession(); //line3
Transaction tx1 = session1.beginTransaction(); //line4
session1.save(customer); //line4
tx1.commit(); //line5
session1.close(); //line6
A) line1 B)line2 C)line3 D)line4 E)line5 F)line6
(10)对于以下程序,Customer对象在第几行变为游离状态?(单选)
Customer customer=new Customer(); //line1
customer.setName(\"Tom\"); //line2
Session session1=sessionFactory.openSession(); //line3
Transaction tx1 = session1.beginTransaction(); //line4
session1.save(customer); //line4
tx1.commit(); //line5
session1.close(); //line6
A) line1 B)line2 C)line3 D)line4 E)line5 F)line6
(11)以下哪一种检索策略利用了外连结查询?(单选)
A)立即检索 B)延迟检索 C)迫切左外连结检索
(12)假设对Customer类的orders集合采用延迟检索策略,编译或运行以下程序,会出现什么情况(单选)
Session session=sessionFactory.openSession();
tx = session.beginTransaction();
Customer customer=(Customer)session.get(Customer.class,new Long(1));
tx.commit();
session.close();
Iterator orderIterator=customer.getOrders().iterator();
A)编译出错 B)编译通过,并正常运行 C)编译通过,但运行时抛出异常
(13)关于HQL与SQL,以下哪些说法正确?(多选)
A)HQL与SQL没什么差别
B)HQL面向对象,而SQL操纵关系数据库
C)在HQL与SQL中,都包含select,insert,update,delete语句
D)HQL仅用于查询数据,不支持insert,update和delete语句
(14)事务隔离级别是由谁实现的?(单选)
A)Java应用程序 B)Hibernate C)数据库系统 D)JDBC驱动程序
(15)悲观锁与乐观锁,哪个具有较好的并发性能?(单选)
A)悲观锁 B)乐观锁
答案:
(1)A,B,C (2)B,C (3)A (4)D (5)A,B,C,D,F (6)C (7)B (8)A,C,D (9)D (10)F (11)C (12)C (13)B,D (14)C (15)B
http://jyjiao2007.iteye.com/blog/760554
关系映射:对象之间的对应数量关系
单、双的数据库表是一样的,只是程序中不同
无论是1对1,还是多对多,还是一对多,只要是双向的,一定要设置mappedby,以及要存对象的时候,要设置好对象之间的关联关系。
1. 1 对 1:(双向外键关联的意思:在程序中两边都设置对方的引用,但是在数据库中一样的,注意设置 mappedBy属性)
1.1 单(主键、外键)
外键关联:@OneToOne
属性:fetch,cascade…
@JoinColumn(name=”wife”)
1.2 双(主键、外键)
外键关联:互有引用
@OneToOne(mappedBy=”wife”)
规律:凡是双向关联,必设mappedBy
2. 多对1:(数据库中两张表,并在多的那个表中加上1的外键)
2.1单:
在程序中在多方类中增加单方类的引用,并在引用对象的get方法上增加 @Many2One
2.2双:
1) 在多方类(User) 的单方引用的get方法上设置:@Many2One
2) 在单方类(group)的多方类引用哈希表对象的get方法上设置一个主解:
@One2Many(mappedBy=”group”)
3. 1对多:(数据库表中有三张表,还生成了一张中间表(默认当成多对多))
3.1 单:在单方类中增加多的引用的HashSet<User>
@One2Many 注解
@JoinColumn(name=”groupId”)
Ps:感觉不太好理解。。。
3.2双
5. 多对多:
5.1 单:
在数据库中增加一张中间关联表,有两个字段:两个表的id,且这两个id构成联合主键、每个id分别为其中一张表的主键作为外键。
@ManyToMany
5.2 双:
6. 集合映射:
7. 继承关系映射:
8. 组合映射(不太理解)
1)除去Wife中主键字段 以及相应的get、set方法,去除该类的@Entity的注解
2)在Husband 类中的getWife()方法上增加 @Embedded 注解
3) hibernate.ctg.xml中去掉Wife的mapping class 标签
9. 联合主键:
10. 简化问题
1) 怎么写Annotation
2) 如何写CRUD
11. Hibernate中的级联操作(关联关系中的CRUD)
默认情况下的基本写法:
Java代码 收藏代码
User u = new User();
u.setName(“user”);
Group g = new Group(“g”);
g.setName(“g”);
u.setGroup(g);
Session session = sessionFactory.getCurrenSession(); Session.beginTrasation();
Session.save(g); (g: detached 状态)
Session.save(u);
Session.getTransation().commit();
使用Spring中的机制的写法:直接存user即可
需要做的是: @ManyToOne( cascade={CascadeType.ALL} )
@OneToMany(mappedBy=”group” ,cascade = {CascadeType.ALL} )….
(从多的一方操作比较方便)
铁律:
1. 双向关系在程序中要在多方设置双向关联:
@ManyToOne( cascade={CascadeType.ALL} ),不然会出错
2. 如果是1对多的双向关系中,需要在单方设置:@OneToMany(mappedBy=” “)
ALL | MERGE| PERSIST | REFRESH | REMOVE
ALL: 对于一个对象任何的持久化操作(增删改查)都会级联到另一个对象
REFRESH:
PERSIST:保存的时候级联
REMOVE:删除的时候级联
不设置 cascade属性将不产生任何级联
级联读操作:
示例程序:
Session s = sessionFactory.getCurrentSession();
s.beginTransation();
//由于@ManyToOne默认会 把1 给取出来,不必设//cascade属性
User u = (User) s.get(User.class , 1);
s.getTransation().commit();
@OneToMany 默认不会级联取出其中对象(取出group对象时默认不会将其所有User对象取出)
cascade属性只负责cud;
fetch:负责 get、load等读取 {FetchType.LAZY, FetchType.EAGER}
l Eager 加载 和 lazy 加载的区别:
eager 加载: 会将需要加载的类(user)以及其关联的对象(group)一起放入内存中。如果session关闭了仍能处理其关联的对象(group)
lazy 加载: 只有当要访问关联的对象(user)时,才从数据库中取得。如果session关闭后被关联的对象不在内存中,此时是无法再取得被关联对象(group) 的。
-------------------------------------------------------------------------------------------------------
Load的时候 fetchType为 LAZY和EAGER的区别:
LAZY: 先从数据库中取出user对象的信息,再取出group对象的信息
级联更新操作
@ManyToOne(cascade = {CascadeType.ALL})
级联删除操作:
l 取消在多方删除对象时级联删除单方对象:
或者:
l 在单方级联删除多方:
1. 一般情况下默认级联删除
2. 取消在单方删除情况下删除多方对象
利用HQL进行精确控制
=================几个问题=======================================
1. 什么是SessionFactory 以及 SessionFactory的取得:
1.1 SessionFactory是由Spring容器来管理的、用来创建Session对象的单例类
1.2 取得SessionFactory对象:
Java代码 收藏代码
public class SessionFactoryTest{
private static SessionFactory sessionFactroy;
public static SessionFactory getSessionFactory(){
sessionFactory = AnnotationConfiguration.configure().buildSessionFactory();
return sessionFactory;
}
}
2. SessionFactory 的 getCurrentSession()方法 和 openSession()方法 的区别:
1) 用途: 界定事务边界(getCurrentSession从上下文中找,如果有就用已有的;如果没有,创建新的session)
2) 用法: 事务提交时是否自动 close session
上下文: 必须配置 current_session_context_class属性的值: jta| thread| managed| custom.Class
thread:即在当前线程中获取 session
3. session
一次数据库会话。
从session中可以取得一个数据库连接,因此每次新建一个session的同时获得也了一个数据库连接
session负责实现对数据库的增、删、改、查操作
API:
1. beginTransaction()
2. getTransaction().commit()
3. save(Object object) 三种状态
5. load()
6. get()
7. update()
8. delete() 参考三种状态
9. saveOrUpdate()
10. clear()
11. flush()
5. hibernate 中三种状态
transient : 对象没有持久化到数据库中,也没有放到session的缓存中
persistent : 对象既持久化到数据库中了,也放到session的缓存中了
detached: 对象在持久化在数据库中,但已经不在session的缓存中了,因为session已经关闭了
三种状态的区分:对象是否在数据库中 对象是否在缓存(session中的hashmap)中
6. 关系映射
七种关系:参考映射关系设置部分
7. 性能优化
hibernate一级缓存、二级缓存和查询缓存简介:
1) 什么是缓存
2) 什么是一级缓存,session级别缓存
session缓存:一级缓存
3) 什么是二级缓存,SessionFactory 级别的缓存,可以跨越session存在
二级缓存由第三方提供
二级缓存又称为:SessionFactory级别的缓存(每个应用只有一个SessionFactory)
5) 打开二级缓存
l 适合放在二级缓存的对象:
经常被访问
不会经常改动
数量不多
l 打开的步骤:
第一步:hibernate.cfg.xml 设定:
第二步: @Cache注解
6) load 默认使用二级缓存,iterate 默认使用二级缓存
7) list 默认往二级缓存加数据,但是查询的时候不使用
8) 如果要 query用二级缓存,需要打开查询缓存
重复查询(查询语句)使用的缓存,两个不同的查询不能使用二级缓存
打开二级缓存:
测试代码:
9)缓存算法
8. O/R Mapping模型:
a) 映射模型
jpa annotation
hibernate annotation extension
hibernate xml
jpa xml
b) 编程接口
jpa
hibernate
c) 数据查询语言
sql
hql
ejbql(jpql)
============= ===重点学习提纲===================================
参考:http://wxg6203.iteye.com/blog/766947
Hibernate是目前最流行的开源对象关系映射(ORM)框架。Hibernate采用低侵入式的设计,也即完全采用普通的Java对象(POJO),而不必继承Hibernate的某个基类,或实现Hibernate的某个接口。Hibernate是面向对象的程序设计语言和关系数据库之间的桥梁,Hibernate允许程序开发者采用面向对象的方式来操作关系数据库。
因为我们知道hibernate它能支持透明持久化从这个角度来看它没有侵入性 所谓侵入性它没有侵入hibernate任何的API所以它叫轻量级框架,轻量级框架的好处是没有侵入性 另外的一个好处是为测试带来了好处,测试非常简单 测试就行我们写普通的java应用程序一样不需要什么环境只需要几个jar包就可以了写个main函数一侧就可以了 它没有侵入性和测试非常简单 这是它流行的一个原因。
hibernate的优缺点
优点:1、程序更加面向对象;
2、提高了生产率;
3、方便移植(修改配置文件);
4、无侵入性。
缺点:
1、效率比JDBC略差;
2、不适合批量操作。
3、只能配置一种关联关系
Hibernate有四种查询方案
1、get,load方法,根据id查找对象
2、HQL--hibernate query language(查询对象:Query)
3、Criteria--标准查询语言(查询对象:Criteria,查询条件:Criterion)
4、通过sql来查(查询对象:SQLQuery)
具体
Query/Criteria:
1.Query接口封装了Hibernate强大的对象查询能力,同时也支持数据库的更新操作
2.提供了动态查询的参数绑定功能
3.提供list(),iterator(),scroll()等对象导航方法
4.提供uiqueResult()方法获取单独的对象
5.提供executeUpdate()方法来执行DML语句
6.提供了可移植的分页查询方法
Session:
1、save,presist保存数据,persist在事务外不会产生insert语句。
2、delete,删除对象
3、update,更新对象,如果数据库中没有记录,会出现异常,脱管对象如属性改变需要保存,则调用update方法
4、get,根据ID查,会立刻访问数据库
5、load,根据ID查,(返回的是代理,不会立即访问数据库)
6、saveOrUpdate,merge(根据ID和version的值来确定是否是save或update),调用merge你的对象还是托管的。当不知该对象的状态时可调用该方法
小贴士:瞬时对象id无值,脱管对象有值,hibernate通过该方式判断对象的状态
7、lock(把对象变成持久对象,但不会同步对象的状态)
hibernate的工作原理
1.配置好hibernate的配置文件和与类对应的配置文件后,启动服务器
2.服务器通过实例化Configuration对象,读取hibernate.cfg.xml文件的配置内容,并根据相关的需求建好表或者和表建立好映射关系
3.通过实例化的Configuration对象就可以建立sessionFactory实例,进一步,通过sessionFactory实例可以创建 session对象
4.得到session之后,便可以对数据库进行增删改查操作了,除了比较复杂的全文搜索外,简单的操作都可以通过hibernate封装好的 session内置方法来实现
5.此外,还可以通过事物管理,表的关联来实现较为复杂的数据库设计
优点:hibernate相当于java类和数据库表之间沟通的桥梁,通过这座桥我们就可以做很多事情了
Hibernate 的初始化.
1)创建Configeration类的实例。
它的构造方法:将配置信息(Hibernate config.xml)读入到内存。
一个Configeration 实例代表Hibernate 所有Java类到Sql数据库映射的集合。
2)创建SessionFactory实例
把Configeration 对象中的所有配置信息拷贝到SessionFactory的缓存中。
SessionFactory的实例代表一个数据库存储员源,创建后不再与Configeration 对象关联。
3)调用SessionFactory创建Session的方法
1】用户自行提供JDBC连接。
Connection con=dataSource.getConnection();
Session s=sessionFactory.openSession(con);
2】让SessionFactory提供连接
Session s=sessionFactory.openSession();
状态转换
临时状态 (transient)
1】不处于Session 缓存中
2】数据库中没有对象 录
Java如何进入临时状态
1】通过new语句刚创建一个对象时
2】当调用Session 的delete()方法,从Session 缓存中删除一个对象时。
持久化状态(persisted)
1】处于Session 缓存中
2】持久化对象数据库中有对象记录
3】Session 在特定时刻会保持二者同步
Java如何进入持久化状态
1】Session 的save()把临时-》持久化状态
2】Session 的load(),get()方法返回的对象
3】Session 的find()返回的list集合中存放的对象
4】Session 的update(),saveOrupdate()使游离-》持久化
游离状态(detached)
1】不再位于Session 缓存中
2】游离对象由持久化状态转变而来,数据库中可能还有对应记录。
Java如何进入持久化状态-》游离状态
1】Session 的close()方法
2】Session 的evict()方法,从缓存中删除一个对象。提高性能。少用。
具体如图:
缓存
主要有session缓存(一级缓存)和sessionfactory缓存(内置缓存和外置缓存(也叫二级缓存))
Session的缓存是内置的,不能被卸载,也被称为Hibernate的第一级缓存(Session的一些集合属性包含的数据)。在第一级缓存中,持久化类的每个实例都具有唯一的OID。
SessionFactory的缓存又可以分为两类:
内置缓存(存放SessionFactory对象的一些集合属性包含的数据,SessionFactory的内置缓存中存放了映射元数据和预定义SQL语句,映射元数据是映射文件中数据的拷贝,而预定义SQL语句是在Hibernate初始化阶段根据映射元数据推导出来,SessionFactory的内置缓存是只读的,应用程序不能修改缓存中的映射元数据和预定义SQL语句,因此SessionFactory不需要进行内置缓存与映射文件的同步。)
外置缓存:SessionFactory的外置缓存是一个可配置的插件。在默认情况下,SessionFactory不会启用这个插件。外置缓存的数据是数据库数据的拷贝,外置缓存的介质可以是内存或者硬盘。SessionFactory的外置缓存也被称为Hibernate的第二级缓存。
缓存的范围分为三类。
1 事务范围:缓存只能被当前事务访问。
2 进程范围:缓存被进程内的所有事务共享。
3 集群范围:在集群环境中,缓存被一个机器或者多个机器的进程共享。
持久化层可以提供多种范围的缓存。如果在事务范围的缓存中没有查到相应的数据,还可以到进程范围或集群范围的缓存内查询,如果还是没有查到,那么只有到数据库中查询。事务范围的缓存是持久化层的第一级缓存,通常它是必需的;进程范围或集群范围的缓存是持久化层的第二级缓存,通常是可选的。
在进程范围或集群范围的缓存,即第二级缓存,会出现并发问题。因此可以设定以下四种类型的并发访问策略,每一种策略对应一种事务隔离级别。
事务型、读写型、非严格读写型、只读型
什么样的数据适合存放到第二级缓存中?
1 很少被修改的数据
2 不是很重要的数据,允许出现偶尔并发的数据
3 不会被并发访问的数据
4 参考数据
不适合存放到第二级缓存的数据?
1 经常被修改的数据
2 财务数据,绝对不允许出现并发
3 与其他应用共享的数据。
Hibernate的二级缓存策略的一般过程如下:
1) 条件查询的时候,总是发出一条select * from table_name where …. (选择所有字段)这样的SQL语句查询数据库,一次获得所有的数据对象。
2) 把获得的所有数据对象根据ID放入到第二级缓存中。
3) 当Hibernate根据ID访问数据对象的时候,首先从Session一级缓存中查;查不到,如果配置了二级缓存,那么从二级缓存中查;查不到,再查询数据库,把结果按照ID放入到缓存。
4) 删除、更新、增加数据的时候,同时更新缓存。
注意几个关键字的含义
inverse="true"表示此表不维护表之间的关系,由另外的表维护。
inverse属性默认是false的,就是说关系的两端都来维护关系。
false代表由己方来维护关系,true代表由对方来维护关系。在一个关系中,只能由一方来维护关系,否则会出问题(解疑中会讲到);同时也必须由一方来维护关系,否则会出现双方互相推卸责任,谁也不管。
可以这样理解,cascade定义的是关系两端对象到对象的级联关系;而inverse定义的是关系和对象的级联关系。
Cascade属性的可能值有
all: 所有情况下均进行关联操作,即save-update和delete。
none: 所有情况下均不进行关联操作。这是默认值。
save-update: 在执行save/update/saveOrUpdate时进行关联操作。
delete: 在执行delete 时进行关联操作。
all-delete-orphan: 当一个节点在对象图中成为孤儿节点时,删除该节点。比如在一个一对多的关系中,Student包含多个book,当在对象关系中删除一个book时,此book即成为孤儿节点。
主键生成策略
increment,identity,sequence,hilo,native,uuid,foreign,assigned,seqhilo,uuid.hex,uuid.string
面试题:
1.Hibernate有哪几种查询数据的方式
2.load()和get()的区别
3.Hibernate工作原理及为什么要用?
4.Hibernate是如何延迟加载?
5.Hibernate中怎样实现类之间的关系?(如:一对多、多对多的关系)
6. 说下Hibernate的缓存机制
7. Hibernate的查询方式
8. 如何优化Hibernate?
------------------------------------------------------------------------------------------------------------------
1.在数据库中条件查询速度很慢的时候,如何优化?
2.在Hibernate中进行多表查询,每个表中各取几个字段,也就是说查询出来的结果集并没有一个实体类与之对应,如何解决这个问题?
3.session.load()和session.get()的区别
4.Session在加载实体对象时,将经过的过程:
5.Hibernate的主键生成机制
=====================Hibernate笔试题==========================
(1)一般情况下,关系数据模型与对象模型之间有哪些匹配关系(多选)
A)表对应类
B)记录对应对象
C)表的字段对应类的属性
D)表之间的参考关系对应类之间的依赖关系
(2)以下关于SessionFactory的说法哪些正确?(多选)
A)对于每个数据库事务,应该创建一个SessionFactory对象
B)一个SessionFactory对象对应一个数据库存储源。
C)SessionFactory是重量级的对象,不应该随意创建。如果系统中只有一个数据库存储源,只需要创建一个。
D)SessionFactory的load()方法用于加载持久化对象
(3)Customer类中有一个Set类型的orders属性,用来存放Order订单对象,在Customer.hbm.xml文件中,用哪个元素映射orders属性?
A)<set> B)<one-to-many> C)<many-to-one> D)<property>
(4)<set>元素有一个cascade属性,如果希望Hibernate级联保存集合中的对象,casecade属性应该取什么值?(单选)
A)none
B)save
C)delete
D)save-update
(5)以下哪些属于Session的方法?
A)load()
B)save()
C)delete()
D)update()
E)open()
F)close()
(6)以下程序的打印结果是什么?(单选)
tx = session.beginTransaction();
Customer c1=(Customer)session.load(Customer.class,new Long(1));
Customer c2=(Customer)session.load(Customer.class,new Long(1));
System.out.println(c1==c2);
tx.commit();
session.close();
A)运行出错,抛出异常
B)打印false
C)打印true
(7)以下程序代码对Customer的name属性修改了两次:
tx = session.beginTransaction();
Customer customer=(Customer)session.load(Customer.class,
new Long(1));
customer.setName(\"Jack\");
customer.setName(\"Mike\");
tx.commit();
执行以上程序,Hibernate需要向数据库提交几条update语句?(单选)
A)0 B)1 C)2 D)3
(8)在持久化层,对象分为哪些状态?(多选)
A)临时状态
B)独立状态
C)游离状态
D)持久化状态
(9)对于以下程序,Customer对象在第几行变为持久化状态?(单选)
Customer customer=new Customer(); //line1
customer.setName(\"Tom\"); //line2
Session session1=sessionFactory.openSession(); //line3
Transaction tx1 = session1.beginTransaction(); //line4
session1.save(customer); //line4
tx1.commit(); //line5
session1.close(); //line6
A) line1 B)line2 C)line3 D)line4 E)line5 F)line6
(10)对于以下程序,Customer对象在第几行变为游离状态?(单选)
Customer customer=new Customer(); //line1
customer.setName(\"Tom\"); //line2
Session session1=sessionFactory.openSession(); //line3
Transaction tx1 = session1.beginTransaction(); //line4
session1.save(customer); //line4
tx1.commit(); //line5
session1.close(); //line6
A) line1 B)line2 C)line3 D)line4 E)line5 F)line6
(11)以下哪一种检索策略利用了外连结查询?(单选)
A)立即检索 B)延迟检索 C)迫切左外连结检索
(12)假设对Customer类的orders集合采用延迟检索策略,编译或运行以下程序,会出现什么情况(单选)
Session session=sessionFactory.openSession();
tx = session.beginTransaction();
Customer customer=(Customer)session.get(Customer.class,new Long(1));
tx.commit();
session.close();
Iterator orderIterator=customer.getOrders().iterator();
A)编译出错 B)编译通过,并正常运行 C)编译通过,但运行时抛出异常
(13)关于HQL与SQL,以下哪些说法正确?(多选)
A)HQL与SQL没什么差别
B)HQL面向对象,而SQL操纵关系数据库
C)在HQL与SQL中,都包含select,insert,update,delete语句
D)HQL仅用于查询数据,不支持insert,update和delete语句
(14)事务隔离级别是由谁实现的?(单选)
A)Java应用程序 B)Hibernate C)数据库系统 D)JDBC驱动程序
(15)悲观锁与乐观锁,哪个具有较好的并发性能?(单选)
A)悲观锁 B)乐观锁
答案:
(1)A,B,C (2)B,C (3)A (4)D (5)A,B,C,D,F (6)C (7)B (8)A,C,D (9)D (10)F (11)C (12)C (13)B,D (14)C (15)B
发表评论
-
Hibernate和EhCache整合
2015-05-11 13:11 890首先是pom.xml,这里面有一些dependenc ... -
spring struts2 hibernate ehcache整合
2015-05-06 12:17 1374这里主要是为了使用ehcache,具体表现就是我们显 ... -
hibernate 注解和xml配置入门
2013-09-18 11:02 2012下面使用学生-课程为例: 首先是使用注解的方 ... -
项目中DAO的结构实现
2013-09-16 17:39 1657首先是定义基础DAO接口: pa ... -
myeclipse 逆向工程生成根据数据表生成映射文件,javaBean,hibernate.cfg.xml
2013-08-12 09:23 1811首先,在myeclispe右上角切换到myeclipse D ... -
通过src调用客户端,将两个&改为一个&
2013-06-19 20:49 0的 -
hibernate配置
2013-06-12 18:09 834首先是hibernate.cxf.xml: <?xm ... -
总结一下这次用ajax/json实现SSH
2013-03-20 16:16 4695首先最简单的来说: 引入struts2-json-plu ... -
hibernate 表关联 多对一 一对多 多对多 注解 xml 马士兵 笔记
2013-01-31 17:21 4787首先是xml文件配置 ... -
使用hibernate中的UserType解决乱码问题
2013-01-18 16:08 1555转自:http://hi.baidu.com/gacmot ... -
hibernate配置自动插入当前时间
2012-12-26 11:04 1483http://blog.sina.com.cn/s/blog_ ... -
hibernate 注解 收藏
2012-12-14 14:39 1237一般情况下,注解@cascad ...
相关推荐
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是一种在Java环境下使用的对象关系映射(ORM)框架,它能够将Java类映射到数据库表,并管理Java应用中的对象关系与SQL数据库之间的转换。Hibernate的主要目标...
### 学习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,开发者可以构建更高效、更易于维护的...