Hibernate基础应用笔记
一、Hibernate
Hibernate是一个ORM(Object Relational Mapping)框架,使应用程序更加专注于如何使用业务对象去实现逻辑功能,而不必耗费精力去关心底层数据库的相关操作。
二、Hibernate操作需要认识的API
Session接口:Session接口负责执行持久化对象的CRUD操作。同时Session对象是非线程安全的。及多个Session可并发访问同一数据库资源;
SessionFactory接口:SessionFactory接口负责初始化Hibernate.它充当数据存储源的代理,并负责创建Session对象。
1、一般情况下,一个项目通常只需要一个SessionFactory就够了,当需要操作多个数据库时,可以为每个数据库指定一个SessionFactory。
Configuration接口:Configuration接口负责配置并启动Hibernate,创建SessionFactory对象。
1、Hibernate应用时,首先创建Configuration对象config,然后调用config.configure(path)读取Hibernate配置文件hibernate.cfg.xml中的配置(path默认为classpath目录下的hibernate.cfg.xml);
2、此配置文件中<session-factory>标签设置了SessionFactory创建所需的信息。所以再调用config.BuildSessionFactory()方法来创建出SessionFactory对象;
Transaction接口:Transaction接口负责事务相关的操作。
1、Hibernate默认使用JDBC进行事务处理。
2、当调用SessionFactory创建Session是,Hibernate会初始化数据库连接,并将AutoCommit设置为false。调用Session对象的beginTransaction方法时,Hibernate会再次确认AutoCommit是否是false。所以获取Session后,此时的AutoCommit已经为false。所以Session中的CURD操作必须放在事务中,操作完成后调用事务的commit()方法提交后才能在数据库中产生效果。
3、开发中也可以设计编写自己的底层事务处理代码。
Query和Criteria接口:Query和Criteria接口负责执行各种数据库查询。它可以使用HQL语言或SQL语句两种表达方式。
三、持久化对象的生命周期
注(个人理解):ORM根本任务是数据库的CURD,而在Hibernate这里可以看成是建立数据库与持久化对象之间的联系,Hibernate为其中的持久化对象定义了三种状态,并定义了相关的状态之间的转化的操作,来建立数据库与持久化对象的联系,从而完成CURD。但不仅仅是简单的CURD,通过这种模式Hibernate还可以对CURD附加了更多的功能。总而言之,这是Hibernate对数据库操作的一种方式。
Hibernate中,每一个持久化对象都是有生命周期的,整个生命周期分为三种状态:
Transient(自由态):指的是对象在内存中存在,但是在数据库中并没有数据与其关联。自由态对象的状态如何改变,不影响数据库。
Persistent(持久态):持久化对象处于由Hibernate管理的状态,这种状态下,持久化对象的状态变化将会被同步到数据库中。
Detached(游离态):处于持久态的对象,在其对应的Session实例关闭后,对象进入游离态。也就是说Session实例是持久态对象的宿主环境,一旦宿主环境失效,那么持久态对象进入游离态。
三种状态的转换
load和get方法:get和load方法都是利用对象的主键值获取相应的对象,并可以使对象处于持久状态。load方法获取对象时不会立即执行查询操作,而是在第一次使用对象时才执行查询操作(称为延迟加载)。如果查询的对象在数据库中不存在,load方法返回值不会为null,二是直接抛出异常。使用get方法获取对象时会立即执行查询操作,并且对象在数据库中不存在时返回null值。
persist和save方法:这两个方法都用于将对象持久化到数据库中,并把对戏那个转换为持久化状态,在对象的操作是没有区别的。persist方法是为了和JPA的使用方法统一而创建的。
save和update方法:两个方法都可以将自由态的对象进行保存,并转换为持久状态。update方法还可以将游离态的对象进行保存。
update和saveOrUpdate方法:不管对象是什么状态,update方法都只会做简单的更新操作,如果对象在数据库中不存在,则update方法操作没有意义,否则数据库中的数据会同步更新。在执行saveOrUpdate方法时该方法会自动判断对象的状态,如果为自由态则执行save操作,如果为游离态或持久态则执行update操作。
update和merge方法:如果持久化徐I想在数据库中存在,使用merge操作时进行同步更新操作。如果对象在数据库中不存在,merge对象则进行保存操作。如果对象是游离状态,经过update操作后,对象转换为持久态。但是经过merge操作后,对象状态依然是游离态。
saveOrUpdate和merge方法:saveOrUpdate方法和merge方法的区别在于如果session中存在两个主键值相同的对象,进行saveOrUpdate操作时会有异常抛出。这是必须使用merge操作。(这是因为saveOrUpdate对自由态的对象执行save操作)
clear和flush方法:clear方法时将Session中对象全部清除,当前在Session中的对象由持久态转换为游离态。flush方法则是将持久态对象的更改同步到数据库中。
四、Hibernate对象关系映射
1、一对多映射
1 <!-- t_address表配置 --> 2 <hibernate-mapping> 3 <class name="com.onetomany.User" table="t_user"> 4 <id name = "id"> 5 <generator class="sequence"> 6 <param name="sequence">PK</param> 7 </generator> 8 </id> 9 <property name="name"></property> 10 <property name = "age"></property> 11 <set name= "address"> 12 <!-- key标签配置t_address表中的外键字段userid --> 13 <key column = "userid"></key> 14 <one-to-many class="com.onetomangy.Address"/> 15 </set> 16 </class> 17 </hibernate-mapping>
1 <!-- t_address表配置 --> 2 <hibernate-mapping> 3 <class name="com.onetomany.Address" table="t_address"> 4 <id name = "id"> 5 <generator class="sequence"> 6 <param name="sequence">PK</param> 7 </generator> 8 </id> 9 <property name="address"></property> 10 <property name = "tel"></property> 11 <property name = "zipCode"></property> 12 <!-- userid为t_address表中的外键字段 --> 13 <many-to-one name="user" 14 class = "com.onetomany.User" column = "userid"> 15 </many-to-one> 16 </class> 17 </hibernate-mapping>
2、一对一映射
1 <!-- t_person表配置 --> 2 <hibernate-mapping> 3 <class name = "com.onetoone.Person" table = "t_person"> 4 <id name = "id"> 5 <generator class="sequence"> 6 <param name = "sequence">PK</param> 7 </generator> 8 </id> 9 <property name = "name"></property> 10 <one-to-one name = "card" class ="com.onetoone.Card"></one-to-one> 11 </class> 12 </hibernate-mapping>
1 <!-- t_card表配置 --> 2 <hibernate-mapping> 3 <class name = "com.onetoone.Person" table = "t_card"> 4 <id name = "id"> 5 <generator class="foreign"> 6 <param name = "property">person</param> 7 </generator> 8 </id> 9 <property name = "cardNum"></property> 10 <one-to-one name = "person" class ="com.onetoone.Person"></one-to-one> 11 </class> 12 </hibernate-mapping>
3、多对多映射
1 <!-- t_teacher表配置 --> 2 <hibernate-mapping> 3 <class name = "com.manytomany.Teacher" table = "t_teacher"> 4 <id name = "id"> 5 <generator class="sequence"> 6 <param name = "sequence">PK</param> 7 </generator> 8 </id> 9 <property name = "name"></property> 10 <set name = "student" table ="t_student_teacher"> 11 <key column = "teacherid"></key> 12 <many-to-many column = "studentid" class="com.manytomany.Student"></many-to-many> 13 </set> 14 </class> 15 </hibernate-mapping>
1 <!-- t_student表配置 --> 2 <hibernate-mapping> 3 <class name = "com.manytomany.Student" table = "t_student"> 4 <id name = "id"> 5 <generator class="sequence"> 6 <param name = "sequence">PK</param> 7 </generator> 8 </id> 9 <property name = "name"></property> 10 <set name = "teacher" table ="t_student_teacher"> 11 <key column = "studentid"></key> 12 <many-to-many column = "teacherid" class="com.manytomany.Teacher"></many-to-many> 13 </set> 14 </class> 15 </hibernate-mapping>
inverse属性的作用:负责控制关系,默认为false,也就是关系的两端都能控制,但这样会造成一些问题,更新的时候会因为两端都控制关系,于是重复更新。一般来说有一端要设为true。
Cascade:负责控制关联对象的级联操作,有一下几个值save-update(在执行保存和修改时进行级联操作),delte(在执行删除时进行级联操作),all(在所有情况下进行级联操作),none(不进行级联操作);none为默认值。