Hibernate-部分知识点概述(持续更新)

Hibernate

面向对象操作模型数据库->阻抗不匹配

ORM(Object Relation Mapping->对象关系映射)->完成对象与关系之间的转换

主流ORM框架:Hibernate Toplink OJB


(一)

简单使用步骤:

详见:http://blog.csdn.net/qq_28796345/article/details/52513814

(1)创建项目

(2)导入jar包

(3)创建实体对象Usre

(4)创建User.hbm.xml映射文件(于相应包下)

(5)创建配置文件于src下(hibernate.cfg.xml)

(6)创建测试类(初始化hibernate)


hibernate.cfg.xml:

<!DOCTYPE hibernate-configuration PUBLIC

    "-//Hibernate/Hibernate Configuration DTD 3.0//EN"

    "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">


<hibernate-configuration>

    <session-factory>

    

        <!-- 数据库驱动 -->

        <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>

        <!-- 所用数据库 -->

        <property name="dialect">org.hibernate.dialect.MySQLDialect</property>

        <!-- 数据库url -->

        <property name="connection.url">jdbc:mysql:///hibernate</property>

        <!-- 数据库用户名 -->

        <property name="connection.username">root</property>

        <!-- 用户密码 -->

        <property name="connection.password">0707</property>

        <!-- 创建表 -->

        <property name="hbm2ddl.auto">create</property>

        <!-- 映射文件位置 -->

        <mapping resource="com/sw/hibernate/domain/User.hbm.xml"/>

    </session-factory>

    

</hibernate-configuration>


User.hbm.xml:

<?xml version="1.0"?>

<!DOCTYPE hibernate-mapping PUBLIC

    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"

    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping

    package="com.sw.hibernate.domain">


    <class name="User" table="user">

        

        <!-- 数据库表主键 column指定字段名 -->        

        <id name="id" column="id">

            <generator class="native"/>

        </id>

        <!-- property为属性 -->

        <property name="name" column="name"/>

        <property name="birthday"/>

        

    </class>

    

</hibernate-mapping>

工具类

初始化:

/*

 *@Author swxctx

 *@time 2016年9月12日

 */

package com.sw.util;


import org.hibernate.Session;

import org.hibernate.SessionFactory;

import org.hibernate.cfg.Configuration;


public final class HibernateUtil {

    //工具类 用于初始化hibernate(一次初始化)

    private static SessionFactory sessionFactory;

    private HibernateUtil(){

        

    }

        static{

            //需要进行一次初始化

            Configuration cfg=new Configuration();

            cfg.configure();//读取配置文件

            //初始化后得到sessionfactory

            sessionFactory = cfg.buildSessionFactory();//类似于DriverManager

        }

    public static SessionFactory getSessionFactory() {

        return sessionFactory;

    }

    

    public static Session getSession(){

        return sessionFactory.openSession();

    }

}
执行方法封装:

/*

 *@Author swxctx

 *@time 2016年9月12日

 */

package com.sw.util;


import org.hibernate.HibernateException;

import org.hibernate.Session;

import org.hibernate.Transaction;


import com.sw.hibernate.domain.User;


public class Tooladd {

    static void addUser(User user){

        Session s=null;

        Transaction tx=null;

        try {

            //初始化

            s=HibernateUtil.getSession();

            //操作数据

            tx=s.beginTransaction();

            //保存对象

            s.save(user);

            //提交

            tx.commit();

        } catch (HibernateException he) {

            // TODO: handle exception

            if(tx!=null){

                tx.rollback();//回滚

                throw he;//抛出异常

            }

        }finally{

            if(s!=null){

                s.close();//关闭

                s=null;

            }

        }

    }

    

    static void addUser1(User user){

        Session s=null;

        Transaction tx=null;

        try {

            //初始化

            s=HibernateUtil.getSession();

            //操作数据

            tx=s.beginTransaction();

            //保存对象

            s.save(user);

            //提交

            tx.commit();

        } finally{

            if(s!=null){

                s.close();//关闭

                s=null;

            }

        }

    }

}



Session接口:

get(查询)、load(更新)、persist(保存)方法


实体对象的三种状态与saveOrUpdate(根据id的值来确定使用save还是update方法)方法

(1)瞬时-数据库没有数据与之对应,超过作用域会被jvm垃圾回收。

(2)持久-数据库没有记录,并且session并没有关闭,与session有关

(3)脱管-与session没有关系,与数据库表有对应


HQL与Criteria


1、Hql

实例:

//查询

static void query(String name){

    Session s=null;

    try {

        //初始化

        s=HibernateUtil.getSession();

        String hql="from User as user where user.name=?";

        Query query=s.createQuery(hql);

        query.setString(0, name);

        List<User> list=query.list();

//            Object ob=query.uniqueResult();//返回object类型

        for(User user:list){

            System.out.println(user.getName());

        }

    }finally{

        if(s!=null){

            s.close();//关闭

            s=null;

        }

    }

}  

注:在hbm.xml文件中,应该避免属性名与数据库关键字冲突,若冲突,则在前加上反引号即可。


hql的命名参数与Query接口的分页查询:

from User as user where user.name=?

如上语句,如果在字段过多时则不会适用。

解决办法:使用命名参数(为用户定义名字)

from User as user where user.name=:name

query.string("name",name);

Query


分页:

Query query=s.createQuery(hql);

//从第一页开始取结果,每页取十条

query.setFirstResult(0);//实现分页 第一条

query.setMaxResults(10);//每页十条


2、Criteria(条件查询)

实例:

static void cri(String name){

    Session s=null;

    try {

        //初始化

        s=HibernateUtil.getSession();

        Criteria c=s.createCriteria(User.class);

        //查找name对应的数据

        c.add(Restrictions.eq("name", name));//传入的参数(约束条件)

        c.setFirstResult(0);//分页

        c.setMaxResults(10);

        List<User> list=c.list();

        User u=(User)c.uniqueResult();

        for(User user:list){

            System.out.println(user.getName());

        }

    }finally{

        if(s!=null){

            s.close();//关闭

            s=null;

        }

    }

}


(二)

关联

详见:点击打开链接

多对一关联关系的映射与原理

一对多

多对一

一对一

多对多(使用中间表)->执行速率较慢,不常用

多对多关联关系的检索

两个组件(对象)关联


级联操作-对相应的对象进行统一的操作(保存时都保存、删除时将其数据都删除等)

<set name="em" cascade="save-update">

    <key column="depart_id"></key>

    <one-to-many class="Employee"/>

</set>


inverse属性(有序集合不能出现,不会放弃关系维护)

用于一对多中->一放弃维护与多个的关联关系

放弃维护关系->不再更新外键

<list name=" " inverse="true">


(四)

继承映射

<?xml version="1.0"?>

<!DOCTYPE hibernate-mapping PUBLIC

    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"

    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping

    package="com.sw.hibernate.domain">


    <class name="Employee" table="Employee" discriminator-value="0">

        

        <!-- 数据库表主键 column指定字段名 -->        

        <id name="id" column="id">

            <generator class="native"/>

        </id>

        

        <discriminator column="type" type="int"/>

        

        <!-- property为属性 -->

        <property name="name" column="name"/>

        

        <!-- Department 多对一-->

        <!-- depart_id 外键  对应于department的id-->

        <many-to-one name="depart" column="depart_id" property-ref="id"/>

        

        <!-- 对象映射 -->

        <subclass name="Skiller" discriminator-value="1">

            <property name="skill"/>

        </subclass>

        <subclass name="Sales" discriminator-value="2">

            <property name="sell"/>

        </subclass>

    </class>

    

</hibernate-mapping>



每个子类映射到一张表(效率低,结构清晰)

<!-- 每个子类对应一张表 -->

<joined-subclass name="Skiller" table="skiller">

    <key column="emp_id"/>

    <property name="skill"/>

</joined-subclass>

<joined-subclass name="Sales" table="sales">

    <key column="emp_id"/>

    <property name="sell"/>

</joined-subclass>


继承映射->1、一个类继承体系一张表 2、每个子类各一张表

<union-subclass>->将每个表都保存完整的信息(每个子类一张表)


(五)

懒加载:Hibernate.initialize(对象)->Domain非final;

通过asm.jar与cglib.jar两个包实现懒加载。


一对一懒加载(默认情况下hibernate会使用懒加载)->查询主对象时不会进行懒加载

查询重对象时,会启用懒加载

除多对一以外,尽量不要禁用懒加载,如果禁用会产生一些意想不到的错误。

懒加载并不能区分空集合,当与数据表结构冲突时(数据为空),则会出现问题。


能够懒加载的对象都是被改写过的代理对象,当相关联的session没有关闭时,访问这些懒加载

对象(代理对象)的属性(getId和getClass除外)。hibername会初始化这些代理,或用hibernate

.initialize(proxy)来初始化代理对象;当相关联的session关闭后,再访问懒加载的对象将

出现异常。


属性亦可进行懒加载。


(六)

1、一级缓存

缓存->第一次读取时将其存放到内存中,第二次直接从内存读取,提高了性能。

(1)将数据放入缓存中->使用map map.put(key,user);

(2)从缓存中取出数据

(3)删除无效数据 map.remove(key);


Session存在缓存,随着session的关闭而消失。

第一次get(获取)时,将数据放入缓存。

session.evict(user);//将user对象从session缓存中清除

session.clear();//清除所有缓存

使用一级缓存需要防止数据溢出(并不会限制放置的个数,直到内存溢出)

一级缓存的存在时间较短(一个请求内),所以会导致数据失效等问题,使用二级缓存可以解决这一问题。


2、二级缓存(SessionFactory级共享)

交给第三方框架处理。

通过配置文件hibernate.cfg.xml进行处理:

<!-- 打开二级缓存 -->

<property name="cache.use_second_level_cache">true</property>

 <!-- 打开查询缓存 -->

<property name="cache.use_query_cache">true</property>

<!-- 所使用的缓存机制 -->

<property name="cache.provider_class">org.hibernate.cache.OSCacheProvider</property>

<!-- 指定需要缓存的类 -->

<class-cache usage="read-only" class="cn/itcast/hibernate/domain/User"/>


指定需要缓存的类,除了在这里指定外,亦可在映射文件中进行配置指定:

<cache usge="read-only"/><!--放置于class内部-->


hibernate寻找数据步骤->先到以及缓存寻找,如果以及缓存不存在该数据,则到二级缓存进行寻找,

若二级缓存仍然不存在,则到数据库中进行寻找。


分布式缓存与中央缓存:

使用缓存的条件:

(1)读取次数大于修改

(2)数据量不能超过内存量

(3)对数据要有独享的控制

(4)可以容忍出现无效数据


(七)

事务

JDBC Transaction(单步事务,使用一个库)

JTA Transaction(分布式事务处理,使用多个库)->跨数据库的事务,由应用JTA容器实现。


openSession()->

getCurrentSession()->获取当前session


ThreadLocal


OpenSessionInView


Hibernate-Mapping->多种属性(隐藏属性的使用)->schema


使用class类可以定义一个持久化类。


鉴别器


property属性亦具有懒加载功能。


Hibernate映射类型。


Session是非线程安全的,生命周期较短,一般不会超过一个请求。代表一个和数据库的连接。

SessionFactory是线程安全的,声明周期较长,一般在整个系统内都是有效的。

保存着喝数据库连接的相关信息。


批量更新

1、flush使一级缓存与数据库同步。

Session.flush();

当数据量较大时,在调用clear之前先调用flush。


2、StatelessSession接口

不和一二级缓存交互,也不触发任何事件。


N+1次查询与懒加载。

N条记录会出现N+1此查询记录。


拦截器

监听器

本地sql查询与命名查询

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Swxctx

您的鼓励将是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值