收藏 分享(赏)

韩顺平 hibernate笔记.doc

上传人:精品资料 文档编号:11001640 上传时间:2020-01-30 格式:DOC 页数:35 大小:455KB
下载 相关 举报
韩顺平 hibernate笔记.doc_第1页
第1页 / 共35页
韩顺平 hibernate笔记.doc_第2页
第2页 / 共35页
韩顺平 hibernate笔记.doc_第3页
第3页 / 共35页
韩顺平 hibernate笔记.doc_第4页
第4页 / 共35页
韩顺平 hibernate笔记.doc_第5页
第5页 / 共35页
点击查看更多>>
资源描述

1、 hibernate 是什么?1. hibernate 是一个框架(framework)2. hibernate 是一个 orm 框架 orm (object relation mapping) 对象关系映射 框架o object - 业务层(只对对象操作)r relation- 关系数据库m mapping 对象关系映射文件3. hibernate 处于我们项目的持久层位置( 正因为如此,所以有人又把 hibernate 称为 持久层框架)4. hibernate 实际上就是对 jdbc 进行了轻量级的封装.5. hibernate 的基础还是我们 java 反射机制 除了 hiberant

2、e 这个 orm 框架,还有一些:apache ojb / toplink / ibatis / ejb cmpApache OJB () Cayenne () Jaxor () Hibernate () iBatis () jRelationalFramework () mirage () SMYLE () TopLink () 把对象持久化: 把对象的信息保存到数据库或者是文件 .总结: hibernate 是对 jdbc 进行轻量级封装的 orm 框架,充当项目的持久层. 为什么需要 hibernate? 快如入门案例:hiberante 可以用在 j2se 项目,也可以用在 j2ee

3、(web 项目中 )struts 是 web 框架,所以用在 web 项目我们使用手动配置 hibernate 方式开发一个 hibernate 项目,完成 crud 操作 。开发流程1. 创建一个项目2. 画出一个简单项目框架示意图3. 引入 hibernate 开发包 (从网上下载 google hibernate http:/www.hibernate.org),完后我们4. 开发 hibernate 有三种方法(开发顺序)我们使用第二种开发项目创建 employe 表.create table employee(id number primary key,name varchar2(6

4、4) not null,email varchar2(64) not null,hiredate date not null)创建一个序列,将来用于主键的自增长 :-创建一个序列create sequence emp_seqstart with 1increment by 1minvalue 1nomaxvaluenocyclenocache5. 开发 domain 对象和对象关系映射文件对象关系映射文件: 作用是用于指定 domain 对象和表的映射关系. ,该文件的取名有规范:domain 对象.hbm.xml, 一般我们放在 和 domain 对象同一个文件夹下(包下)我们的 Emplo

5、yee.hbml.xml 配置文件 :emp_seq6. 手动配置我们的 hibernate.cfg.xml 文件,该文件用于配置 连接的数据库的类型,driver,用户名,密码 ,url 同时管理 对象关系映射文件 ,该文件的名称,我们一般不修改.hibernate.cfg.xml 配置文件oracle.jdbc.driver.OracleDriverscotttigerjdbc:oracle:thin:127.0.0.1:1521:orclhsporg.hibernate.dialect.OracleDialecttrue7. 测试文件 TestMain.javapackage com.h

6、sp.view;import com.hsp.util.*;import java.util.Date;import org.hibernate.Session;import org.hibernate.SessionFactory;import org.hibernate.Transaction;import org.hibernate.cfg.*;import com.hsp.domain.Employee;public class TestMain /* param args*/public static void main(String args) /查询load-hql 语句 (hi

7、bernate query language)public static void delEmp() /删除/获取一个 sessionSession session=MySessionFactory.getSessionFactory().openSession();Transaction ts=session.beginTransaction();/删除 1.先获取该雇员,然后删除Employee emp=(Employee) session.load(Employee.class, 3);session.delete(emp);mit();session.close();public st

8、atic void updateEmp() / TODO Auto-generated method stub/修改用户/获取一个会话Session session=MySessionFactory.getSessionFactory().openSession();Transaction ts=session.beginTransaction();/修改用户 1. 获取要修改的用户,2.修改/load 是通过主键属性,获取该对象实例.表的记录对应Employee emp=(Employee) session.load(Employee.class, 3);emp.setName(“韩顺平 8

9、“);/update.emp.setEmail(““);mit();session.close();public static void addEmployee() /我们使用 hibernate 完成 crud 操作 这里我们只见对象,不见表/现在我们不是用 service ,直接测试./1。创建 Configuration,该对象用于读取 hibernate.cfg.xml,并完成初始化Configuration configuration=new Configuration().configure();/2.创建 SessoinFactory这是一个会话工厂,是一个重量级的对象 Sess

10、ionFactory sessionFactory=configuration.buildSessionFactory();/3.创建 Sessoin 相当于 jdbc Connection servelt HttpSession ,也不是 jsp sessionSession session=sessionFactory.openSession();/4.对 hiberate 而言,要求程序员,在进行 增加,删除,修改的时候使用事务提交,Transaction transaction = session.beginTransaction();/添加一个雇员Employee employee=

11、new Employee();employee.setName(“shunping“);employee.setEmail(““);employee.setHiredate(new Date();/insert ./保存session.save(employee);/save employee 就是持久化该对象 (把对象保存到了数据库中称为一条记录)/=insert into 被 hiberante 封装/提交mit();session.close(); 现在我们体验一下 hibernate 切换数据库的优势.这次,我们使用 让 hibernate 自动完成 domain-映射文件-表 的工作

12、.1. 首先我们把 hibernate.cfg.xml 文件重新配置.com.mysql.jdbc.Driverrootrootjdbc:mysql:/localhost:3306/testorg.hibernate.dialect.MySQLDialecttruecreate2. 对对象映射文件,做了相应的修改.笔试题: 请列举出 hibernate 常见的接口和类?请解释什么事 pojo 类,它有什么要求:1. pojo 类是和一张表对应2. 一般我们放在 com.xxx.domain 下3. pojo 需要一个主键属性(用于标示一个 pojo 对象)4. 除了主键属性外,它应当还有其属性

13、,属性的访问权限是 private5. 提供 set /get 方法6. 它应当有一个无参的构造方法(hibernate 反射)7. pojo 类其实就是 javabean/ 有些老程序员 叫他 date 对象上机练习:写一个简单的雇员管理系统.emp( id , name , tel , birthday ),可以,进入主界面请选择数据库类型1. 表示 连接 oracle2. 表示 连接 mysql3. 表示 连接 sql server请选择操作1. 显示所有雇员2. 根据 id 查询指定雇员3. 修改雇员信息(请先输入 id)4. 根据 id 删除雇员.* 用户可以多次选择操作.PHP 是

14、目前 web 编程第一语言,欢迎下载韩顺平老师最新力作 PHP 视频教程,详情查看 http:/ hibernate 的核心类和接口 Configuration 类它的用处是:1. 读取 hibernate.cfg.xml2. 管理对象关系映射文件 3. 加载 hibernate 的驱动,url ,用户4. 管理 hibernate 配置信息 hibernate.cfg.xml 对象关系映射文件 SessionFactory (会话工厂)1. 可以缓存 sql 语句和数据 (称为 session 级缓存)!2. 是一个重量级的类,因此我们需要保证一个数据库,有一个 SessionFactroy

15、这里我们讨论一个通过 SessionFactory 获取 Session 的两个方法 openSession() 一个 getCurrentSession();1. openSession() 是获取一个新的 session2. getCurrentSession () 获取和当前线程绑定的 session,换言之,在同一个线程中,我们获取的 session 是同一session,这样可以利于事务控制如果希望使用 getCurrentSession 需要配置 hibernate.cfg.xml 中配置.3. 如何选择原则:如果需要在同一线程中,保证使用同一个 Session 则,使用 getC

16、urrentSession()如果在一个线程中,需要使用不同的 Session,则使用 opentSession()4. 通过 getCurrentSession() 获取的 session 在事务提交后,会自动关闭,通过 openSession()获取的 session 则必须手动关闭5. 如果是通过 getCurrentSession() 获取 sesssion ,进行查询需要事务提交 .全局事务和本地事务jndi 如何确定你的 session 有没有及时关闭windows cmd netstat an oracle 1521 mysql 3306 sql server 1433linux

17、/unix netstat anp top session 接口它的主要功能和作用是:1. Session 一个实例代表与数据库的一次操作( 当然一次操作可以是 crud 组合)2. Session 实例通过 SessionFactory 获取,用完需要关闭。3. Session 是线程不同步的( 不安全),因此要保证在同一线程中使用 ,可以用 getCurrentSessiong()。4. Session 可以看做是持久化管理器,它是与持久化操作相关的接口 get vs load1. 如果查询不到数据,get 会返回 null,但是不会报错, load 如果查询不到数据,则报错 Object

18、NotFoundException2. 使用 get 去查询数据,( 先到一级/二级)会立即向 db 发出查询请求(select .), 如果你使用的是 load 查询数据,(先到一级、二级)即使查询到对象,返回的是一个代理对象 ,如果后面没有使用查询结果,它不会真的向数据库发select ,当程序员使用查询结果的时候才真的发出 select ,这个现象我们称为懒加载 (lazy)3. 通过修改配置文件,我们可以取消懒加载4. 如何选择使用哪个: 如果你确定 DB 中有这个对象就用 load(),不确定就用 get()(这样效率高) 我们对获取 session 的工具类,升级,让它可以直接返回

19、 全新的 session 和线程相关的 session 代码:package com.hsp.util;import org.hibernate.Session;import org.hibernate.SessionFactory;import org.hibernate.cfg.Configuration;final public class HibernateUtil /SqlHelper private static SessionFactory sessionFactory=null;/使用线程局部模式private static ThreadLocal threadLocal=ne

20、w ThreadLocal();private HibernateUtil();static sessionFactory=new Configuration().configure(“com/hsp/config/hsp.cfg.xml“).buildSessionFactory();/获取全新的全新的 sesessionpublic static Session openSession()return sessionFactory.openSession();/获取和线程关联的 sessionpublic static Session getCurrentSession()Session

21、session=threadLocal.get();/判断是否得到if(session=null)session=sessionFactory.openSession();/把 session 对象设置到 threadLocal,相当于该 session 已经和线程绑定threadLocal.set(session);return session; query 接口通过 query 接口我们可以完成更加复杂的查询任务.举例: 通过用户来查询数据.快如入门 :Session session=HibernateUtil.getCurrentSession();Transaction ts=null

22、;try ts=session.beginTransaction();/获取 query 引用 这里 Employee 不是表.而是 domain 类名/where 后面的条件可以是类的属性名,也可以是表的字段,安照 hibernate 规定,我们还是应该使用类的属性名.Query query=session.createQuery(“from Employee where namehsp=shunping“);/通过 list 方法获取结果,这个 list 会自动的将封装成对应的 domain 对象/所以我们 jdbc 进行二次封装的工作没有.List list=query.list();f

23、or(Employee e: list)System.out.println(e.getAaaid()+“ “+e.getHiredate();mit(); catch (Exception e) if(ts!=null)ts.rollback();throw new RuntimeException(e.getMessage();finally/关闭 sessionif(session!=null criteria 接口的简单使用快如入门:Session session=HibernateUtil.getCurrentSession();Transaction ts=null;try ts=

24、session.beginTransaction();Criteria cri=session.createCriteria(Employee.class).setMaxResults(2).addOrder(Order.desc(“id“) );List list=cri.list();for(Employee e: list)System.out.println(e.getAaaid();mit(); catch (Exception e) if(ts!=null)ts.rollback();throw new RuntimeException(e.getMessage();finally

25、/关闭 sessionif(session!=null 如何使用 eclipse 进行 hibernate 快速开发我们以前面讲的对 employee 表进行 crud 为例,演示具体用法手动配置:db(table )- 手写 domain 对象-对象关系映射文件现在我们希望用工具完成 Domain 对象和 关系映射文件的工作.1. 创建 web 项目2. 通过 myeclipse 提供 数据库浏览器连接到我们的 oracle 数据库(多人开发)* 这里请大家小心,如果我们测试你们把自己的数据库通过 db 浏览器连接上引入 hibernate 开发包.,同时自动创建 hibernate.cfg

26、.xml 文件,如果希望把 hibernate 开发包升级,我们可以重新引入包.下面我们使用 myeclipse 提供的逆向工程,自动的创建 domain 类和对象关系映射文件.java 对象(属性) 表字段类型拉通练习一把=PHP 是目前 web 编程第一语言,欢迎下载韩顺平老师最新力作 PHP 视频教程,详情查看 http:/ 为什么要学习 hql(hibernate query language)-这个是官方推荐,功能强大? 删除session.delete(对象 ) - 批量删除? 添加session.save session.persist? 修改-批量修改 sessin.updat

27、e(对象)查询 对象 objobj.setXXX();? 查询load get 查询所有 性别是 男的雇员? hql 的详解为了讲解清楚,我模拟一个学生选课系统 ,创建三张表从创建的三张表,我们看出:hibernate 设计者 推荐我们在设计表的时候,应当每张表有一个主键,而且该主键最好不含业务逻辑, product 表 id productNo name price1 bi001 冰箱 10002 nj111 电脑 2000 我们现在使用 hibernate 工具,自动生成 domain 对象 和映射文件,如果我们的表有主外键的关系,则应当先映射主表,再映射从表* uniqueResult

28、方法如果我们检索一个对象,明确知道最多只有一个对象,则建议使用该方法:具体用法如下:Student s=(Student) session.createQuery(“from Student where sid=20050003“).uniqueResult();System.out.println(s.getSname();*distinct 的用法过滤重复的记录/比如,显示所有学生的性别和年龄.List list=session.createQuery(“select distinct sage,ssex from Student“).list();for(int i=0;i list=s

29、ession.createQuery(“from Student where sdept in (计算机系,外语系)“).list();/取出 1. for 增强for(Student s:list)System.out.println(s.getSname()+“ “+s.getSaddress()+“ “+s.getSdept();*group by 使用/显示各个系的学生的平均年龄List list=session.createQuery(“select avg(sage),sdept from Student group by sdept“).list();/取出 1. for 增强f

30、or(Object obj:list)System.out.println(obj0.toString()+“ “+obj1.toString();/having 的使用/1.对分组查询后的结果,进行筛选:比如请显示人数大于 3 的系名称/a. 查询各个系分别有多少学生.List list=session.createQuery(“select count(*) as c1,sdept from Student group by sdept having count(*)3“).list();/取出 1. for 增强for(Object obj:list)System.out.println

31、(obj0.toString()+“ “+obj1.toString();/2 查询女生少于 200 人的系/a.查询各个系的女生有多个个List list=session.createQuery(“select count(*) as c1,sdept from Student where ssex=F group by sdept“).list();/取出 1. for 增强for(Object obj:list)System.out.println(obj0.toString()+“ “+obj1.toString();/1.查询计算机系共多少人?-如果我们返回的是一列数据/这时我们的取

32、法是直接取出 list-object 而不是 list-ObjectList list=session.createQuery(“select sage from Student where sdept=计算机系“).list();/取出 1. for 增强for(Object obj:list)System.out.println(obj.toString();3.查询选修 11 号课程的最高分和最低分.List list=session.createQuery(“select 11,max(grade),min(grade) from Studcourse where course.cid

33、=11“).list();/取出 1. for 增强for(Object obj:list)System.out.println(obj0.toString()+“ max=“+obj1.toString()+“ min=“+obj2.toString();/计算各个科目不及格的学生数量.(学生练习!)List list=session.createQuery(“select count(*),student.sdept from Studcourse where gradePreparedStatement setXXX)使用参数绑定的好处有 3:1. 可读性提高, 2 效果高 3,防止 s

34、ql 注入漏洞? 面试题: 如果不使用参数绑定,怎样防止登录时, sql 注入?name password 思路: 1. 通过用户名,查询出该用户名在数据库中对应的密码,然后再与用户输入的秘密比较,如果相等,则用户和法,否则,非法.参数绑定有两种形式Query q=session.createQuery(from Student where sdept=:dept and sage:age)如果我们的参数是 :冒号形式给出的,则我们的参数绑定应当这样:List list=session.createQuery(“from Student where sdept=:a1 and sage:sag

35、e“).setString(“a1“, “计算机系“).setString(“sage“, “2“).list();还有一种形式:Query q=session.createQuery(from Student where sdept=? and sage?)如果我们的参数是以 ? 形式给出的则,参数绑定应当:List list=session.createQuery(“from Student where sdept=? and sage?“).setString(0, “计算机系“).setString(1, “2“).list();参数的绑定,可以分开写:形式如下:Query query

36、=session.createQuery(“from Student where sdept=? and sage?“);query.setString(0, “计算机系“);query.setString(1, “2“);List list=query.list();for(int i=0;i22在程序中,我们这样获取并执行:List list=session.getNamedQuery(“myquerytest“).list();System.out.println(list.size();Iterator it=list.iterator();while(it.hasNext()Obje

37、ct obj=(Object)it.next();System.out.println(“n=“+obj0);hibernate 对象的三种关系:1. one to one : 身份证人 2. one to many 部门 员工3. many-to-one 员工部门4. many-to-many 学生老师 criterial 使用:/查询年龄大于 10 岁的学生 criteriaSession s=HibernateUtil.getCurrentSession();Transaction tx=s.beginTransaction();Criteria cri=s.createCriteria

38、(Student.class);/添加检索条件cri.add(Restrictions.gt(“sage“, new Long(10);List list=cri.list();for(Student s1: list)System.out.println(s1.getSname();mit(); hibernate 开发的三种方式中的:编写 domain object + 映射文件 - 创建出对应的数据库 ,这里我们说明如果要自动的创建出对应的数据库,需要做配置(hibernate.cfg.xml).create这里有四个配置值: create , update , create-drop,

39、 validatecreate : 当我们的应用程序加载 hibernate.cfg.xml new Configuration().config(); 就会根据映射文件,创建出数据库, 每次都会重新创建, 原来表中的数据就没有!update: 如果数据库中没有该表,则创建,如果有表,则看有没有变化,如果有变化,则更新.create-drop: 在显示关闭 sessionFactory 时,将 drop 掉数据库的 schemavalidate: 相当于每次插入数据之前都会验证数据库中的表结构和 hbm 文件的结构是否一致 在开发测试中,我们配置哪个都可以测试,但是如果项目发布后,最好自己配置

40、一次,让对应的数据库生成,完后取消配置, domain 对象的细节 :1. 需要一个无参的构造函数(用于 hibernate 反射该对象)2. 应当有一个无业务逻辑的主键属性.3. 给每个属性提供 get set 方法.4. 在 domian 对象中的属性,只有配置到了对象映射文件后,才会被 hiberante 管理.5. 属性一般是 private 范围 对对象关系映射文件的说明对象关系文件中,有些属性是可以不配,hibernate 会采用默认机制,比如table 值不配,则以类的小写做表名type 不配置,则 hibernate 会根据类的属性类型,选择一个适当的类型hibernate 对

41、象的三种状态,转换图:面试图:如果判断一个对象处于怎样的状态 ?主要的依据是: 1. 看该对象是否处于 session, 2, 看在数据库中有没有对应的记录瞬时态: 没有 session 管理,同时数据库没有对应记录持久态: 有 session 管理,同时在数据库中有记录脱管态/游离态: 没有 session 管理,但是在数据库中有记录. 懒加载:简述: 当我们查询一个对象的时候,在默认情况下,返回的只是该对象的普通属性,当用户去使用对象属性时,才会向数据库发出再一次的查询.这种现象我们称为 lazy 现象.解决方法可以这样:1. 显示初始化 Hibernate.initized(代理对象)2

42、. 修改对象关系文件 lazy 改写 lazy=false3. 通过过滤器(web 项目) openSessionInView hibernate 对象的关系映射1. many-to-one2. one-to-many看一个需求: 通过一个部门号 (1),来获取该部门的所有学生?这里请大家参考代码:3 one-to-one一对一有有两种方式(1) 基于主键的一对一原理图 :(2) 基于外键的一对一原理图 :3. many-to-many学生课程 就是 many-to-many 顾客商品qqqq 群上机练习,请自己想出 生活中one-to-many many-to-onemany-to-many

43、one-to-one 的四组对象关系,并使用 hibernate 实现写出对应的 domain object 和对象关系映射文件,并通过 hbm2ddl 自动创建成功对应的表=PHP 是目前 web 编程第一语言,欢迎下载韩顺平老师最新力作 PHP 视频教程,详情查看 http:/ 为什么要学习 hql(hibernate query language)-这个是官方推荐,功能强大? 删除session.delete(对象 ) - 批量删除? 添加session.save session.persist? 修改-批量修改 sessin.update(对象)查询 对象 objobj.setXXX(

44、);? 查询load get 查询所有 性别是 男的雇员? hql 的详解为了讲解清楚,我模拟一个学生选课系统 ,创建三张表从创建的三张表,我们看出:hibernate 设计者 推荐我们在设计表的时候,应当每张表有一个主键,而且该主键最好不含业务逻辑, product 表 id productNo name price1 bi001 冰箱 10002 nj111 电脑 2000 我们现在使用 hibernate 工具,自动生成 domain 对象 和映射文件,如果我们的表有主外键的关系,则应当先映射主表,再映射从表* uniqueResult 方法如果我们检索一个对象,明确知道最多只有一个对象

45、,则建议使用该方法:具体用法如下:Student s=(Student) session.createQuery(“from Student where sid=20050003“).uniqueResult();System.out.println(s.getSname();*distinct 的用法过滤重复的记录/比如,显示所有学生的性别和年龄.List list=session.createQuery(“select distinct sage,ssex from Student“).list();for(int i=0;i list=session.createQuery(“from

46、Student where sdept in (计算机系,外语系)“).list();/取出 1. for 增强for(Student s:list)System.out.println(s.getSname()+“ “+s.getSaddress()+“ “+s.getSdept();*group by 使用/显示各个系的学生的平均年龄List list=session.createQuery(“select avg(sage),sdept from Student group by sdept“).list();/取出 1. for 增强for(Object obj:list)System

47、.out.println(obj0.toString()+“ “+obj1.toString();/having 的使用/1.对分组查询后的结果,进行筛选:比如请显示人数大于 3 的系名称/a. 查询各个系分别有多少学生.List list=session.createQuery(“select count(*) as c1,sdept from Student group by sdept having count(*)3“).list();/取出 1. for 增强for(Object obj:list)System.out.println(obj0.toString()+“ “+obj1

48、.toString();/2 查询女生少于 200 人的系/a.查询各个系的女生有多个个List list=session.createQuery(“select count(*) as c1,sdept from Student where ssex=F group by sdept“).list();/取出 1. for 增强for(Object obj:list)System.out.println(obj0.toString()+“ “+obj1.toString();/1.查询计算机系共多少人?-如果我们返回的是一列数据/这时我们的取法是直接取出 list-object 而不是 list-ObjectList list=session.createQuery(“select sage from Student where sdept=计算机系“).list();/取出 1.

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 企业管理 > 管理学资料

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报