韩顺平 hibernate笔记.doc_第1页
韩顺平 hibernate笔记.doc_第2页
韩顺平 hibernate笔记.doc_第3页
韩顺平 hibernate笔记.doc_第4页
韩顺平 hibernate笔记.doc_第5页
已阅读5页,还剩30页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

u hibernate是什么?1. hibernate 是一个框架(framework)2. hibernate 是一个orm框架 l orm (object relation mapping) 对象关系映射 框架o object - 业务层(只对对象操作)r relation- 关系数据库m mapping 对象关系映射文件3. hibernate 处于我们项目的持久层位置(正因为如此,所以有人又把hibernate称为 持久层框架)4. hibernate 实际上就是对jdbc进行了轻量级的封装.5. hibernate 的基础还是我们java 反射机制l 除了hiberante 这个orm框架,还有一些:apache ojb / toplink / ibatis / ejb cmpApache OJB () Cayenne () Jaxor () Hibernate () iBatis () jRelationalFramework () mirage () SMYLE () TopLink () 把对象持久化: 把对象的信息保存到数据库或者是文件.总结: hibernate 是对jdbc进行轻量级封装的 orm 框架,充当项目的持久层.u 为什么需要hibernate?u 快如入门案例:hiberante 可以用在 j2se 项目,也可以用在 j2ee (web项目中)struts是web框架,所以用在 web项目我们使用手动配置hibernate方式开发一个hibernate 项目,完成crud操作 。开发流程1. 创建一个项目2. 画出一个简单项目框架示意图3. 引入hibernate 开发包 (从网上下载 google hibernate ),完后我们4. 开发hibernate 有三种方法(开发顺序)我们使用第二种开发项目创建employe 表.create table employee(id number primary key,name varchar2(64) 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对象同一个文件夹下(包下)我们的Employee.hbml.xml配置文件 :emp_seq6. 手动配置我们的hibernate.cfg.xml文件,该文件用于配置 连接的数据库的类型,driver,用户名,密码 ,url .同时管理 对象关系映射文件 ,该文件的名称,我们一般不修改.hibernate.cfg.xml配置文件oracle.jdbc.driver.OracleDriverscotttigerjdbc:oracle:thin::1521:orclhsporg.hibernate.dialect.OracleDialecttrue7. 测试文件TestMain.javapackage com.hsp.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语句(hibernate 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 static 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);/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这是一个会话工厂,是一个重量级的对象SessionFactory sessionFactory=configuration.buildSessionFactory();/3.创建Sessoin 相当于jdbc Connection servelt HttpSession ,也不是 jsp sessionSession session=sessionFactory.openSession();/4.对hiberate而言,要求程序员,在进行 增加,删除,修改的时候使用事务提交,Transaction transaction = session.beginTransaction();/添加一个雇员Employee employee=new Employee();employee.setName(shunping);employee.setEmail();employee.setHiredate(new Date();/insert ./保存session.save(employee);/save employee就是持久化该对象 (把对象保存到了数据库中称为一条记录)/=insert into .被hiberante封装/提交mit();session.close();u 现在我们体验一下hibernate切换数据库的优势.这次,我们使用 让hibernate自动完成 domain-映射文件-表 的工作.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. 除了主键属性外,它应当还有其属性,属性的访问权限是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是目前web编程第一语言,欢迎下载韩顺平老师最新力作PHP视频教程,详情查看 u hibernate的核心类和接口 Configuration 类它的用处是:1. 读取hibernate.cfg.xml2. 管理对象关系映射文件 3. 加载hibernate 的驱动,url ,用户.4. 管理hibernate配置信息 hibernate.cfg.xml 对象关系映射文件 SessionFactory (会话工厂)1. 可以缓存sql语句和数据(称为session级缓存)!2. 是一个重量级的类,因此我们需要保证一个数据库,有一个SessionFactroy这里我们讨论一个通过SessionFactory 获取 Session的两个方法 openSession() 一个 getCurrentSession();1. openSession() 是获取一个新的session2. getCurrentSession () 获取和当前线程绑定的session,换言之,在同一个线程中,我们获取的session是同一session,这样可以利于事务控制如果希望使用 getCurrentSession 需要配置 hibernate.cfg.xml中配置.3. 如何选择原则:如果需要在同一线程中,保证使用同一个Session则,使用getCurrentSession()如果在一个线程中,需要使用不同的Session,则使用opentSession()4. 通过 getCurrentSession() 获取的session在事务提交后,会自动关闭,通过openSession()获取的session则必须手动关闭5. 如果是通过getCurrentSession() 获取 sesssion ,进行查询需要事务提交.全局事务和本地事务jndi l 如何确定你的session有没有及时关闭windows cmd netstat an oracle 1521 mysql 3306 sql server 1433linux/unix netstat anp top session接口它的主要功能和作用是:1. Session一个实例代表与数据库的一次操作(当然一次操作可以是crud组合)2. Session实例通过SessionFactory获取,用完需要关闭。3. Session是线程不同步的(不安全),因此要保证在同一线程中使用,可以用getCurrentSessiong()。4. Session可以看做是持久化管理器,它是与持久化操作相关的接口u get vs load1. 如果查询不到数据,get 会返回 null,但是不会报错, load 如果查询不到数据,则报错ObjectNotFoundException2. 使用get 去查询数据,(先到一级/二级)会立即向db发出查询请求(select .), 如果你使用的是 load查询数据,(先到一级、二级)即使查询到对象,返回的是一个代理对象,如果后面没有使用查询结果,它不会真的向数据库发select ,当程序员使用查询结果的时候才真的发出select ,这个现象我们称为懒加载(lazy)3. 通过修改配置文件,我们可以取消懒加载4. 如何选择使用哪个: 如果你确定DB中有这个对象就用load(),不确定就用get()(这样效率高)u 我们对获取session的工具类,升级,让它可以直接返回 全新的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=new 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 session=threadLocal.get();/判断是否得到if(session=null)session=sessionFactory.openSession();/把session对象设置到 threadLocal,相当于该session已经和线程绑定threadLocal.set(session);return session;u query接口通过query接口我们可以完成更加复杂的查询任务.举例: 通过用户来查询数据.快如入门 :Session session=HibernateUtil.getCurrentSession();Transaction ts=null;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();for(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&session.isOpen()session.close();u criteria 接口的简单使用快如入门:Session session=HibernateUtil.getCurrentSession();Transaction ts=null;try ts=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/关闭sessionif(session!=null&session.isOpen()session.close();u 如何使用eclipse进行hibernate 快速开发我们以前面讲的对employee表进行crud为例,演示具体用法手动配置:db(table )- 手写domain对象-对象关系映射文件现在我们希望用工具完成 Domain对象和 关系映射文件的工作.1. 创建web项目2. 通过myeclipse 提供 数据库浏览器连接到我们的oracle数据库(多人开发)* 这里请大家小心,如果我们测试你们把自己的数据库通过 db 浏览器连接上引入hibernate开发包.,同时自动创建hibernate.cfg.xml文件,如果希望把hibernate开发包升级,我们可以重新引入包.下面我们使用myeclipse提供的逆向工程,自动的创建domain类和对象关系映射文件.java对象(属性) 表字段类型拉通练习一把=PHP是目前web编程第一语言,欢迎下载韩顺平老师最新力作PHP视频教程,详情查看 u 为什么要学习hql(hibernate query language)-这个是官方推荐,功能强大? 删除session.delete(对象) - 批量删除? 添加session.save session.persist? 修改-批量修改 sessin.update(对象)查询 对象 objobj.setXXX();? 查询load get 查询所有 性别是 男的雇员?u hql的详解为了讲解清楚,我模拟一个学生选课系统 ,创建三张表从创建的三张表,我们看出:hibernate 设计者 推荐我们在设计表的时候,应当每张表有一个主键,而且该主键最好不含业务逻辑, product 表 id productNo name price1bi001 冰箱 10002nj111 电脑 2000 我们现在使用hibernate工具,自动生成 domain 对象 和映射文件,如果我们的表有主外键的关系,则应当先映射主表,再映射从表* uniqueResult方法如果我们检索一个对象,明确知道最多只有一个对象,则建议使用该方法:具体用法如下: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;ilist.size();i+)Object objs=(Object) list.get(i);System.out.println(objs0.toString()+ +objs1.toString();*between and.List list=session.createQuery(select distinct sage,ssex,sname from Student where sage between 20 and 22).list();for(int i=0;ilist.size();i+)Object objs=(Object) list.get(i);System.out.println(objs0.toString()+ +objs1.toString()+objs2.toString();*in /not in/查询计算机系和外语系的学生信息List list=session.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 增强for(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(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.查询计算机系共多少人?-如果我们返回的是一列数据/这时我们的取法是直接取出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=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,防止 sql注入漏洞? 面试题: 如果不使用参数绑定,怎样防止登录时, 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:sage).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=session.createQuery(from Student where sdept=? and sage?);query.setString(0, 计算机系);query.setString(1, 2);List list=query.list();for(int i=0;ilist.size();i+)Student s= list.get(i);System.out.println(s.getSname()+ +s.getSage();把HibernateUtil升级了u 在映射文件中得到hql语句hibernate提供了一种更加灵活的查询方法:把hql语句配置到 对象关系映射文件,22在程序中,我们这样获取并执行:List list=session.getNamedQuery(myquerytest).list();System.out.println(list.size();Iterator it=list.iterator();while(it.hasNext()Object 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(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, validatecreate : 当我们的应用程序加载hibernate.cfg.xml new Configuration().config(); 就会根据映射文件,创建出数据库, 每次都会重新创建, 原来表中的数据就没有!update: 如果数据库中没有该表,则创建,如果有表,则看有没有变化,如果有变化,则更新.create-drop: 在显示关闭 sessionFactory时,将drop掉数据库的schemavalidate: 相当于每次插入数据之前都会验证数据库中的表结构和hbm文件的结构是否一致l 在开发测试中,我们配置哪个都可以测试,但是如果项目发布后,最好自己配置一次,让对应的数据库生成,完后取消配置, u domain对象的细节:1. 需要一个无参的构造函数(用于hibernate反射该对象)2. 应当有一个无业务逻辑的主键属性.3. 给每个属性提供 get set方法.4. 在domian对象中的属性,只有配置到了对象映射文件后,才会被hiberante管理.5. 属性一般是private范围u 对对象关系映射文件的说明对象关系文件中,有些属性是可以不配,hibernate会采用默认机制,比如 table 值不配,则以类的小写做表名 type不配置,则hibernate会根据类的属性类型,选择一个适当的类型hibernate对象的三种状态,转换图:面试图:如果判断一个对象处于怎样的状态?主要的依据是: 1. 看该对象是否处于session, 2, 看在数据库中有没有对应的记录瞬时态: 没有session管理,同时数据库没有对应记录持久态: 有session管理,同时在数据库中有记录脱管态/游离态: 没有session管理,但是在数据库中有记录.u 懒加载:简述: 当我们查询一个对象的时候,在默认情况下,返回的只是该对象的普通属性,当用户去使用对象属性时,才会向数据库发出再一次的查询.这种现象我们称为 lazy现象.解决方法可以这样:1. 显示初始化 Hibernate.initized(代理对象)2. 修改对象关系文件

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论