




已阅读5页,还剩13页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
TarenaDay01Hibernate笔记整理完整版1. 基本概念:(1)有什么用是开源的用于封装数据访问层的组件,我们称为数据访问层框架(或持久层框架);是对JDBC+SQL的轻量级封装。(2)出现背景,需要解决的问题:a)SQL语句过于繁杂,和数据库的耦合度高b)不同数据库之间SQL的不同,导致移植困难:例如分页查询的区别(Oracle与MySql之间区别)c)二维关系表和对象之间数据结构的不匹配:我们从数据库中取出的数据时结构集(一张表),而我们开发时需要将查询到得结果集封装为对象,然而数据库中二维表的数据结构和内存中java对象的数据结构是不匹配的(表中的数据需要经过处理才能变为Java对象)。(3)工作原理-ORM思想对象-关系映射(Object-Relation Mapping):Hibernate用于应用程序中的对象(Object)与表中的数据关系(Relationship)之间的映射(Mapping),即把对象保存到关系表中或者把关系表中数据取出映射为对象。可以这样理解:Hibernate可以直接从数据库中取出Java对象,或者把Java对象直接保存于数据库中,中间sql语句等繁琐的步骤被Hibernate封装。2. Hibernate的基本使用核心步骤:1) 导入Jar包:Hibrenate开发包,数据库驱动包2) Hibernate配置文件(只有1个):hibernate.cfg.xml用于数据库连接信息及Hibernate的一些配置信息(指定数据库方言类型)-主要用于定义数据库连接参数,指定数据库方言类型。-hibernate.cfg.xmlcom.mysql.jdbc.Driverjdbc:mysql:/localhost:3306/jd1112db?useUnicode=true&characterEncoding=utf8roottaodongjie199012 1 org.hibernate.dialect.MySQLDialect true 3) Hibernate映射文件(可以有n个):用于指明类和表之间的对应关系,Hibernate根据该文件生成SQL语句;映射名称为*.hbm.xml推荐:类名Emp,映射文件Emp.hbm.xml-*.hbm.xml 4) 测试类TestUser.java public class Test3TestJutil测试工具:可以同时测试多个方法public void test1()/创建一个User对象User user=new User();user.setName(kobe);/调用Hibernate的API用于装载Hinernate配置文件Configuration conf=new Configuration();/在类路径中装载 默认的配置文件hibernate.cfg.xml/如果配置文件关联了映射文件,同时也装载了映射信息conf.configure();/默认加载src/hibernate.cfg.xml/如果装载指定的配置文件/创建SessionFactorySessionFactory factory=conf.buildSessionFactory();/创建Session:与数据库之间的通话(类似于Connection)Session session=factory.openSession();可以封装在HibernateUtil工具类中/获得事务Transaction tx=session.getTransaction();/开启事务tx.begin();/插入数据,或者删除,更新数据session.save(user);/delete(user),update(user)注意:更新的时候容易把原有数据冲掉;解决办法:先从数据库中把要更新的数据取出,再更新;User user=(User)session.get(User.class,13);/按照主键值查找user.setNickname(“ssh”);Session.update(user);,/提交事务mit();/关闭sessionsession.close();-封装为HibernateUtil:public class HibernateUtil public static Configuration conf;private static SessionFactory sessionFactory;static静态代码块|只加载一次,提高程序性能。 conf=new Configuration();conf.configure()默认加载hibernate.cfg.xml配置文件和映射文件。;sessionFactory=conf.buildSessionFactory();public static Session getSession()return sessionFactory.openSession();-按主键进行查询方法:public void testFindAll()Session session=HibernateUtils.getSession();/HQL查询语句 hibernate query language面向对象的查询语句Query query=session.createQuery(“from User对象类名”);/User类名-from User where Listlist=query.list();session.close();for(User user:list)System.out.println(user.getId()+”+user.getNickname();-核心API:Configuration:配置和映射文件加载-Hibernate主配置,映射文件另一种方法:程序块中追加类-conf.addClass(User.class)进行追加SessionFactory:session对象工厂.getSession()-获得SessionSession:用于进行增删改操作.get(对象名.class,主键条件值).createQuery(“from 对象名”);-创建Query对象session.close();-关闭连接Transaction:用于事务管理(无法自动提交,需要手动代码commit)Transaction tx=session.beginTransaction();-开始事务mit();-提交事务Query:用于查询(是结果集对象)-是HQL(hibernate query language)语言Listlist=query.lsit();-查询结果返回为集合Iterator it=query.iterator();-返回迭代器3. 主键生成方式常用主键生成方式:1) identity:用于自动生成主键方式,除了Oracle不支持,其他数据库一般都支持(较常用)。2) sequence:Oracle中使用,用序列生成ID主键:先调用指定的序列获取值,然后再执行插入操作,写入数据表主键字段。3) native:主键生成方式如果是native,就看配置文件hibernate.cfg.xml中方言是什么;如果方言是Mysql,相当于identity,如果方言是Oracle,相当于sequence4)increament:先获取主键最大值,然后再执行最大值+1,执行插入。(并发性太高系统不安全)5)assigned:告诉Hibernate框架忽略主键值的生成,程序员需要显示指定值。uuid:采用UUID算法生成一个主键值(字符串)hilo:采用高地位算法生成一个主键值(数值)4. Hibernate数据类型(了解)Hbm.xml映射文件可以使用两种类型:推荐使用Hibernate类型a. java类型java.lang.Integerjava.lang.Stringjava.sql.Dateb. Hibernate类型integer,double,long,stringdate,time,timestamp时间戳,存放年月日分秒true_false将在数据库中存放一个字符T或者F。 ,yes_no将在数据库中存一个字符Y或者N-相当于boolean类型Day025. 改造ProjectDAOImpl实现为Hibernate结构工厂方法实现Action与DAO的解耦:public class DAOFactorypublic static ProjectDAO getProjectDAO()return new HibernateProjectDAOImpl()也可以调用其他的接口实现类实例;增加了灵活性。;作用:1)创建实例 2)工厂设计模式用于解耦6. Hibernate框架特性:(1)一级缓存:每个Session对象都有一个一级缓存,当对某个对象获取时,首先去一级缓存中获取,没有采取数据库查询。当数据被缓存到session中时,session就要负责维护缓存中的数据,这是Hibernate的重要机制:一级缓存机制。理解:1)如果session被查询,session将先到缓存中查找是否有被查询的对象,找到则直接取出,否则才查询数据库。2)session需要负责实时维护在缓存中的数据,保证缓存中的数据与数据库中数据一致性,一旦用户对缓存中的数据做了修改,session立刻将数据更新到数据库中。3)当session关闭后,将销毁一级缓存。4)一个session对象不能访问其他session对象的一级缓存。ThreadLocal利用一级缓存:利用ThreadLocal可以与当前线程绑定在一起。实现在多个类中只使用同一个session对象,改造HibernateUtil的getSession()方法,目的是为了保障多次调用getSession()方法返回同一个session,这样后续查询数据,可以从缓存中获取。-session与线程绑定注意:当希望在多个类中调用session,则不要关闭session(session.close(),否则,其他类将使用不到session对象。-修改HinernateUtil工具类public class HibernateUtil public static Configuration conf;private static SessionFactory sessionFactory;private static ThreadLocal线程独立的,可以得到同一个session sessionLocal=new ThreadLocal();static conf=new Configuration();conf.configure();sessionFactory=conf.buildSessionFactory();public static Session getSession()Session session=sessionLocal.get();if(session=null)session=sessionFactory.openSession()返回一个新建的Session对象,必须显示close();.getCurrentSession():返回当前的session对象,如果没有则创建一个新的对象;在事务结束时自动关闭。;sessionLocal.set(session);return session;Public static void closeSession()Session session=sessionLocal.get();if(session!=null)session.close();sessionLocal.set(null);-Hibernate支持的Session与线程绑定另一种方法:sessionFactory.getcurrentSession()实施步骤:a) 在hibernate.cfg.xml中加入元素:threadb)在工具类HibernateUtil中加上sessionFactory.getcurrentSession();public class HibernateUtil public static Configuration conf;private static SessionFactory sessionFactory;static conf=new Configuration();conf.configure();sessionFactory=conf.buildSessionFactory();public static Session getSession()return sessionFactory.getcurrentSession()返回当前的session对象,如果没有则创建一个新的对象; 在事务结束时自动关闭;自动实现线程单例。;(2) 延迟加载(懒加载)(默认加载关闭延迟加载:在.hbm.xml中class增加属性:lazy=”false”.)1)基本原理:当访问实体对象时,并不是立即到数据库中查找,而是在真正要使用实体对象的时候,才去数据库查询数据。具备这样功能的方法:session.load()/等价于session.get()但该方法没有延迟加载。query.iterator()先找到id,然后在调用的时候根据Id一个一个查找。有N+1条查询记录。:/等价于query.list() 这些方法返回的对象,里面没有数据,数据在使用的时候(调用getXXX()方法时)才取。2)实现原理1)load方法,iterator方法返回的对象不是实体类,而是该实体类动态子类对象是与get()方法的区别。,该子类重写了getXXX方法,在该方法中触发了对数据库的访问。-public class User$899323 extends User /重写user属性的get方法 public Object getXXX() /触发查询操作 return 属性值; 动态生成类:一般情况下:a)编译Java源文件:在硬盘上生成二进制.class文件 b)JVM加载.class文件,将类读入一块内存中 c)应用程序调用方法区中的类及方法。动态生成技术,是应用程序直接在内存中创建了一个类,就像我们调用load方法,我们并没有创建Foo$EnhancerByCGLIB$b3a0560c这个类,该类是由Hibernate动态生成的。严格来讲,动态生成类技术不是由Hibernate完成,是由其他组件生成的:a) asm.jar的作用就是在内存中生成类b) cglib-2.1.3.jar对其做了封装,用于生成某个类的子类。注意:自定义的类不要做成final类型,会让动态生成机制失效,因为在很多框架中会运用了这样的动态生成机制。2)当调用load方法或iterator方法时,具体Hibernate调用了GBLIB的功能实现了动态生成子类。原理:a)query.iterate()语句执行结束后,因为延迟加载机制,先执行select t_id from t_foo语句,从数据库中仅仅将id取出; b)在迭代过程中,每次当执行fooIt.next()语句,需要对象数据时,才根据id到数据库中取出全部数据。好处:query.iterator()可以去一级缓存中去找,而query.list()直接去数据库中查找。使用:当对象在缓存存放的几率比较高的时候,使用iterator效率会更高。3)防止session关闭过早方法方法一ThreadLocal能很好的运用到延迟加载中,在企业中广泛应用。:一般在使用时,Session关闭不要写在DAO方法里,而是放在Struts拦截器+ThreadLocal,最后才关闭session.方法二:Hibernate提供的OpenSessionInView技术(了解)a)OpenSessionInView技术把Session的关闭延迟到View组件运行完之后;b)如果用延迟加载必须使用OpenSessionInView技术,否则在取数据时,session已经关闭了。c)使用OpenSessionInView必须满足Session的线程单例-具体使用ThreadLocal.(3) 对象状态对象的三种状态:对于Hibernate而言,对象的状态分为3种。1)暂时态:对象刚创建时,和Session没有发生任何关系时,当程序运行完酒立刻消失,叫暂时态。例如:User user=new User().2)持久态:当一个对象与session发生了关系,例如对象执行了save,get,query等方法对象变为持久态;持久对象存在于Session缓存,由Session负责将对象的状态同步到数据库。注意:只有当事务提交(mit()隐式得调用了session.flush()方法。)和session.flush()之后才更新数据库数据。例子1: - session.save(userUser由临时变成了持久态,在事务提交之前的所有更改都会更新到数据库中去。); user.setPassword(“222”); mit();-最后在数据库中的结构已经修改了密码为222。例子2:知识点:session.fush()运用-Transaction tx=session.beginTransaction(); User user=(User)session.get(User.class,13); user.setNickName(“ssh3”); session.flush();-同步一次 user.setNickName(“ssh4”); mit();-再同步一次 HibernateUtil.closeSession();-执行了两次同步操作同时注意:a)Session中会缓存Session的缓存叫一级缓存。该对象 b)Session再获取对象时,首先去查找一级缓存,如果没有才查询数据库 c)Session要负责将持久态对象的变化更新session.flush()的时候更新,tx在提交的时候会自动调用session的flush();在mit()时会自动调用flush()方法。到数据库。3)游离态:调用了session.evict(Object obj)将对象从session中踢出。方法,和Session脱离了关系。7. 关系映射一对多关系映射:(one-to-many) Order(1)Item(n)1) 首先在Order类中添加一个集合属性Set items;Setter和getter方法;2) 然后在Order.hbm.xml中添加items属性的映射/表示items是一个set集合指定一个外键字段与当前主键关联。指定items集合里面的类型,取得Item对象填充。3) 在程序中可以使用dept.getEmps()获取相关员工对象,注意需要使用延迟加载,不要过早关闭session.One-to-many需求下的常见操作:1. 基本概念基础:t_order(t_id,); t_item(t_id,t_order_id);需求:操作Order的时候一般都需要操作Item2. 基本配置:类:class OrderSetitems;配置文件: 3. 基本操作:a) 保存Order,同时关联的保存Item:使用级联保存:b) 删除Order,同时级联删除与之关联的Item使用级联删除:或者c) 更新Order,Order中解除了和一个Item的关系,希望在数据库中删掉对应的记录或者d) 查询Order,同时带出Item:From Order用select的方式取ItemSelect distinct(o)from Order o join fetch尽量不要放在配置文件中。 o.items用join的方式取Item.e) 查询出包含特定Item的Orderselect i.order from Item i where ductName=select distinct(o)from Order o join fetch o.items i where ductName=f) 查询Order中包含Item的数目:方法一:from Order o;order.getItems().size()方法二:Formula的方式class OrderPrivate int itemsNum;One-to-many(List)业务需求:当查找队伍team时,就查出该team中所有人员person,并且该team中的person是需要有顺序的查出。1) 基础:class TeamListpersons; Class Persont_team(t_id)t_person(t_idt_team_id,t_turn用于排序的属性。)2)配置 2) 操作:同Set的one-to-many;但是,不要inverse=”true”,也就不需要反向关联。Day03多对一关系映射:(many-to-one)Emp(n)-Dept(1)需求1:在去除Emp(many)的时候Dept(one)关联的取出,步骤如下1)首先在Emp类中添加一个部门属性Private Dept dept;setter,getter方法2)然后再Emp.hbm.xml中添加dept属性的映射3)在程序中查询:使用emp.getDept()获取部门信息。Emp emp=(Emp)session.load(Emp.class,1);/延迟加载System.out.println(emp.getId()+”+emp.getName();System.out.println(emp.getDept().getId()得到部门Id.+”+emp.getDept().getDname()+”+emp.getDept().getLocal();Session.close();注意:上面进行了两次查询,如何使用一次查询得到需求表单?-解决方法:使用fetch属性指定抓取方式进行操作。“select”:意思是发送一个select语句抓取;“join”:执行join关联抓取。注意:如何在有些地方使用join,在有些地方不使用join?-解决方法:在HQL语句中可以使用join fetch语句。Session session=HibernateUtil.getSession();String hql=”from Emp e join fetch e.dept where e.id=?进行联合查询。”;Query query=session.createQuery(hql);query.setTnteger(0,1);List list=query.list();for(Emp e:list)System.out.println(e.getId()+”+e.getEname();HibernateUtil.close();查询操作无需使用mit();当使用更改,增加,删除操作时菜需要提交事务,和JDBC相同。-增加一个部门,为该部门增加两个员工:Many-to-one需求下的常见操作:1. 保存Emp:Emp中有已经存在的Dept2. 取出Emp(带着Dept):Emp emp=(Emp)session.get(Emp.class,empId);关联属性默认是延迟加载:但是:取Dept还是用单独的SQL,可以设置fetch方式同时进行:此时用join的方式生成SQL.3. 查询Emp(带着Dept)HQL:from Emp关联属性默认是延迟加载:但是:取Dept还是单独的SQLHQL:from Emp e left outer join fetch e.dept4. 根据特定条件查询Emp(带着Dept):HQL:from Emp e where =HQL:from Emp e left outer join fetch e.dept where =5. 根据Dept的属性查询Emp(带着Dept)HQL:from Emp e where =HQL:from Emp e left outer join fetch e.dept where =与使用细节1) 使用fetch属性指定抓取方式进行操作“select”:意思是发送一个select语句抓取;“join”:执行join关联抓取。2) 使用cascade属性指定级联操作save-update:级联做插入和更新delete:级联做删除all:做所有的操作-删除部门,同时把该部门员工删除 a)现在Dept.hbm.xml中设置级联操作: b)先找到要删除的部门,然后删除。Dept dept=(Dept)session.load(Dept.class,6注意:当使用新建的对象进行删除操作时达不到删除该部门员工的作用。);session.delete(dept);3) inverse指定关系由哪一方维护所谓的关系维护是指d_emp中dept_id字段与d_dept变中的id字段的对等。deptinverse=trueemp关系维护交给对方(emp)负责,当我们对dept对象做级联操作时,不会维护关系,不执行update语句。提示:在One的一方使用inverse=true,会提高对one一方对象级联操作的效率。当在增加和删除操作时,内部使用update维护表与表之间的关系。当对同一个部门插入很多员工的时候,效率会很低过程是:先插入部门,再插入员工,此时员工部门编号为null;再对每一个员工进行update操作,更改部门编号。解决方法:在Dept.nbm.xml中对set元素增加inverse属性为”true”.4)formula属性用于指定一个子查询,使用子查询结果填充属性。使用时,需要注意以下细节:a) formular=”()”,将子查询使用()括起来。b) ()内子查询是SQL语句。c) 子查询语句,表明需要指定别名。-查询部门,班级人数方法一:直接查询public void test3()Session session=HibernateUtil.getSession();String hql=from Banji;Query query=session.createQuery(hql);List banjis=query.list();for(Banji b:banjis)System.out.println(b.getId()+b.getDescription()+b.getXueshengs().size但是效率很低。();HibernateUtil.closeSession();方法二:运用子查询映射a) 给部门增加属性empNum.b) 在Dept.hbm.xml中增加映射。c)在程序中直接查找该属性:public void test4()Session session=HibernateUtil.getSession();String hql=from Dept;Query query=session.createQuery(hql);List depts=query.list();for(Dept b:depts)System.out.println(b.getNo()+b.getDescription()+b.getEmpNum();HibernateUtil.closeSession();多对多关系映射:Student(n)Course(n)1) 基本概念基础:t_student(t_id); t_course(t_id); t_student_course(t_id,t_student_id,t_course_id)第三张表用于维护学生与课程之间的关系。需求:操作Student的时候一般都需要操作Course 操作Course的时候一般都需要操作Student2) 基本配置class StudentPrivate Setcourse;Student.hbm.xml:8. 持久层的特点:所在的数据与数据库中的数据进行同步,映射关联。9. 继承映射9.1继承关系映射到多个表1)基础class Productclass Book extends Productclass Computer extends Productt_product(t_id)t_book(t_product_id)t_computer(t_product_id)没有主键增长,照应t_product表中的id.2) 配置.3) 基本操作保存:Hibernate会根据具体的类型(Book或者Computer)来去等插入哪个子表,父表一定会插入。删除:Hibernate 会根据具体的类型(Book或者Computer)来确定删除哪个子表,父表一定会删除。查询子表:from Book:Hibernate会关联查询t_produtct和t_book查询父类:from Product: Hibernate会关联查询t_product和所有的子表返回的对象是具体的子类类型(可以强制转型)。只查询父类
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025采购合同示范文本
- 合同范本模板哪里有
- 水塔上拆迁合同范本
- 2025新房购房合同范本新房买卖合同的合同范本
- 家电转卖维修合同范本
- 贵州茶叶合同范本
- 荒地补偿协议合同范本
- 瓦房扩建改造合同范本
- 出口长期供货合同范本
- 纸箱模具采购合同范本
- 解读幼儿园教育指导纲要
- 质量异常应对策略与培训实践
- 秘书工作中的职业发展规划研究论文
- 《高处作业安全培训》课件
- 垃圾清运合同范本模板建筑
- 合伙开公司必签的五份协议
- Module9 Unit2 Wishing You Happiness Every Day(说课稿)-2023-2024学年外研版(三起)英语六年级下册
- 粤沪版物理九年级上册第十二章第1节《认识内能》同步练习
- 采油工培训教学计划
- 设计概论讲课课件(第三版杨晓琪)
- 《血管活性药物静脉输注护理》团体标准解读
评论
0/150
提交评论