1、hibernate介绍与动手入门体验
* hibernate.cfg.xml中必须配置的几个属性:(可以参考eg文件夹和etc文件夹下的配置
文件)
driver_class; 数据库驱动
url;
username;
password;
dialect;数据库方言
resource; 与对象对应的配置文件
hbm2ddl.auto;是否自动生成表
* show ENGINE; 能查看ENGINE,就是数据库设置的事物类型;
* 测试主程序:
Configuration cfg = new Configuration(); //初始化配置文件
cfg.configure();
SessionFactory sf = cfg.buildSessionFactiory(); //新建SessionFactory
Session se = sf.openSession(); //创建Session
* 默认情况下事务是关闭的;
2、hibernate入门案例的细节分析
* 开发流程
Domain object->mapping->db(官方推荐)
db->mapping->Domain object(使用较多)
* 必须有不带参数的构造方法;
* 如果java对象那个属性不需要存入数据库,那么在heibernate映射文件就不需要配置这
个属性;
3、hibernate入门案例的代码优化
* 加载配置文件最好写成单例模式
* src 目录并不是classpath,src编译之后的目录能把文件放入classpath 中
4、Session接口及get-load-persist方法
* 每个类其实也都是Class 的实例;
* load有懒加载特性;
* session的persist和save方法的区别:在未开启事务时persist不会插入数据;save会
先插入数据,然后回滚删除数据;
5、实体对象的三种状态与saveOrUpdate方法
* 三种状态:瞬时、持久、游离(脱管);
可以从session理解:对象新建出来时就是瞬时状态,进入session则是持久状态,
session关闭则是脱管状态;
也可以从跟数据库关系理解:新建对象是和数据库没有关系的就是瞬时状态,数据库有
记录且跟session有关系的就是持久状态,数据库有数据但和session没有关系就是脱管状
态;
* 如果不知道对象是什么状态可以用saveOrUpdate()方法;
6、hql的命名参数与Query接口的分页查询
* Query qr = s.createQuery("select o from User o where o.name =
? and o.id =? ");
qr.setParameter(0, "jim");
qr.setParameter(1, 1);
或者重命名?(占位符)
Query qr = s.createQuery("select o from User o where o.name =
:n and o.id = :i ");
qr.setParameter(n, "jim");
qr.setParameter(i, 1);
14、多对一关联关系的映射与原理分析
* 保存时尽量先保存一的一端,再保存多的一端,否则会多出update的操作
* 单双向其实体现在:domain中的bean是否有对应属性和配置文件中
25、Hibernate中使用的集合类型
* 集合映射(set\list\array\bag\map)
* 集合的简单实用原则:大部分情况下使用set,需要保证集合中的顺序用list,想用
list有不需要保证顺序用bag;
* 实体中的集合必需用接口定义,不能定义成具体类,因为集合在运行时会被替换成
Hibernate的是实现:如
private Set<Employee> emps;//正确
private HashSet<Employee> emps;//错误 不能定义为具体类,因为HIbernate中会对
Set转型,会报错。 HashSet hs = (HashSet) depart.getemps();会报错
26、关联关系的级联操作
* 级联发生在对象关系上(即检索时用);
* 常用 级联关系:none、all(同生同死)、save-update、delete、delete-orphan
(one-to-many);
* 一般对many-to-one,many-to-many不设置级联,one-to-one,one-to-many中设置
级联;
27、inverse属性的作用与原理分析
* 只存在在集合关系上如set list等
* 为防止1对n 问题的产生(产生n条更新语句),一般在one的一端关系上进行
inverse="true",让one的一端放维护关系,让many一端维护关系;
* 保存数据的时候先保存one的一端,再保存many端,这样可以避免1对n问题的产生;
* list中不能用inverse="true"属性,多的一端没有inverse属性
32、继承关系_每个具体类映射一张独立表
* 这种情况生成的表的id不能重复,所以主键生成器不能用自增长了
33、load方法的懒加载及原理分析
* 懒加载
* load方法举例:
User u = (User)s.load(User.class,1);//返回的对象u是个代理对象,继承了User,
所以User不能设置为final;
* 懒加载返回的对象只能在session关闭之前访问数据库,要想在session关闭后也能访问
可以把返回对象初始化,Hibernate.initialize(u);
* 集合查询默认也是lazy="true"的,所以要想在外部调用查询集合必须把lazy="false"
35、一对多和多对多的懒加载分析
* 比如访问depart时,Hibernate不会去查找employee,这就是因为Hibernate默认使用了
懒加载lazy="true";
* 如果初始化对象就会去查找employee
* one-to-one 要想实现懒加载必须加上constraint="true"
39、hibernate的内部缓存分析
* 缓存作用用来提高性能,可以简单的理解成一个map;
* Session是一级缓存;
* get\load\update会从一级缓存读取数据;query会将数据放入一级缓存,但不会读取一
级缓存,query能读取二级缓存;
* 一级缓存数量不可以控制,要防止内存溢出,可以用evict(object),clear()清除缓存
;
?????如果开启了二级缓存,load的对象在外部是否可以调用??不可以
42、分布式缓存的分析与研讨
* 分布缓存集群和中央缓存
44、OpenSessionInView模式的代码分析
* ThreadLocal 类似于一个map, key 是当前线程;如果把一个Session加入 一个
TreadLocal对象中,则在这个线程内可以共享这个session 对象,避免反复获取Session
;
* Open session in view :在生成页面时保持session处于打开状态;可以解决:事物边
界问题和懒加载问题
* Open session in view 缺陷:增长了事物开启时间,session的生命周期增长;
* Session 不释放缺陷:系统内存被占用;Session不关闭不会释放数据连接,影响并发
;
* UUID移植性好,不访问数据库;
50、
* Session是非线程安全的;在b/s系统中一般不会超过一个请求;如果长时间打开会占用
内存和数据库连接;
* SessionFactory是线程安全的,一个数据库对应一个SessionFactory,什么周期长,一
般在整个系统生命周期内有效;
* flush()保证一级缓存和数据库进行同步;
* 在大批量数据操作样例:
for(int i=0;i<100000;i++){
session.save(obj);
if(i%==0){
session.flush();
session.clear();
}
}
下面的方式也行:
Query q = s.createQuery("update u set birthday = :bd from User u");
q.executeUpdate();
53、iterate查询与N+1此查询问题
* 使用iterate()出现n+1次问题,用list呢????list在不存在关联查询(懒加载情况
)的情况不会产生此问题;
* 懒加载情况也会产生n+1次问题。
* ctr+t查看方法在实现类中的情况;
55、
* 本地化查询样例:
//加上ddEntity(User.class)返回对象,否则返回对象数组
Query q = s.createSqlQuery("select * from user").addEntity(User.class);
List rs = q.list();
for(User u: rs){}
56、
* 不适合OLAP(On-Line Analytical Processing 联机分析处理),以查询为主的系统;适
合OLTP(on-line transaction procession)联机事务处理;
* 不适合关系模型设计不合理的老系统;
* 数据量巨大,性能要求苛刻的系统不适合,应为Hibernate批量操作数据的效率不高;