hibernate

hibernate入门
    hibernate是JavaEE 轻量级持久层(dao)框架
    ORM框架:对象关系映射(Object/Relation Mapping)就是将Java对象(JavaBean)映射到数据库表,通过操作Java对象(ORM框架提供api),就可以完成对数据表的操作
    hibernate是一个ORM框架
    流行数据库框架
        JPA,javaee提供一种规范(接口)
        hibernate
        MyBatis apache框架
        Apache DBUtils
        Spring JDBCTemplate
    hibernate版本:hibernate-distribution-3.6.10.Final



Hibernate的优点
    Hibernate对JDBC访问数据库的代码做了封装,大大简化了数据访问层繁琐的重复性代码
    Hibernate是一个基于jdbc的主流持久化框架,是一个优秀的orm实现,它很大程度的简化了dao层编码工作
    Hibernate使用java的反射机制
    Hibernate的性能非常好,因为它是一个轻量级框架。映射的灵活性很出色。它支持很多关系型数据库,从一对一到多对多的各种复杂关系



hibernate配置文件
    hibernate主配置文件
        名称: 固定,hibernate.cfg.xml
        位置: 固定,src
        作用: 配置数据库连接信息
        注册: 不需要注册
    hibernate映射文件
        名称: 任意,需要在主配置文件中注册(推荐:javaBean名称.hbm.xml)
        位置: 任意,需要在主配置文件中注册(推荐:javaBean同包)
        作用: 配置javaBean与表的对应关系
        注册: 需要在主配置文件中注册



hibernate编写流程
    1. 导入jar包(/hibernate/hibernate-distribution-3.6.10.Final)
        数据库驱动
        核心jar: /hibernate3.jar
        必须jar: /lib/required/*.jar
        jpa jar: /lib/jpa/*.jar
    2. 编写javabean与hbm.xml文件
        hbm.xml位置:javabean同包
        hbm.xml约束文件位置:hibernate3.jar/org.hibernate/hibernate-mapping-3.0.dtd
    3. 编写主配置文件:hibernate.cfg.xml,将所有的hbm.xml文件注册
        hibernate.cfg.xml位置:/src
        hibernate.cfg.xml约束文件位置:hibernate3.jar/org.hibernate/hibernate-configuration-3.0.dtd
    4. 通过hibernate提供的api操作



helloworld搭建
    1 导入jar包 (9 jar)(/hibernate/hibernate-distribution-3.6.10.Final)
        数据库驱动
        核心jar: /hibernate3.jar
        必须jar: /lib/required/*.jar
        jpa jar: /lib/jpa/*.jar
        jar介绍
            hibernate3.jar                          核心jar
            antlr-2.7.6.jar                         一个语言转换工具,hibernate利用它实现HQL到SQL的转换
            commons-collections-3.1.jar             collections Apache 的工具集,用来增强java对集合的处理能力
            dom4j-1.6.1.jar                         dom4j XML 解析器
            hibernate-jpa-2.0-api-1.0.1.Final.jar   JPA 接口开发包
            javassist-3.12.0.GA.jar                 代码生成工具,Hibernate用它在运行时扩展Java类
            jta-1.1.jar                             表中的JAVA事务(跨数据库)处理接口
            slf4j-log4j12-1.7.2.jar                 Hibernate使用的一个日志系统
    2 编写javabean与hbm.xml文件
        javaBean
            名称: User
            属性: 
                Integer userId;
                String username;
                String password;
        映射文件
            名称: User.hbm.xml
            位置: User类同包
            内容:
                <?xml version="1.0" encoding="UTF-8"?>
                <!DOCTYPE hibernate-mapping PUBLIC 
                    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
                    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
                <hibernate-mapping>
                    <!-- 描述 对象 与 表 映射 -->
                    <class name="cn.itcast.a_hello.User" table="t_user">
                        <!-- 主键配置 -->
                        <id name="userId">
                            <!-- 主键生成策略 -->
                            <generator class="native"></generator>
                        </id>
                        <!-- 普通字段 -->
                        <property name="username"></property>
                        <property name="password"></property>
                    </class>
                </hibernate-mapping>
    3 编写主配置文件:hibernate.cfg.xml,将所有的hbm.xml文件注册
        先创建数据库hibernate01,不用创建表
        然后创建主配置文件
        名称: hibernate.cfg.xml
        位置: src
        内容:
            <?xml version="1.0" encoding="UTF-8"?>
            <!DOCTYPE hibernate-configuration PUBLIC
                "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
                "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
            <hibernate-configuration>
                <!-- 相当于 连接池的配置 -->
                <session-factory>
                    <!-- 1 基本4项 -->
                    <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
                    <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/hibernate01</property>
                    <property name="hibernate.connection.username">root</property>
                    <property name="hibernate.connection.password">1234</property>
                    
                    <!-- 2 方言 ,hibernate提供对不同数据库以及不同版本的支持-->
                    <property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>
                    
                    <!-- 3 其他-->
                    <!-- 显示sql语句-->
                    <property name="hibernate.show_sql">true</property>
                    <!-- 格式化sql语句-->
                    <property name="hibernate.format_sql">true</property>
                    <!-- 自动生成表结构,注意:hibernate不能自动生成数据库-->
                    <property name="hibernate.hbm2ddl.auto">update</property>
                    
                    <!-- java ee6.0项目,异常提供没有验证工厂,取消验证 -->
                    <property name="javax.persistence.validation.mode">none</property>
                    
                    <!-- 添加映射文件-->
                    <mapping resource="cn/itcast/a_hello/User.hbm.xml"/>
                </session-factory>
            </hibernate-configuration>
    4 通过hibernate提供api操作对象
        测试代码
            //提供数据
            User user = new User();
            user.setUsername("凤儿");
            user.setPassword("1234");
            
            //1加载配置文件,并获得配置对象
            Configuration config = new Configuration().configure();
            //2获得连接池--创建session工厂
            SessionFactory factory = config.buildSessionFactory();
            //3获得连接 -- 获得回话Session
            Session session = factory.openSession();
            //4开启事务--hibernate事务默认不提交
            Transaction transaction = session.beginTransaction();
            
            //操作
            session.save(user);
            
            //5提交事务
            transaction.commit();
            //6释放资源
            session.close();
            factory.close();



hbm.xml 映射文件
    示例
        <?xml version="1.0" encoding="UTF-8"?>
        <!DOCTYPE hibernate-mapping PUBLIC 
            "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
            "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
        <hibernate-mapping>
            <!-- 描述 对象 与 表 映射 -->
            <class name="cn.itcast.a_hello.User" table="t_user">
                <!-- 主键配置 -->
                <id name="userId">
                    <!-- 主键生成策略 -->
                    <generator class="native"></generator>
                </id>
                <!-- 普通字段 -->
                <property name="username"></property>
                <property name="password"></property>
            </class>
        </hibernate-mapping>
    说明
        <hibernate-mapping>根标签
            package : 给当前配置文件设置一个包,如果要使用此包下的类,可以直接类名。如果没有包,需要填写类的全限定名称
            catalog : 数据库名称,默认使用url设置的数据库名
        <class>标签,用于配置“对象 javabean”与“关系 table” 映射
            name : 类的全限定名称,如果配置package,就可以使用类名。
            table : 当前对象 对应的表名称
            注意:hibernate规定每一个表必须存在主键。
        <id> 用于表的主键,用于对象OID
            name : 对象属性名称,必填
        <property> 普通属性
            name : 对象属性名称,必填 
            column : 表中对应列的名称,默认值是name的值.注意:如果列名是关键字,可以使用中音符`(mysql) 中括号[](mssql) 双引号""(oracle) 括住,否则创建表不成功
            type : 表中对应列的类型
                java类型:全限定类名 ,区分大小写
                    例如:java.lang.String
                hibernate类型:hibernate规定的
                    例如:string,integer
                    时间类型: date 日期,time 时间,timestamp 时间戳(日期时间)
                    二进制: binary 相对于byte[]
            length :  表中对应列的大小
                string --> varchar(255)
        hibernate.hbm2ddl.auto 用于设置hibernate如果处理hbm映射文件生成ddl语句并执行
            取值:validate | update | create | create-drop
            create-drop : 在执行语句时,如果表已经存在先删除,再创建表。如果执行SessionFactory.close()方法,将在执行之后将表删除。【测试】
            create : 在执行之前先删除,后创建。【测试,初始化数据】
            validate : hbm.xml与表结构进行校验,如果不符合将抛异常。【最终测试】
                hbm.xml中所有配置在表中是否存在相应的字段,如果表中的字段大于配置项的内容,并不报错。
            update : 如果表不存在,则创建,如果已经存在,且hbm.xml被修改,则进行表结构的更新。【开发使用】
                注意:hibernate只负责表结构的统一,但不负责删除列。



hibernate API
    1 Configuration 配置对象,负责加载配置文件
        hibernate核心配置文件
            hibernate.properties
            hibernate.cfg.xml , 主配置文件
        构造
            new Configuration() ,自动加载hibernate.properties文件
        api
            configure() 方法执行加载hibernate.cfg.xml
            buildSessionFactory() 获得SessionFactory会话工厂
            addClass(Class),加载指定PO类对应的hbm.xml文件
                例:config.addClass(Person.class); 
            addResource(String),加载指定的hbm.xml文件
                例:config.addResource("cn/itcast/b_dao/Person.hbm.xml")
    2 SessionFactory ,会话工厂,相当于连接池
        获得方法:config.buildSessionFactory()
        api
            Session openSession() 打开一个会话,获得一个连接
            Session getCurrentSession() 获得当前线程中的会话。(二级缓存,session管理时讲)
    3 Sessioin ,会话,可以操作PO类,相当于连接Connection
        获得方式:sessionFactory.openSession();
        api
            void save(Object) 保存对象
            void update(Object) 通过id更新对象
            void delete(Object) 通过id删除对象
            Object get(Class,id) ,通过id查询数据
            Query createQuery(hql) 执行HQL语句
    4 Query对象
        获得方式:session.createQuery(hql);
        api
            Query setFirstResult(int) ,设置开始索引 startIndex
            Query setMaxResults(int) ,设置每页显示的个数 pageSize
            List list() ,执行hql语句并获得所有内容
            Object uniqueResult()  ,执行hql语句,并获得一个结果。如果没有结果将返回null,如果结果为多个将抛异常
    测试代码
        //1 配置对象
        Configuration config = new Configuration().configure();
        //2 会话工厂--连接池
        SessionFactory factory = config.buildSessionFactory();
        //3获得会话--连接
        Session session = factory.openSession();
        //4开启事务
        Transaction transaction = session.beginTransaction();
        
        //操作
        
        //5 提交事务
        transaction.commit();
        //6释放资源
        session.close();
        factory.close();



hibernate.cfg.xml 主配置文件
    示例
        <?xml version="1.0" encoding="UTF-8"?>
        <!DOCTYPE hibernate-configuration PUBLIC
            "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
            "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
        <hibernate-configuration>
            <!-- 相当于连接池的配置 -->
            <session-factory>
                <!-- 基本4项 -->
                <property name="hibernate.connection.driver_class">oracle.jdbc.OracleDriver</property>
                <property name="hibernate.connection.url">jdbc:oracle:thin:@localhost:1521:orcl</property>
                <property name="hibernate.connection.username">scott</property>
                <property name="hibernate.connection.password">scott</property>
                
                <!-- 方言,取值在hibernate3.jar/org.hibernate.dialect下的类-->
                <property name="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</property>
                
                <!-- 其他 -->
                <!-- * 显示sql语句 -->
                <property name="hibernate.show_sql">true</property>
                <!-- * 格式化sql语句 -->
                <property name="hibernate.format_sql">false</property>
                <!-- * ddl语句处理方式 (可以设置自动生成表,不能自动生成库)-->
                <property name="hibernate.hbm2ddl.auto">create</property>
                
                <!-- java ee6.0项目,异常提供没有验证工厂,取消验证 -->
                <property name="javax.persistence.validation.mode">none</property>
                
                <!-- 添加其他配置文件 -->
                <mapping resource="model/User.hbm.xml"/>
                
            </session-factory>
        </hibernate-configuration>
    说明
        <property name="固定key">相应的值</property>
            key和value借鉴文件位置:/hibernate/hibernate-distribution-3.6.10.Final/project/etc/hibernate.properties
            注意:key区分大小写,key如果以"hibernate."开头,可以省略"hibernate."字符串。
    常用key
        hibernate.dialect   方言,用于设置使用的数据库类型
            取值: 在hibernate3.jar/org.hibernate.dialect下的类的全限定名称
            SQL Server2005      org.hibernate.dialect.SQLServer2005Dialect
            mysql               org.hibernate.dialect.MySQL5Dialect
            oracle10g           org.hibernate.dialect.Oracle10gDialect
        hibernate.hbm2ddl.auto 用于设置hibernate在每次运行项目时如何处理表
            取值:validate | update | create | create-drop
            create-drop : 在执行语句时,如果表已经存在先删除,再创建表。如果执行SessionFactory.close()方法,将在执行之后将表删除。【测试】
            create : 在执行之前先删除,后创建。【测试,初始化数据】
            validate : hbm.xml与表结构进行校验,如果不符和将抛异常。【最终测试】
                hbm.xml中所有配置在表中是否存在相应的字段,如果表中的字段大于配置项的内容,并不报错。
            update : 如果表不存在,则创建,如果已经存在,且hbm.xml被修改,则进行表结构的更新。【开发使用】
                注意:hibernate只负责表结构的统一,但不负责删除列。



PO和OID
    PO : Persistent Object  持久对象,即存在映射文件(hbm.xml)的javabean
    OID : 持久化对象的唯一标识
        Hibernate使用OID来建立内存中的对象和数据库中记录的对应关系
        对象的OID和数据库的表的主键对应(即对象的OID就是对象中表的主键对应的属性的值).为保证OID的唯一性,应该让Hibernate来为OID赋值



主键生成策略
    标签: <generator>
    位置: 映射文件hbm.xml的id标签中,例
        <id name="id">
            <generator class="native"></generator>
        </id>
    class取值:
        1,increment : hibernate使用sql查询进行表主键值的累加,不支持多线程。
            先执行一条select语句,查询当前表的最大记录数,在此基础上+1,再更新
        2,identity : 使用数据库提供的自动增长列,例如:mysql(auto_increment) mssql(identity)
        3,sequence : 使用数据库支持序列操作,例如:oracle
        4,hilo : 高低位算法,使用另一张表来处理结果,保证支持多线程(了解)
            table 另一张表的表名
            column 另一张表的列名
            max_lo 每一次操作(事务)后累加的值
            例:
                <generator class="hilo">
                    <param name="table">hi_value</param>
                    <param name="column">next_value</param>
                    <param name="max_lo">100</param>
                </generator>
            计算方式,next_value * max_lo + next_value + 本次操作中的第几个操作 - 1 
            如: 第一次插入1条: 1 (第一次操作next_value为0)
                第二次插入1条: 101
                第三次插入2条: 202,203
                第四次插入2条: 303,304
            在max_lo范围内的线程数是线程安全的
        5,native : 根据底层数据库的能力选择 identity、sequence 或者 hilo 中的一个【】
        6,uuid : hibernate生成一个唯一标识字符串【】
        7,assigned : 自然主键,必须手动的维护OID,一般不用
        注意:1-5的OID的类型必须是整形(long,int,short)



PO对象状态
    持久对象的三种状态:transient 瞬时态、persistent 持久态 、detached 脱管态
        瞬时:session没有缓存数据,且数据库没有相应的记录。OID没有值 (如:新创建的对象)
        持久:session缓存数据,且数据库最终将会有数据。(如:保存了对象)
        脱管:session没有数据,但数据库有数据。OID有值 (如:保存完对象后,session被关闭)(如果OID有值,但数据库没有对应的记录,还是脱管态)
    状态的转换
        瞬时:
            瞬时 --> 持久 , save() 或 saveOrUpdate() 
            瞬时 --> 脱管 , 手动设置OID
        持久:
            持久 --> 瞬时,执行delete方法 (当提交时才真正执行删除)
            持久 --> 脱管,执行session close() 关闭 | clear() 清空所有 | evict(Object) 将指定PO对象移除session
        脱管:
            脱管 --> 瞬时,将OID手动移除(设置成默认值)
            脱管 --> 持久,执行update()



hibernate一级缓存
    一级缓存:指的是session级别的缓存。hibernate默认缓存
    在 Session 接口的实现中包含一系列的 Java 集合, 这些 Java 集合构成了 Session 缓存. 只要 Session 实例没有结束生命周期, 存放在它缓存中的对象也不会结束生命周期
    当session的save()方法持久化一个对象时,该对象被载入缓存,以后即使程序中不再引用该对象,只要缓存不清空,该对象仍然处于生命周期中。当试图get()、 load()对象时,会判断缓存中是否存在该对象,有则返回,此时不查询数据库。
    Session 能够在某些时间点, 按照缓存中对象的变化来执行相关的 SQL 语句, 来同步更新数据库, 这一过程被称为刷出缓存(flush)
    默认情况下 Session 在以下时间点刷出缓存:
        当应用程序调用 Transaction 的 commit()方法的时, 该方法先刷出缓存(session.flush()),然后再向数据库提交事务(tx.commit())
        当应用程序执行一些查询操作时,如果缓存中持久化对象的属性已经发生了变化,会先刷出缓存,以保证查询结果能够反映持久化对象的最新状态
        调用 Session 的 flush() 方法
    快照:在进行查询数据时,hibernate会再缓存一份同样的数据(不只是一级缓存中的一份),即快照,当进行事务提交时,会将一级缓存的数据与快照的数据进行对比,如果对象的属性已经发生了变化,则会更新数据库



关联关系映射
    参见《SQL》的 <表与表之间的关系>
    一对多
        例:用户(User)和订单(order)
        User中
            添加属性: private Set<Order> orderSet;
        user.hbm.xml中
            添加配置:
                <set name="orderSet">
                    <key column="user_id"></key>
                    <one-to-many class="test.Order"/>
                </set>
            说明
                set   : 使用的是Set集合,所以用set标签,除此之外还有list,array,map标签
                name  : 属性名称
                column: 从表的外键
                class : 从表对应的java类型
        Order中
            添加属性: private User user;
        order.hbm.xml中
            添加配置
                <many-to-one name="user" class="test.User" column="user_id"></many-to-one>
            说明
                many-to-one标签用于描述多对一关系
                name  : 属性名称
                class : 属性类型
                column: 表中的外键
    多对多



级联操作
    对一个对象进行操作时,对它所关联的对象的操作
    


hibernate在持久化一个瞬时对象时,它所关联的对象必须是持久对象,如果它关联了一个瞬时对象,则会报TransientObjectException
hibernate在commit时默认执行flush操作


一对多关系
主表对应的对象的配置映射文件
<!-- 
    set   : 使用的是Set集合,所以用set标签
    name  : 属性名称
    column: 从表的外键
    class : 从表对应的java类型
    cascade : 级联操作,取值为 all|none|save-update|delete|all-delete-orphan|delete-orphan
        none : 默认,如果插入主表的数据,不同步插入从表的数据;如果删除主表的数据,从表的外键会被改为null(不会被删除)
        save-update : 如果插入主表的数据,同步插入从表的数据(根据集合)
        delete : 如果删除主表的数据,同步删除从表的数据
        all : save-update 和 delete 的合并
        delete-orphan : 删除孤儿,如果从主表对应的对象的集合中删除从表对应的对象,则从表中的数据的外键会被改为null,相当于孤儿,此选项会直接删除从表的数据
        all-delete-orphan : all 和 delete-orphan 的合并
    inverse="true" : 放弃对从表的维护,在一对多 进行双向关联时,使用此属性可以少执行一条update语句
 -->
<set name="allOrder" cascade="all-delete-orphan">
    <key column="user_id"></key>
    <one-to-many class="test.Order"/>
</set>
从表对应的对象的配置映射文件
<!-- 
    name  : 属性名称
    class : 属性类型
    column: 表中的外键
 -->
<many-to-one name="user" class="test.User" column="user_id"></many-to-one>

在set标签添加属性 order-by 可在查询数据库时进行排序,例order-by="createDate asc"











评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值