首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件架构设计 >

Hibernate 概述 札记

2012-12-09 
Hibernate 概述 笔记hibernate三种查询:标准化查询hql原始sql查询from user user where user.name like 'j

Hibernate 概述 笔记

hibernate三种查询:

标准化查询
hql
原始sql查询

from user user where user.name like 'j%'

可以运用对象的导航技术,少了连接查询的麻烦

user.group.name=?

关键字不区分大小写

select name from student实体是需要区分大小写的.
简单属性的查询,返回的类型取决于属性的类型.
List a;
for(Iterator it = a.iterator();it.hasNext()){


查询多个属性,集合元素是对象数组
长度取决于属性个数.

select new Student(id,name) from Student
这里需要注意在实体里加入响应的构造函数.这里返回的是Student对象实体.可以使用别名.可以有as关键字.

from Student s

使用select查询实体对象必须采用as

select s from Student as s
select * from Student(实体)
这是不对的.但是可以使用count(*)

n+1问题损耗性能.(query.iterator)
1是指查询ID的select的语句
之后是根据ID发出select语句,迭代接口会利用缓存,即缓存存在时候不会发出select语句.

list只会往缓存放数据,不会使用缓存.所以多次查询都会重新发送sql,除非配置了查询缓存.

外置命名查询,这样sql是可配置的.具体放在vo的映射文件里头.
<query name="">
<![CDATA[from User]]>可以放到任意的映射文件里头
</query>


还可以在映射文件里加入过滤器查询条件
可以通过字符串的拼接方式,也可以使用占位符的方式.
方法连的查询是直接通过导航的形式.
也可以使用冒号的形式传递参数 like:myname
in(:aa)
setParamList("aa",new Object[]{1,3,3})


hibernate不太适合批量的操作,主要是缓存的数据和数据库的不一致.

分布式缓存比较麻烦.需要通过一定的方式同步数据
load和get会使用缓存
迭代查询普通属性,一级缓存不起作用,因为是缓存实体对象的.

load得到的是代理,使用时才发出sql语句.
session间不能共享缓存的数据,因为缓存伴随session的生命周期而存在.
save时会使用缓存.

session.clear()或者evict()方法(可以指定驱逐特定的对象,clear清楚所有缓存)
一级缓存无法实现自动分配.必须通过以上2种方法.

数组可以在声明时指定长度,但是内存中没有分配.当使用静态初始化时,即声明时立刻赋值,就不能在声明的内部指定长度.多维数组可以作同样的考虑.

session缓存也叫事务级缓存.

?

?

一对多和多对一映射是一致的,都是在多的一端加入字段.主要的差别是加载时查询级联数据有些不同.

hihernate一对多关联映射(单向Classes----->Student)

一对多关联映射利用了多对一关联映射原理

多对一关联映射:在多的一端加入一个外键指向一的一端,它维护的关系是多指向一
一对多关联映射:在多的一端加入一个外键指向一的一端,它维护的关系是一指向多

也就是说一对多和多对一的映射策略是一样的,只是站的角度不同

在一一端维护关系的缺点:
?* 如果将t_student表里的classesid字段设置为非空,则无法保存
?* 因为不是在student这一端维护关系,所以student不知道是哪个班的,
?? 所以需要发出多余的update语句来更新关系

?

<hibernate-mapping package="com.bjsxt.hibernate">
?<class name="Classes" table="t_classes">
??<id name="id">
???<generator constrained="true"/>


唯一外键关联时需要在一端多加入一个字段.他是多对一的一个特例,只需在多的一端的多余字段的唯一性设置为true就可以.

hibernate一对一唯一外键关联映射(单向关联Person---->IdCard)

一对唯一外键关联映射是多对一关联映射的特例

可以采用<many-to-one>标签,指定多的一端的unique=true,这样就限制了多的一端的多重性为一
通过这种手段映射一对一唯一外键关联

hibernate一对一唯一外键关联映射(双向关联Person<---->IdCard)

一对一唯一外键关联双向,需要在另一端(idcard),添加<one-to-one>标签,指示hibernate如何加载
其关联对象,默认根据主键加载person,外键关联映射中,因为两个实体采用的是person的外键维护的关系,
所以不能指定主键加载person,而要根据person的外键加载,所以采用如下映射方式:
<one-to-one name="person" property-ref="idCard"/>

?


领域模型,即对象模型
sessionFactory是线程安全的.session是非线程安全的.一个session的生命周期对应一个请求的业务操作.
只对一个数据库操作,称之为本地事务.
对于跨数据库的访问,需要用到JTA.

get查询对象不存在时返回null.不支持懒加载.
load调用时生成的是代理,真正使用时才发出sql语句.这就是延迟加载.其原理是代理方式.

load方法,当数据库不存在相应的数据时,查询的操作就会出现异常.

理解对象的状态,需要抓住三点,session的边界,对象,数据库是否存在记录

update时没有赋值的字段成为了null.所以做好先load上来.

测试实体对象的生命周期

junit简介:
?* 编写测试类xxxTest,需要继承TestCase
?* 编写单元测试方法,测试方法必须以test开头,测试方法不能含有参数和返回值,如:
?? public void testHello1() {}
?* 最好单元测试的代码单独建立一个目录
?
了解Hibernate中CRUD操作

了解get和load的区别?
?* get不支持lazy,load支持lazy
?* 采用get加载数据,如果没有匹配的数据,返回null,而load则抛出异常
?
transient状态的特征?
?* 在数据库中没有与之匹配的数据
?* 没有纳入session的管理
?
persistent状态的特征?
?* persistent状态的对象在数据库中有与之匹配的数据
?* 纳入了session的管理
?* 在清理缓存(脏数据检查)的时候,会和数据库同步
?
detached状态的特征?
?* 在数据库中有与之匹配的数据
?* 没有纳入session的管理? ??
?
?orm 的m是map包括映射机制和缓存机制 ,maping只是一个简单的映射,范围比较小.

轻量级框架测试比较简单.EJB是重量级的,测试的时候要继承一些框架的接口,需要专门的部署,需要注册到JNDI对象树上,使用时还需要查找,很是麻烦.

可以建立jar库,此后不用每次进行相同的加入jar的操作.右键工程--properties--java--buildbath--user liberaris 

hibernate项目配置顺序

1、新建java项目

2、创建User Library,加入如下jar
?* HIBERNATE_HOME/hibernate3.jar
?* HIBERNATE_HOME/lib/*.jar
?* MySql jdbc驱动
?
3、创建hibernate配置文件hibernate.cfg.xml,为了便于调试最好加入log4j配置文件.里面是连接数据所需要的属性配置.

<hibernate-configuration>
<session-factory>
<properties name="">
</hibernate-configuration>
</session-factory>

其中还可以配置一个数据库语言适配器,通过hibernate的api能够自动翻译成合数据库相关的语句

4、定义实体类

5、定义User类的映射文件User.hbm.xml,一般放在一起.
主键需要配置生成策略.实体的属性与数据库字段有一定的映射机制.

6、将User.hbml.xml文件加入到hibernate.cfg.xml文件中
需要放到<propertis>属性映射的后面

7、编写hbm2ddl工具类,将实体类生成数据库表

package com.bjsxt.hibernate;

import org.hibernate.cfg.Configuration;
import org.hibernate.tool.hbm2ddl.SchemaExport;

public class ExportDB {

?public static void main(String[] args) {
??
??//读取hibernate.cfg.xml文件
??Configuration cfg = new Configuration().configure();//不调用configure方法时默认就调用properties文件.
??
??SchemaExport export = new SchemaExport(cfg);
??
??export.create(true, true);//
第一个true表示打印ddl语句.第二个true表示将脚本导入到数据库里.
?}
}
一个数据库对应一个sessionfactory;

Configuration cfg = new Configuration().configure();
??
??//创建SessionFactory
??SessionFactory factory = cfg.buildSessionFactory();

8、开发客户端
?
为了方便跟踪sql执行,在hibernate.cfg.xml文件中加入<property name="hibernate.show_sql">true</property>

hibernate的事务自动提交是false
session.beginTransaction();//手动开启事务
???
???User user = new User();
???user.setName("张三");
???user.setPassword("123");
???user.setCreateTime(new Date());
???user.setExpireTime(new Date());
???
???//保存数据
???session.save(user);
???
???//提交事务,需要得到事务的上下文
???session.getTransaction().commit();


session.getTransaction().rollback();//出现问题时回滚.

?

项目的分层:表示层-struts,
业务层-spring
持久层应该是透明的-hibernate(01年就出现了)
数据库

各层之间的依赖一般都是通过抽象进行的,抽象是一种规范,所以变化比较小.

数据若只是保存到磁盘文件上,一些事物操作就不存在,并发的问题也就无从解决.

没有h,很多jdbc语句都要自己写,而且很多都是重复.开发效率不高.

对象的继承关系,关系数据库里没有与之对应的概念.这叫做阻抗不匹配.

和h差不多的框架有:apache OJB,sun提出的一套标准--JDO,oracle提出的TOPLink,ibatis(只是对sql进行了轻量级的包装,严格意义上不属于orm框架)

h的优点:sql大部分不用写,直接操作对象.提高生产力,开发更为对象化,移植性很好(只需要更改配置),实现了透明持久化,无须继承h的任何类和任何接口,保存的对象是一个POJO对象,即没有任何的侵入性,属于轻量级的第三方框架.

适用情况:
简单对象的查询和修改.
批量的修改则不适合,主要是和缓存有关.

对象之间的关系复杂时不适合,

当要求使用数据库的特殊功能时也不适合. 因为sql是h自动生成的.所以实现的功能是比较有限的

热点排行