Hibernate学习笔记

1.配置hibernate.cfg.xml

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
          "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
          "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<!-- Generated by MyEclipse Hibernate Tools.                   -->
<hibernate-configuration>

<session-factory>
    <property name="connection.username">root</property>
    <property name="connection.url">
        jdbc:mysql://localhost:3306/test
    </property>
    <property name="dialect">
        org.hibernate.dialect.MySQLDialect
    </property>
    <property name="connection.password">1234</property>
    <property name="connection.driver_class">
        com.mysql.jdbc.Driver
    </property>
    <property name="myeclipse.connection.profile">mydiver</property>
    <property name="format_sql">true</property>
     <property name="hibernate.hbm2ddl.auto">update</property>
    <property name="show_sql">true</property>
    <mapping resource="com/haoyi/pojo/BookTbl.hbm.xml" />
    <mapping resource="com/haoyi/pojo/Department.hbm.xml" />
    <mapping resource="com/haoyi/pojo/Employee.hbm.xml" />
        <mapping resource="com/haoyi/pojo/Person.hbm.xml" />
            <mapping resource="com/haoyi/pojo/IdCard.hbm.xml" />
            <mapping resource="com/haoyi/pojo/Teacher.hbm.xml" />
            <mapping resource="com/haoyi/pojo/Student.hbm.xml" />
</session-factory>

</hibernate-configuration>

2.对session等的重复代码,我写了一个单例,只让他做一次

public final class HibernateUtil {
    private static SessionFactory sessionFactory;
 
private HibernateUtil(){
     
}
static
{
    //1.读取配置文件信息
     Configuration cf = new Configuration().configure();
     
    //2.建造一个sessionfactory
     sessionFactory =cf.buildSessionFactory();
    //3.打开一个session
}
 
public static SessionFactory getSessionFactory() {
        return sessionFactory;
    }
 public static Session getSession(){
     return sessionFactory.openSession();
 }
}

3.基本概念和CURD

lSession的几个主要方法

1.save,persist保存数据,persist在事务外不会产生insert语句。
2.delete,删除对象
3.update,更新对象,如果数据库中没有记录,会出现异常。
4.get,根据ID查,会立刻访问数据库。
5.Load,根据ID查,(返回的是代理,不会立即访问数据库)。
6.saveOrUpdate,merge(根据ID和version的值来确定是save或update),调用merge你的对象还是托管的。
7.lock(把对象变成持久对象,但不会同步对象的状态)

4.对象状态

l瞬时(transient):数据库中没有数据与之对应,超过作用域会被JVM垃圾回收器回收,一般是new出来且与session没有关联的对象。
l持久(persistent):数据库中有数据与之对应,当前与session有关联,并且相关联的session没有关闭,事务没有提交;持久对象状态发生改变,在事务提交时会影响到数据库(hibernate能检测到)
l脱管(detached):数据库中有数据与之对应,但当前没有session与之关联;托管对象状态发生改变,hibernate不能检测到。
 

5.HQL(Hibernate Query Language)

面向对象的查询语言,与SQL不同,HQL中的对象名是区分大小写的(除了JAVA类和属性其他部分不区分大小写);HQL中查的是对象而不是和表,并且支持多态;HQL主要通过Query来操作,Query的创建方式:
Query q = session.createQuery(hql);
lfrom Person
lfrom User user where user.name=:name
lfrom User user where user.name=:name and user.birthday < :birthday

6.关联映射

多对一(Employee - Department)
映射文件<many-to-one name=”depart” column=”depart_id”/>
 
一对多(Department-Employee)
<set name=”employees”>
<key column=”depart_id”/>
<one-to-many class=”Employee”/>
</set>
一对一(Person - IdCard)
1)基于主键的one-to-one(person的映射文件)
<id name=”id”>
<generator class=”foreign”><param name=”property”>idCard</param></generator>
<id>
<one-to-one name=”idCard” constrained=”true”/>
2)基于外健的one-to-one,可以描述为多对一,加unique=“true”约束
<one-to-one name=”idCard” property-ref=“person”/>
             property-ref用于指定关联类的一个属性,这个属性将会和本外键相对应
<many-to-one name=”person” column=”person_id” unique=”true” not-null=”true”/>
 <!-唯一的多对一,其实就便成了一对一了-->
 
多对多(teacher - student)
在操作和性能方面都不太理想,所以多对多的映射使用较少,实际使用中最好转换成一对多的对象模型;Hibernate会为我们创建中间关联表,转换成两个一对多。
<set name="teacher" table="teacher_student">
<key column="teacher_id"/>
<many-to-many class="Student" column="student_id"/>
</set>
 
组件映射(User-Name)
关联的属性是个复杂类型的持久化类,但不是实体即:数据库中没有表与该属性对应,但该类的属性要之久保存的。
<component name=”name” class=”com.test.hibernate.domain.Name”>
<property name=”initial”/>
<property name=”first”/>
<property name=”last”/>
</component>
当组件的属性不能和表中的字段简单对应的时候可以选择实现:
org.hibernate.usertype. UserType或
org.hibernate.usertype. CompositeUserType

7.集合映射

集合映射(set, list, array,bag, map)
l这些集合类都是Hibernate实现的类和JAVA中的集合类不完全一样,set,list,map分别和JAVA中的Set,List,Map接口对应,bag映射成JAVA的List;这些集合的使用和JAVA集合中对应的接口基本一致;JAVA的实体类中集合只能定义成接口不能定义成具体类, 因为集合会在运行时被替换成Hibernate的实现。
l集合的简单使用原则:大部分情况下用set,需要保证集合中的顺序用list,想用java.util.List又不需要保证顺序用bag。
 
cascadeinverse (Employee – Department)
lCasade用来说明当对主对象进行某种操作时是否对其关联的从对象也作类似的操作,常用的cascade:
none,all,save-update ,delete, lock,refresh,evict,replicate,persist,
merge,delete-orphan(one-to-many) 。一般对many-to-one,many-to-many不设置级联,在<one-to-one>和<one-to-many>中设置级联。
 
linverse表“是否放弃维护关联关系”(在 Java里两个对象产生关联时,对数据库表的影响),在one-to-many和many-to-many的集合定义中使 用,inverse=”true”表示该对象不维护关联关系;该属性的值一般在使用有序集合时设置成false(注意hibernate的缺省值是 false)。
one-to-many维护关联关系就是更新外键。many-to-many维护关联关系就是在中间表增减记录。
注: 配置成one-to-one的对象不维护关联关系
自己理解:一般在一对多里,让一的一端放弃对关系的维护,这样效率高

8.懒加载

通过asm和cglib二个包实现;Domain是非final的。
1.session.load懒加载。
2.one-to-one(元素)懒加载:
必需同时满足下面三个条件时才能实现懒加载
(主表不能有constrained=true,所以主表没有懒加载)
lazy!=false 2)constrained=true 3)fetch=select
3.one-to-many (元素)懒加载:1)lazy!=false 2)fetch=select
4.many-to-one (元素) :1)lazy!=false 2)fetch=select
5.many-to-many (元素) :1)lazy!=false 2)fetch=select
6.能够懒加载的对象都是被改写过的代理对象,当相关联的session没有关闭时,访问这些懒加载对象(代理对象)的属性(getId和 getClass除外)hibernate会初始化这些代理,或用Hibernate.initialize(proxy)来初始化代理对象;当相关联的 session关闭后,再访问懒加载的对象将出现异常。

9.Hibernate不适合的场景

1.不适合OLAP(On-Line Analytical Processing联机分析处理),以查询分析数据为主的系统;适合OLTP(on-line transaction processing联机事务处理)。

2.对于些关系模型设计不合理的老系统,也不能发挥hibernate优势。
3.l数据量巨大,性能要求苛刻的系统,hibernate也很难达到要求, 批量操作数据的效率也不高。
 
原文链接:http://www.cnblogs.com/xiaomuv587/archive/2012/09/29/2708544.html
原文地址:https://www.cnblogs.com/gengaixue/p/4674177.html