Hibernate学习笔记

作者 Administrator 创建于2014-10-29 12:08:00 修改者wuqingman 修改于2021-01-27 08:19:00字数8528
文档摘要:Hibernate是一种orm 工具,O(object是Java中的对象)、R(relation是关系——关系型数据库中的数据)、M(mapping是映射),将数据库中的数据和内存中的Java的面向对象的数据进行数据之间的映射的工具。
关键词:
一、Hibernate介绍 Hibernate是一种orm 工具,O(object是Java中的对象)、R(relation是关系——关系型数据库中的数据)、M(mapping是映射),将数据库中的数据和内存中的Java的面向对象的数据进行数据之间的映射的工具。 对比: 使用了ORM之后,会使代码更为简洁 二、安装hibernate 1、引入jar包:Hibernate 4.1.4 Libraries 2、将hibernate.cfg.xml引入项目的src目录下 3、使用hibernate将对象保存到数据库表中,使用hibernate为相关类和相关表建立一个映射文件(xml文件) 将该.xml文件取名为:若是:xxx类 <=> xxx.hbm.xml 后缀* 必须掌握知识点: 1、使用hibernate的步骤 step1:搭建环境,配置全局的hibernate.xml文件 oracle.jdbc.driver.OracleDriver jdbc:oracle:thin:@127.0.0.1:1521:orcl scott tiger org.hibernate.dialect.Oracle10gDialect true step2:连接数据库 step3:在Java文件中: //使用hibernate中的Configration //1、 创建一个读取配置文件的对象 Configuration cfg= new Configuration(); //2、默认读取hibernate.cfg.xml文件 cfg.configure(); //3、获取SessionFactory,session代表和数据库的一次连接<=> jdbc中的connection //注:Factory的存在十分重要,并且其实例对象只会有一个 SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory (); //可以一次写成匿名对象 //如果要指定读取摸个hibernate.xml文件,可以写为:configure("a/b/hibernate.xml") //4、获取到数据库的连接,基于session对数据库进行增删改查 Session session = sessionFactory.openSession(); //打开会话 Transaction tr= null; try {//开启事务 tr= session.beginTransaction(); /** * 在此处对数据进行一组增删改查操作 */ //提交事务 tr.commit(); } catch (Exception e) { //出现异常的时候进行回滚 tr.rollback(); } finally{ if(session!= null){ session.close(); //关闭会话 } } 2、save、saveorupdate、update 的区别 2.1 session.save(对象):向数据库中插入数据,但是必须确定该对象在数据库中一定不存在,否则报错。 2.2 session.update(对象):对数据库中已有的数据进行更新修改,但是必须提前确保该对象在数据库中一定存在,否则报错。 2.3 session.saveorupdate(对象):向数据库中插入数据,如果已经存在则进行更新操作覆盖原来存在的值,如果数据库中还没有改对象的数据,则插入新数据。 注:使用saveorupdate之后,软件的容错性更好,也更健壮 3、使用get()和load()方法的区别: 3.1 session.get(类名.class,主键):使用get()查询出的学生对象,如果主键编号在数据库中没有,返回的对象是null;如果库中存在对应主键的数据,则会在对象被调用之前将数据查询出来并将查出的数据放在某个类中。 3.2 session.load(类名.class,主键):使用load()查询数据时,会延迟加载,即:将数据库中的数据加载到对象中延迟到使用该对象的时候才做 4、配置文件: 4.1 configration:是与全局配置文件相关 4.2 mapping:与单个类的映射文件相关 三、主键生成策略 1、适用情况:数据库中的表已经设置了主键自增长,向其中插入数据 < generator class= "sequence" > 注:主键必须为整型数 1.1 新建表:设置主键自动增长(使用Oracle来实现) -- 建立表 create table Book( bid number primary key , bname varchar2( 20)not NULL ); -- 设设置自增长序列 CREATE SEQUENCE emp_sequence2 INCREMENT BY 1 -- 每次加几个 START WITH 1 -- 从1开始计数 NOMAXVALUE -- 不设置最大值 NOCYCLE -- 一直累加,不循环 NOCACHE -- 不建缓冲区 -- 设置触发器,每当向该表中插入数据的时候,实现主键自动增长 create OR REPLACE trigger mem_trig before insert on Book for each row when (new.bid is null ) begin select hibernate_sequence.nextval into:new.bid from dual; end; 1.2 新建mapping文件 2、适用情况:在数据库中表没有设置自增长,但是希望插入后的数据实现手动自增长 使用: increment.hibernate < generator class ="increment"> 3、适用情况:数据库中的表主键设置的是自动增长,但是想要实现自己手动插入非自增长的主键值,可以覆盖自动增长 4、使用情况:希望该表的主键是随机生成的32为随机数 使用:uuid < generator class ="uuid"> 四、联合主键 1、建立具有联合主键的表:person(cid,sid,sname) Oracle实现 CREATE TABLE Student( c_id VARCHAR2( 10) , s_id VARCHAR2( 10) , s_name VARCHAR2( 20) NOT NULL , CONSTRAINTS Student_pk PRIMARY KEY (c_id,s_id) --创建复合主键 ); 2、建立主键类:要实现序列化接口! 3、表建立该表的类:拥有主键类的实例 public class Student { PK_Student pk; String name; } 4、配置mapping文件 5、在测试类中调用该复合主键来查询: PK_Student pk= new PK_Student( "u01", "lovo001");//设置主键,并为主键赋值 Student s = (Student) session.get(Student.class, pk); 五、myeclipse中使用hibernate逆向工程(使用工具自动生成数据库表相应的bean和.xml配置文件) 5.1 让MyEclipse连接到数据库,建立新的数据库驱动: 右键单击,新建: 5.2 建立hibernate逆向工具 六、在session使用SQL语句来获取数据 6.1 获取session的几种方法: · session.openSession()方法:每调用一次就会打开一次到数据库的连接 · session.getCurrentSession()方法:获取和当前线程绑定的session · Session session=HibernateSessionFactory.getSession();(常用) 其中: session是和数据库的一次连接,在一次连接中,只要session没有close(),就可以反复的执行多条SQL语句,来完成一次业务逻辑。 6.2 在session中使用标准的SQL语句来查询: session.createSQLQuery(标准SQL语句) · 获取单列(需要明确知道该列的数据类型) List list = session .createSQLQuery("select ENAME from emp") .list(); · 获取单值 String s= session.createSQLQuery("select ENAME from emp").uniqueResult(); · 查询多列 (可以将多列同时查询出来放到一个对象数组中) List 优点:节约内存; 缺点:第一次使用的时候比较慢 (像jsp、servlet只在使用的时候才会被编译 ) 3、实现增删改数据 int r = session .createSQLQuery("DML语句对数据库中的数据进行增删改") .executeUpdate(); System. out.println(r); 常见问题小结: 1、双向一对多的序列化死循环问题: 解决方案:改为单向一对多、使用transient禁止导致死循环的属性序列化,并且在mapping文件中去掉many-to-one映射关系 2、hibernate默认懒加载会报500错误 解决方案:多方中添加lazy="false" 九、hibernate缓存(一、二级缓存) 9.1 缓存 · 定义 :从数据库中查询出的数据在第一次查询出来的时候,保存在内存中,下次再查询的 时候,会直接去缓存中查询,不去数据库中查找。 · 应用:计算机的内存对操作系统来说,就是缓存,计算机运行速度的瓶颈就是IO,和硬件打交道的时候。 · orm框架,实际上是使用其缓存技术,以提高查询速度,并且该缓存技术对程序员来说是透明的。 优点:提高查询速度,减少数据库的访问量,数据库是保存在硬盘上的文件系统。 缺点:当数据发生改变的时候,使用缓存不能使数据即时的更新,数据不是实时更新的 · 如何使用缓存: 1、缓存的大小设置 2、缓存策略: 2.1 先进先出策略 2.2 最少使用策略 注:Hibernate已经实现了以上的缓存策略 9.2 Hibernate的分级缓存 · 一级缓存:即session缓存,是Hibernate自带的,默认状态为开启状态(查询数据时先到session中查找,如果没有该条数据则向数据库发出查询语句,得到查询结果,并放入session中) 例如:session.get(Student.class,"lovo001"); · · 注:不同的session不能共享缓存空间,在不同session中的对象即时内容相同,也归为不同的对象 · 清空缓存:clear();不是将数据销毁,而是引用指针不在指向该数据 · 二级缓存:在jvm中所有session共享缓存 · o 二级缓存使用第三方技术,需要在cfg.xml文件中配置 o 二级缓存默认为关闭状态 o 工作方式: o § 先到一级缓存session中查找,找不到再到二级缓存中找,也找不到的时候,在发出数据库查询,找到数据 9.3 Hibernate 的缓存刷出 事务提交时,将会与数据库中的数据进行同步 十、Hibernate中对象的三种状态 · 瞬态(transient):刚刚new出来的实例对象,Java内存中有该对象,但是数据库、session中都没有该对象的数据。 · 持久态(persistent):执行session.save()之后,Java内存中有该对象数据,session、数据库中都有该对象的数据。 · 脱管态(detached):脱离session(缓存)的管理之后,session中没有、数据库中有该对象的数据,可能出现这种状态的情况: · o session关闭 o session缓存被clear() 清空所有的对象 o session.evict(); 是清空指定对象 例如:save():仅限用于保存瞬态的对象 十一、并发和事务 1、并发 · 数据库原生的并发——锁 · hibernate封装之后的并发——乐观锁、悲观锁 · o 特点:悲观锁(给表加锁):获取数据之后加锁,使其他用户等待;乐观锁(给表加一个版本号):通过版本号的变动来查看当前操作是否有误 十二、抓取策略(提升性能) 本文档由深度开源(https://www.open-open.com)用户上传