Hibernate(三)

持久化:

所谓的持久化,就是将内存中的数据永久存储到关系型数据库中。

持久化类:

指一个java类与数据库表建立了映射关系,那么这个类称为持久化类。

持久化类的编写规则:

*持久化类需要提供无参数的构造函数。因为在Hibernate的底层需要使用反射生成类的实例。

*持久化类的属性需要私有,对私有的属性提供公有的get和set方法。因为在Hibernate的底层会将查询到的数据进行封装。

*持久化类的属性要尽量使用包装类的类型。因为包装类和基本数据类型的默认值不同,包装类的类型语义描述更清晰而基本数据类型不容易描述。

*持久化类要有一个唯一标识OID与表的主键对应。在Java中通过地址区分是否是同一个对象,在关系型数据库的表中是通过主键区分是否是同一条记录,而Hibernate需要通过这个唯一标识OID区分在内存中是否是同一个持久化类。Hibernate是不允许在内存中出现两个OID相同的持久化对象的。

*持久化类尽量不要使用final进行修饰。因为Hibernate中有延迟加载的机制,这个机制中会产生代理对象,Hibernate产生代理对象使用的是字节码的增强技术完成的,其实就是产生了当前类的一个子类对象实现的。如果使用了final修饰持久化类,就不能产生子类,从而就不能产生代理对象,那么Hibernate的延迟加载策略(是一种优化手段)就会失效。

主键的类型:

*自然主键:主键的本身就是表中的一个字段实体中的一个具体属性),具有业务含义,称为自然主键。例如客户表中,如果把name字段作为主键,其前提条件是:每一个客户的姓名不允许为null,不允许客户重名,并且不允许修改客户姓名。不能满足不断变化的业务需求,一旦出现了客户重名的业务需求,就必须修改数据类型,重新定义表的主键,给数据库的维护增加了难度。

*代理主键:主键的本身不是表中必须的一个字段不是实体中某个具体属性),不具有业务含义,称为代理主键。一般取名为ID,通常为整数类型。

实际开发中,尽量使用代理主键。

主键生成策略:

【increment】:Hibernate提供的自动增长机制,适用short、long、int类型的主键。在单线程中使用。

首先发送一条语句:select  max(id)  from  表,然后id+1作为下一条记录的主键。

【identity】:适用short、long、int类型的主键,采用的是数据库底层的自动增长机制,条件是数据库支持自动增长数据类型(mysql、DB2)。Oracle没有自动增长。

【sequence】:适用short、long、int类型的主键,根据底层数据库序列生成标识符。Oracle支持序列。mysql就不能使用序列。

native】:本地策略,可以在identity和sequence之间进行自动切换。

【uuid】:适用于字符串类型的主键,采用128位的UUID算法生成标识符。

【assigned】:Hibernate放弃外键的管理,需要通过手动编写程序或用户自己设置。

主键生成策略在映射配置文件中设置:

持久化类的三种状态:

在Hibernate中持久化的对象可以划分为三种状态:瞬时态、持久态、托管态

瞬时态(transient)】:没有唯一的标识OID、没有被session管理。

持久态(persistent)】:存在唯一的标识OID、被session管理。持久化类的持久态对象可以自动更新数据库。

托管态(detached)】:存在唯一的标识OID、没有被session管理。

public class HibernateDemo1 {
 
	@Test
	public void demo1() {

		Session session = HibernateUtils.getSession();
		Transaction transaction = session.beginTransaction();

		Customer customer = new Customer();//瞬时态对象:没有唯一标识OID,没有被session管理
		customer.setCust_name("赵武");
		
		session.save(customer);//持久态对象:有唯一标识OID,被session管理

		transaction.commit();	
		session.close();

        System.out.println(customer);//托管态对象:有唯一标识OID,没有被session管理
	}
	
}

Hibernate持久化对象的三种状态转换:

1、瞬时态:

【获得】:Customer customer = new Customer();

【瞬时态---->持久态】:save()、saveOrUpdate()执行save方法

【瞬时态---->托管态】:为瞬时态对象设置持久化标识。customer.setCust_id(1l);

2、持久态

【获得】:get()、load()、find()、iterate()

【持久态---->瞬时态】:delete()

【持久态---->托管态】:close()、clear()清除一级缓存的所有对象、evict(Object  obj)清除一级缓存中的某一个对象。

3、脱管态

【获得】:Customer customer = new Customer();    customer.setCust_id(1l);

【脱管态---->瞬时态】:customer.setCust_id(null);

【脱管态---->持久态】:update()、saveOrUpdate()执行update方法

持久态对象特性:

持久态对象能够自动更新数据库

public class HibernateDemo1 {
 
	@Test
	public void demo1() {

		Session session = HibernateUtils.getSession();
		Transaction transaction = session.beginTransaction();

        //获得持久态对象
		Customer customer = session.get(Customer.class,1l);
		customer.setCust_name("赵武");
		
		//session.update(customer);//不用手动调用update方法就可以更新

		transaction.commit();	
		session.close();
	}	
}

save()方法

  • save()方法使一个瞬时态对象转变为持久态对象
  • session的save()方法完成以下操作:
    • 把News对象加入到session缓存中,使它进入持久化状态
    • 选用映射文件指定的标识符生成器,为持久化对象分配唯一的OID。在使用代理主键的情况下,setId()方法为News对象设置OID是无效的。
    • 计划执行一条insert语句:在flush缓存的时候
  • persist()和save()区别
    • 当对一个OID不为null的对象执行save()方法时,会把该对象以一个新的oid保存到数据库中;但执行persist()方法时会抛出一个异常。

update()方法

  • update()方法使一个托管态对象变为持久态对象,并且计划执行一条update语句
  • 若希望session仅当修改了News对象的属性时,才执行update()语句,可以把映射文件中<class>元素的select-before-update设为true。该属性的默认值为false
  • 当update()方法关联一个脱管态对象时,如果在session的缓存中已经存在相同的OID的持久态对象时,会抛出异常
  • 当update()方法关联一个脱管态对象时,如果数据库中不存在相应的记录,也会抛出异常。

saveOrUpdate()方法

  • saveOrUpdate()方法同时包含了save()与update()方法的功能
  • 判定对象为临时对象的标准
    • java对象的OID为null
    • 映射文件中为<id>设置了unsaved-value属性,并且java对象的OID取值与这个unsaved-value属性值匹配。

delete()方法

  • delete()方法即可以删除一个脱管态对象,也可以删除一个持久态对象
  • delete()方法处理过程:
    • 计划执行一条delete语句
    • 把对象从session缓存中删除,该对象进入删除状态
  • Hibernate的cfg.xml配置文件中有一个hibernate.use_identifier_rollback属性,其默认值为false,若把它设置为true,将改变delete()方法的运行行为:delete()方法会把持久态对象或脱管态对象的OID设置为null,使它们变成瞬时态对象。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值