收藏 分销(赏)

hibernate笔记总结_sdh.doc

上传人:pc****0 文档编号:7824694 上传时间:2025-01-19 格式:DOC 页数:39 大小:458.27KB 下载积分:10 金币
下载 相关 举报
hibernate笔记总结_sdh.doc_第1页
第1页 / 共39页
hibernate笔记总结_sdh.doc_第2页
第2页 / 共39页


点击查看更多>>
资源描述
欢迎下载韩顺平老师的PHP视频教程 ,详情查看 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 cmp Apache 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 http://www.hibernate.org),完后我们 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_seq start with 1 increment by 1 minvalue 1 nomaxvalue nocycle nocache 5. 开发domain对象和对象关系映射文件 对象关系映射文件: 作用是用于指定 domain对象和表的映射关系. ,该文件的取名有规范: domain对象.hbm.xml,一般我们放在 和domain对象同一个文件夹下(包下) 我们的Employee.hbml.xml配置文件 : <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" " <hibernate-mapping package="com.hsp.domain"> <class name="Employee" table="employee"> <!-- id元素用于指定主键属性 --> <id name="id" column="id" type="java.lang.Integer"> <!-- 该元素用于指定主键值生成策略hilo native increment sequence uuid --> <generator class="sequence"> <param name="sequence">emp_seq</param> </generator> </id> <!-- 对其它属性还有配置 --> <property name="name" type="java.lang.String"> <column name="name" not-null="false" /> </property> <property name="email" type="java.lang.String" > <column name="email" not-null="false"/> </property> <property name="hiredate" type="java.util.Date"> <column name="hiredate" not-null="false" /> </property> </class> </hibernate-mapping> 6. 手动配置我们的hibernate.cfg.xml文件,该文件用于配置 连接的数据库的类型,driver, ,用户名,密码 ,url ....同时管理 对象关系映射文件 ,该文件的名称,我们一般不修改. hibernate.cfg.xml配置文件 <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" " <hibernate-configuration> <session-factory> <!-- hibernate 设计者,给我们提供了一写常用的配置 --> <!-- 配置使用的driver --> <property name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property> <property name="connection.username">scott</property> <property name="connection.password">tiger</property> <property name="connection.url">jdbc:oracle:thin:@127.0.0.1:1521:orclhsp</property> <!-- 配置dialect方言,明确告诉hibernate连接是哪种数据库 --> <property name="dialect">org.hibernate.dialect.OracleDialect</property> <!-- 显示出对于sql --> <property name="show_sql">true</property> <!-- 指定管理的对象映射文件 --> <mapping resource="com/hsp/domain/Employee.hbm.xml"/> </session-factory> </hibernate-configuration> 7. 测试文件TestMain.java package 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() { //删除 //获取一个session Session 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("abc@"); 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 session] Session session=sessionFactory.openSession(); //4.对hiberate而言,要求程序员,在进行 增加,删除,修改的时候使用事务提交, Transaction transaction = session.beginTransaction(); //添加一个雇员 Employee employee=new Employee(); employee.setName("shunping"); employee.setEmail("shunping@"); employee.setHiredate(new Date()); //insert ............. //保存 session.save(employee);//save employee就是持久化该对象 (把对象保存到了数据库中称为一条记录) //==>insert into ....[被hiberante封装] //提交 mit(); session.close(); } } u 现在我们体验一下hibernate切换数据库的优势. 这次,我们使用 让hibernate自动完成 domain->映射文件->表 的工作. 1. 首先我们把 hibernate.cfg.xml文件重新配置. <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" " <hibernate-configuration> <session-factory> <!-- hibernate 设计者,给我们提供了一写常用的配置 --> <!-- 配置使用的driver --> <property name="connection.driver_class">com.mysql.jdbc.Driver</property> <property name="connection.username">root</property> <property name="connection.password">root</property> <property name="connection.url">jdbc:mysql:/localhost:3306/test</property> <!-- 配置dialect方言,明确告诉hibernate连接是哪种数据库 --> <property name="dialect">org.hibernate.dialect.MySQLDialect</property> <!-- 显示出对于sql --> <property name="show_sql">true</property> <!-- 让hibernate给我们自动创建表 create :如果没有该表则创建. --> <property name="hbm2ddl.auto">create</property> <!-- 指定管理的对象映射文件 --> <mapping resource="com/hsp/domain/Employee.hbm.xml"/> </session-factory> </hibernate-configuration> 2. 对对象映射文件,做了相应的修改. <!-- 对主键生成策略我们做了修改 --> <id name="id" column="id" type="java.lang.Integer"> <generator class="increment"></generator> </id> 笔试题: 请列举出hibernate常见的接口和类 ?请解释什么事pojo类,它有什么要求: 1. pojo类是和一张表对应 2. 一般我们放在 com.xxx.domain下 3. pojo 需要一个主键属性(用于标示一个pojo对象) 4. 除了主键属性外,它应当还有其属性,属性的访问权限是private 5. 提供 set /get 方法 6. 它应当有一个无参的构造方法(hibernate 反射) 7. pojo类其实就是javabean/ 有些老程序员 叫他 date对象 上机练习: 写一个简单的雇员管理系统. emp( id , name , tel , birthday ), 可以,进入主界面 请选择数据库类型 1. 表示 连接 oracle 2. 表示 连接 mysql 3. 表示 连接 sql server 请选择操作 1. 显示所有雇员 2. 根据id查询指定雇员 3. 修改雇员信息(请先输入id) 4. 根据id 删除雇员. * 用户可以多次选择操作. u hibernate的核心类和接口 ① Configuration 类 它的用处是: 1. 读取hibernate.cfg.xml 2. 管理对象关系映射文件 <mapping resource=””> 3. 加载hibernate 的驱动,url ,用户.. 4. 管理hibernate配置信息 ② hibernate.cfg.xml ③ 对象关系映射文件 ④ SessionFactory (会话工厂) 1. 可以缓存sql语句和数据(称为session级缓存)!! 2. 是一个重量级的类,因此我们需要保证一个数据库,有一个SessionFactroy 这里我们讨论一个通过SessionFactory 获取 Session的两个方法 openSession() 一个 getCurrentSession(); 1. openSession() 是获取一个新的session 2. 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 1433] linux/unix netstat –anp top ⑤ session接口 它的主要功能和作用是: 1. Session一个实例代表与数据库的一次操作(当然一次操作可以是crud组合) 2. Session实例通过SessionFactory获取,用完需要关闭。 3. Session是线程不同步的(不安全),因此要保证在同一线程中使用,可以用getCurrentSessiong()。 4. Session可以看做是持久化管理器,它是与持久化操作相关的接口 u get vs load 1. 如果查询不到数据,get 会返回 null,但是不会报错, load 如果查询不到数据,则报错ObjectNotFoundException 2. 使用get 去查询数据,(先到一级/二级)会立即向db发出查询请求(select ...), 如果你使用的是 load查询数据,(先到一级、二级))即使查询到对象,返回的是一个代理对象,如果后面没有使用查询结果,它不会真的向数据库发select ,当程序员使用查询结果的时候才真的发出select ,这个现象我们称为懒加载(lazy) 3. 通过修改配置文件,我们可以取消懒加载 <class name="Employee" lazy="false" table="employee"> 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<Session> threadLocal=new ThreadLocal<Session>(); private HibernateUtil(){}; static { sessionFactory=new Configuration().configure("com/hsp/config/hsp.cfg.xml").buildSessionFactory(); } //获取全新的全新的sesession public static Session openSession(){ return sessionFactory.openSession(); } //获取和线程关联的session public 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<Employee> 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{ //关闭session if(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<Employee> 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{ //关闭session if(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对象(属性) <---------1. java类型 2. hibernate types-------------> 表字段类型 拉通练习一把. u 为什么要学习hql(hibernate query language)->这个是官方推荐,功能强大 ? 删除 session.delete(对象) -> 批量删除 ? 添加 session.save session.persist ? 修改->批量修改 sessin.update(对象) 查询 对象 obj obj.setXXX(); ? 查询 load get 查询所有 性别是 男的雇员? u hql的详解 为了讲解清楚,我模拟一个学生选课系统 ,创建三张表 从创建的三张表,我们看出: hibernate 设计者 推荐我们在设计表的时候,应当每张表有一个主键,而且该主键最好不含业务逻辑, product 表 id productNo name price 1 bi001 冰箱 1000 2 nj111 电脑 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;i<list.size();i++){ Object [] objs=(Object[]) list.get(i); System.out.println(objs[0].toString()+" "+objs[1].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;i<list.size();i++){ Object [] objs=(Object[]) list.get(i); System.out.println(objs[0].toString()+" "+objs[1].toString()+objs[2].toString()); } *in /not in //查询计算机系和外语系的学生信息 List<Student> 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<Object[]> list=session.createQuery("select avg(sage),sdept from Student group by sdept").list(); //取出1. for 增强 for(Object[] obj:list){ System.out.println(obj[0].toString()+" "+obj[1].toString()); } //having的使用 //1.对分组查询后的结果,进行筛选:比如请显示人数大于3的系名称 //a. 查询各个系分别有多少学生. List<Object[]> 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(obj[0].toString()+" "+obj[1].toString()); } //2查询女生少于200人的系 //a.查询各个系的女生有多个个 List<Object[]> 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(obj[0].toString()+" "+obj[1].toString()); } //1.查询计算机系共多少人?->如果我们返回的是一列数据 //这时我们的取法是直接取出list->object 而不是 list->Object[] List<Object[]> list=session. createQuery("select sage from Student where sdept='计算机系'").list(); //取出1. for 增强 for(Object obj:list){ System.out.println(obj.toString()); } 3.查询选修11号课程的最高分和最低分. List<Object[]> 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(obj[0].toString()+" max="+obj[1].toString()+" min="+obj[2].toString()); } //计算各个科目不及格的学生数量.(学生练习!) List<Object[]> list=session. createQuery("select count(*),student.sdept from Studcourse where grade<60 group by student.sdept").list(); //取出1. for 增强 for(Object[] obj:list){ System.out.println(obj[0].toString()+" "+obj[1].toString()); } u 参数绑定案例 (jdbc->PreparedStatem
展开阅读全文

开通  VIP会员、SVIP会员  优惠大
下载10份以上建议开通VIP会员
下载20份以上建议开通SVIP会员


开通VIP      成为共赢上传

当前位置:首页 > 百科休闲 > 其他

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        抽奖活动

©2010-2025 宁波自信网络信息技术有限公司  版权所有

客服电话:4009-655-100  投诉/维权电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服