chapter3chapter3_第1页
chapter3chapter3_第2页
chapter3chapter3_第3页
chapter3chapter3_第4页
chapter3chapter3_第5页
已阅读5页,还剩7页未读 继续免费阅读

下载本文档

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

文档简介

Chapter3 Hibernate的持久化*课程回顾:Hibernate框架入门*1. Hibernate框架的概述:ORM2. 框架的入门的程序* 编写映射的配置文件* 编写核心的配置文件* 编写程序3. 配置的文件4. 使用的接口和方法*教学导航*1. Hibernate持久化对象的状态2. Hibernate操作持久化对象的方法3. 注解配置一、什么是持久化类1. 持久化类:就是一个Java类(咱们编写的JavaBean),这个Java类与表建立了映射关系就可以成为是持久化类,这个类就称为是持久化类也有人称之为POJO类。* 持久化类 = JavaBean + xxx.hbm.xml二、持久化类的编写规则1. 提供一个无参数 public访问控制符的构造器- 底层需要进行反射.2. 提供一个标识属性,映射数据表主键字段- 唯一标识OID.数据库中通过主键.Java对象通过地址确定对象.持久化类通过唯一标识OID确定记录3. 所有属性提供public访问控制符的 set或者get 方法4. 标识属性应尽量使用基本数据类型的包装类型及建议实现序列化接口三、持久化类对象的状态及转换操作Hibernate为了管理持久化类:将持久化类分成了三个状态* 瞬时态:Transient Object* 没有持久化标识OID, 没有被纳入到Session对象的管理.* 持久态:Persistent Object* 有持久化标识OID,已经被纳入到Session对象的管理.* 脱管态:Detached Object* 有持久化标识OID,没有被纳入到Session对象的管理.Hibernate持久化对象的状态的转换1. 瞬时态(临时)- 没有持久化标识OID, 没有被纳入到Session对象的管理获得瞬时态的对象User user = new User()瞬时态对象转换持久态 save()/saveOrUpdate();瞬时态对象转换成脱管态 user.setId(1)2. 持久态- 有持久化标识OID,已经被纳入到Session对象的管理获得持久态的对象 get()/load();持久态转换成瞬时态对象delete(); - 比较有争议的,进入特殊的状态(删除态:Hibernate中不建议使用的)持久态对象转成脱管态对象 session的close()/evict()/clear();3. 脱管态(游离)- 有持久化标识OID,没有被纳入到Session对象的管理获得脱管态对象:不建议直接获得脱管态的对象.User user = new User();user.setId(1);脱管态对象转换成持久态对象update();/saveOrUpdate()/lock();脱管态对象转换成瞬时态对象user.setId(null);4. 注意:持久状态对象有自动更新数据库的能力!/ 持久化对象具有自动更新数据库的能力 Test public void test2() / 1.得到session Session session = HibernateUtil.getSession(); session.beginTransaction(); Customer customer = session.get(Customer.class, 1); / 查询id=1的Customer对象,如果查询到,会将Customer对象存到一级缓存中 customer.setName(Tom); / 操作持久化对象来修改属性 / 2.事务提交,并关闭session session.getTransaction().commit(); session.close(); Hibernate对象常用状态切换实例1. Transient(瞬时状态)session = HibernateUtil.openSession();session.beginTransaction();User user = new User();user.setUsername(aaa);user.setPassword(aaa);user.setBorn(new Date();/* 以上user就是一个Transient(瞬时状态),此时user并没有被session进行托管,即在session的* 缓存中还不存在user这个对象,当执行完save方法后,此时user被session托管,并且数据库中存在了该对象* user就变成了一个Persistent(持久化对象)*/session.save(user);/如果两个对象中的值不一致就会继续发出相应的sql语句user.setPassword(bbb);/此时会发出2条sql,一条用户做插入,一条用来做更新session.getTransaction().commit();Save()方法运行时我们知道hibernate会发出一条insert的语句,执行完save方法后,该user对象就变成了持久化的对象了。后面user又重新修改了属性值,那么在提交事务时,此时hibernate对象就会拿当前这个user对象和保存在session缓存中的user对象进行比较,如果两个对象相同,则不会发送update语句,否则,如果两个对象不同,则会发出update语句。记住一点:如果一个对象以经是持久化状态了,那么此时对该对象进行各种修改,或者调用多次update、save方法 时,hibernate都不会发送sql语句,只有当事物提交的时候,此时hibernate才会拿当前这个对象与之前保存在session中的持久化对 象进行比较,如果不相同就发送一条update的sql语句,否则就不会发送update语句。session = HibernateUtil.openSession();session.beginTransaction();/此时u是一个离线对象,没有被session托管User u = new User();u.setId(4);u.setPassword(hahahaha);/当执行save的时候总是会添加一条数据,此时id就会根据Hibernate所定义的规则来生成/session.save(u);/完成update之后也会变成持久化状态session.update(u);/u已经变成了一个持久化的对象,那么如果此时对u对象进行修改操作后,在事务提交的时候,则会拿该对象和session中刚保存的持久化对象进行比较,如果不同就发一条sql语句。session.getTransaction().commit();2. Transient(瞬时状态)当save一执行的时候,此时发送一条插入的语句,因此对于离线对象,如果要使其变成持久化对象的话,我们不能使用save方法,而应该使用update方法。如果在commit()方法之前u.setUsername(world);/会发出一条sqlsession.update(u);此时对u对象再进行修改操作后,在事务提交的时候,则会拿该对象和session中刚保存的持久化对象进行比较,如果不同就发一条sql语句。如果在commit()方法之前u.setUsername(lisi);/会抛出异常u.setId(333);调用update方法后,user变成了一个持久化对象,在对user进行一些修改后,此时又通过 u.setId(333)方法设置了u的ID,那么这个时候,hibernate会报错,因为我们的u当前已经是一个持久化对象,如果试图修改一个持久化 对象的ID的值的话,就会抛出异常,这点要特别注意。小结:.对于刚创建的一个对象,如果session中和数据库中都不存在该对象,那么该对象就是瞬时对象(Transient).瞬时对象调用save方法,或者离线对象调用update方法可以使该对象变成持久化对象,如果对象是持久化对象时,那么对该对象的任何修改,都会在提交事务时才会与之进行比较,如果不同,则发送一条update语句,否则就不会发送语句.离线对象就是,数据库存在该对象,但是该对象又没有被session所托管四、区分自然主键和代理主键1. 创建表的时候* 自然主键:对象本身的一个属性.如创建一个人员表,每个人都有一个身份证号.(唯一的)使用身份证号作为表的主键.自然主键.(开发中不会使用这种方式)* 代理主键:不是对象本身的一个属性. 如创建一个人员表,为每个人员单独创建一个字段id.用这个字段作为主键.代理主键.(开发中推荐使用这种方式)2. 创建表的时候尽量使用代理主键创建表五、主键的生成策略1. increment:适用于short,int,long作为主键.不是使用的数据库自动增长机制。Hibernate中提供的一种增长机制。先进行查询:select max(id) from user;再进行插入:获得最大值+1作为新的记录的主键。问题:不能在集群环境下或者有并发访问的情况下使用.2. identity:适用于short,int,long作为主键。但是这个必须使用在有自动增长数据库中.采用的是数据库底层的自动增长机制。底层使用的是数据库的自动增长(auto_increment).像Oracle数据库没有自动增长。如MySQl中是auto_increment, SQL Server 中是Identity。支持的数据库有MySql、SQL Server、DB2、Sybase和HypersonicSQL。3. sequence:适用于short,int,long作为主键.底层使用的是序列的增长方式。 Oracle数据库底层没有自动增长,想自动增长需要使用序列。支持sequence的数据库有:Oracle 、DB2(Mysql/SQlServer不支持)、PostgreSql、SAPDb等4. uuid:适用于char,varchar类型的作为主键。 使用随机的字符串作为主键。5. native:本地策略.根据底层的数据库不同,自动选择适用于该种数据库的生成策略.(short,int,long) :根据数据库的类型,自动在sequence 、identity和,hilo进行切换。如果底层使用的MySQL数据库:相当于identity。如果底层使用Oracle数据库:相当于sequence。6. assigned:主键的生成不用Hibernate管理了.必须手动设置主键。在程序中session.save();之前,由程序员自己指定主键值为多少。例如:user.setId(1);这就是在程序中程序员手动为用户表指定主键值为1。 Hibernate主键生成策略分类UUID,increment、Hilo、assigned:对数据库无依赖identity:依赖Mysql或sql server,主键值不由hibernate维护sequence:适合于oracle等支持序列的dbms,主键值不由hibernate维护,由序列产生。native:根据底层数据库的具体特性选择适合的主键生成策略,如果是mysql或sqlserver,选择identity,如果是oracle,选择sequence。六、注解方式配置Hibernate JPA主键策略PA的4种策略,分别为:AUTO策略,Sequence策略,Identity策略,Table策略。auto策略是JPA默认的策略,在hibernate的代码 GenerationType.AUTO 进行定义。使用 AUTO 策略就是将主键生成的策略交给持久化引擎 (persistence engine) 来决定,由它自己从 Table 策略,Sequence 策略和 Identity策略三种策略中选择最合适的。EntityTable(name = t_customer)public class Customer IdGeneratedValue(strategy = GenerationType.AUTO)Column(name = id)private Integer id;注意:1、如果是mysql数据库,一定要将主键列设置成自增长的,否则使用AUTO策略的时候,会报错:org.hibernate.exception.GenericJDBCException: Field id doesnt have a default value2、如果是oracle数据库,那么会使用hibernate_sequence,这个名称是固定的,不能更改。Sequence对应Hibernate代码 GenerationType.SEQUENCE 。一些数据库,如oracle就会内置序列生成器。为了使用序列,我们需要使用JPA的sequence策略。EntityTable(name = t_customer)public class Customer IdGeneratedValue(strategy = GenerationType.SEQUENCE, generator = mySeqGenerator)SequenceGenerator(name = mySeqGenerator, sequenceName = t_customer_sequence, initialValue = 1000, allocationSize = 50)Column(name = id)这里需要配合使用SequenceGenerator,用来指定序列的相关信息。name:序列生成器的名称,会在GeneratedValue中进行引用sequenceName:oracle数据库中的序列生成器名称initialValue:主键的初始值allocationSize:主键每次增长值的大小注意:如果底层数据库不执行序列,会报错:org.hibernate.MappingException: org.hibernate.dialect.MySQLDialect does not support sequencesIdentity对应Hibernate代码 GenerationType.IDENTITY 。 这个很适合像mysql这样的数据库,提供了对自增主键的支持。EntityTable(name = t_customer)public class Customer IdGeneratedValue(strategy = GenerationType.IDENTITY)Column(name = id)private Integer id;Table策略对应Hibernate代码 GenerationType.TABLE 。 使用一张特殊的数据库表,保存插入记录的时,需要的主键值。Hibernate注解入门一、 实体类/javax.persistence导入这个包下的包不然会不符/* * 客户*/EntityTable(name = CST_CUSTOMER)public class Customer IdGeneratedValue(strategy = GenerationType.IDENTITY)Column(name = cust_id) private Long cust_id;Column(name = cust_name) private String cust_name;Column(name = cust_user_id) private Long cust_user_id; private Long cust_create_id; private String cu

温馨提示

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

评论

0/150

提交评论