Hibernate框架

Hibernate框架

标签(空格分隔): javaWeb

[TOC]

Hibernate介绍

Hibernate核心内容是ORM(关系对象模型)。可以将对象自动的生成数据库中的信息,使得开发更加的面向对象。这样作为程序员就可以使用面向对象的思想来操作数据库,而不用关心繁琐的JDBC。所以,Hibernate处于三层架构中的D层(持久层)

Hibernate核心技术

Configuration

Configuration作用:

  1. 读取 hibernate.cfg.xml
  2. 管理对象关系映射文件
  3. 加载 hibernate 驱动 url 以及用户名,密码....
  4. 管理 hibernate 配置信息(mapping resource)

SessionFactory

SessionFactory作用:

  1. 可以缓存sql语句和数据,称为sessionFactory级的缓存(二级缓存)
  2. 它是一个重量级的类,因此我们需要保证一个数据库只有一个sessionfactory

sessionfactory获取session的方法

SessionFactory factory = new Configuration().configure().buildSessionFactory();
//openSession();   
//---是获取一个新的 Session
Session session = factory.openSession();
//getCurrentSession(); 
//---获取和当前线程绑定的session,就是在同一个线程中,获取的session是同一个session,这样可以利于事务的控制
Session session = factory.getCurrentSession();
/*
getCurrentSession须先配置才能用:
需要在hibernate.cfg.xml的配置文件中提供配置
<property name="hibernate.current_session_context_class">thread</property>
*/
方法 使用方式 关闭方式 线程安全
openSession() 同一个线程中,每次都使用不同session 手动关闭 不安全
getCurrentSession() 同一个线程中,保证使用同一个session 自动关闭 安全

Session

Session之快照机制

    在创建session这个一级缓存对象的时候,session分为2块区域,一个是缓存区域。一个是快照区域
    当到了查询语句, 所获得的数据,缓存区域保存一份,快照区域也保存一份。
    到后面的set的时候,会修改缓存区域的参数。
    当提交事务的时候,会对比2块区域的内容,一致就没问题。不一致就修改数据库。

与一级缓存相关的方法

session.close()                         //一级缓存消失
Session.clear();                        //清空缓存
Session.evict(Object entity);           //清除指定的对象在一级缓存中的引用
Session.flisb();                        //使用数据库中的数据覆盖缓存中的数据

Query查询接口

// 1.查询所有记录
Query query = session.createQuery("from Customer");
List<Customer> list = query.list();
System.out.println(list);
条件查询
// 1.条件查询:
Query query = session.createQuery("from Customer where name = ?");
query.setString(0, "李健");
List<Customer> list = query.list();
System.out.println(list);
        
// 2.条件查询:
Query query = session.createQuery("from Customer where name = :aaa and age = :bbb");
query.setString("aaa", "李健");
query.setInteger("bbb", 38);
List<Customer> list = query.list();
System.out.println(list);
排序查询
//排序查询和SQL语句中的排序的语法是一样的
升序
session.createQuery("from Customer order by cust_id").list();
//降序
session.createQuery("from Customer order by cust_id desc").list();
分页查询

Hibernate框架提供了分页的方法,咱们可以调用方法来完成分页

//两个方法如下:
setFirstResult(a)       //-- 从哪条记录开始,如果查询是从第一条开启,值是0
setMaxResults(b)        //-- 每页查询的记录条数


//演示代码如下
List<LinkMan> list = session.createQuery("from LinkMan").setFirstResult(0).setMaxResults().list();

Criteria查询接口

// 1.查询所有记录
Criteria criteria = session.createCriteria(Customer.class);
List<Customer> list = criteria.list();
System.out.println(list);
        
// 2.条件查询
Criteria criteria = session.createCriteria(Customer.class);
criteria.add(Restrictions.eq("name", "李健"));
List<Customer> list = criteria.list();
System.out.println(list);
        
// 3.条件查询
Criteria criteria = session.createCriteria(Customer.class);
criteria.add(Restrictions.eq("name", "李健"));
criteria.add(Restrictions.eq("age", 38));
List<Customer> list = criteria.list();
System.out.println(list);

Transtraction(事物)

Hibernate的使用

下载jar包:

http://sourceforge.net/projects/hibernate/files/hibernate-orm/5.0.7.Final/hibernate-release-5.0.7.Final.zip/download

导入jar

/*Hibernate-required start  */
hibernate-core-5.0.7.Final.jar                      //核心
hibernate-commons-annotations-5.0.1.Final.jar       //注解
javassist-3.18.1-GA.jar                             //动态代理
dom4j-1.6.1.jar                                     //XML解析
antlr-2.7.7.jar                                     
geronimo-jta_1.1_spec-1.1.1.jar
hibernate-jpa-2.1-api-1.0.0.Final.jar
jandex-2.0.0.Final.jar
jboss-logging-3.3.0.Final.jar
standard.jar
/*Hibernate-required end */
/*---------------------------------*/
//BeanUtils包
commons-beanutils-1.8.3.jar
commons-logging-1.1.1.jar
/*---------------------------------*/
//jstl包
jstl.jar
standard.jar
/*---------------------------------*/
//mysql驱动包
mysql-connector-java-5.1.7-bin.jar
/*---------------------------------*/
/*日志 log4j*/
slf4j-api-1.6.1.jar                                 //Hibernate推荐使用的日志接口(未实现)
slf4j-log4j12-1.7.2.jar                             //log4j接口与实现间的链接
log4j-1.2.16.jar                                    //log4j具体实现
/*---------------------------------*/

持久化类

    持久化类 = JavaBean(Java类) + xxx.hbm.xml(hbm的配置文件)

持久化类的编写规则

  1. 提供一个无参数 public访问控制符的构造器 -- 底层需要进行反射.
  2. 提供一个标识属性,映射数据表主键字段 -- 唯一标识OID.数据库中通过主键.Java对象通过地址确定对象.持久化类通过唯一标识OID确定记录
  3. 所有属性提供public访问控制符的 set或者get 方法
  4. 标识属性应尽量使用基本数据类型的包装类型

新建JavaBean类Customer.java

package com.itheima.domain;

/**
 * 客户的JavaBean
 * @author Administrator
 */
public class Customer {
    
    /**
     * `cust_id` bigint(32) NOT NULL AUTO_INCREMENT COMMENT '客户编号(主键)',
          `cust_name` varchar(32) NOT NULL COMMENT '客户名称(公司名称)',
          `cust_user_id` bigint(32) DEFAULT NULL COMMENT '负责人id',
          `cust_create_id` bigint(32) DEFAULT NULL COMMENT '创建人id',
          `cust_source` varchar(32) DEFAULT NULL COMMENT '客户信息来源',
          `cust_industry` varchar(32) DEFAULT NULL COMMENT '客户所属行业',
          `cust_level` varchar(32) DEFAULT NULL COMMENT '客户级别',
          `cust_linkman` varchar(64) DEFAULT NULL COMMENT '联系人',
          `cust_phone` varchar(64) DEFAULT NULL COMMENT '固定电话',
          `cust_mobile` varchar(16) DEFAULT NULL COMMENT '移动电话',
     */
    
    // 以后使用包装类,默认值是null
    private Long cust_id;
    private String cust_name;
    private Long cust_user_id;
    private Long cust_create_id;
    private String cust_source;
    private String cust_industry;
    private String cust_level;
    private String cust_linkman;
    private String cust_phone;
    private String cust_mobile;
    
    
    public Long getCust_id() {
        return cust_id;
    }
    public void setCust_id(Long cust_id) {
        this.cust_id = cust_id;
    }
    public String getCust_name() {
        return cust_name;
    }
    public void setCust_name(String cust_name) {
        this.cust_name = cust_name;
    }
    public Long getCust_user_id() {
        return cust_user_id;
    }
    public void setCust_user_id(Long cust_user_id) {
        this.cust_user_id = cust_user_id;
    }
    public Long getCust_create_id() {
        return cust_create_id;
    }
    public void setCust_create_id(Long cust_create_id) {
        this.cust_create_id = cust_create_id;
    }
    public String getCust_source() {
        return cust_source;
    }
    public void setCust_source(String cust_source) {
        this.cust_source = cust_source;
    }
    public String getCust_industry() {
        return cust_industry;
    }
    public void setCust_industry(String cust_industry) {
        this.cust_industry = cust_industry;
    }
    public String getCust_level() {
        return cust_level;
    }
    public void setCust_level(String cust_level) {
        this.cust_level = cust_level;
    }
    public String getCust_linkman() {
        return cust_linkman;
    }
    public void setCust_linkman(String cust_linkman) {
        this.cust_linkman = cust_linkman;
    }
    public String getCust_phone() {
        return cust_phone;
    }
    public void setCust_phone(String cust_phone) {
        this.cust_phone = cust_phone;
    }
    public String getCust_mobile() {
        return cust_mobile;
    }
    public void setCust_mobile(String cust_mobile) {
        this.cust_mobile = cust_mobile;
    }
    @Override
    public String toString() {
        return "Customer [cust_id=" + cust_id + ", cust_name=" + cust_name + ", cust_user_id=" + cust_user_id
                + ", cust_create_id=" + cust_create_id + ", cust_source=" + cust_source + ", cust_industry="
                + cust_industry + ", cust_level=" + cust_level + ", cust_linkman=" + cust_linkman + ", cust_phone="
                + cust_phone + ", cust_mobile=" + cust_mobile + "]";
    }
    
}

java同目录配置映射文件Customer.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="com.itheima.domain.Customer" table="cst_customer">
        <!-- 配置id 
            见到name属性,JavaBean的属性
            见到column属性,是表结构的字段
        -->
        <id name="cust_id" column="cust_id">
            <!-- 主键的生成策略 
            increment:Hibernate中提供的一种增长机制(并发访问会出错)
            identity:数据库的自动增长(auto_increment)(Oracle数据库没有自动增长)
            sequence:底层使用的是序列的增长方式(Oracle自动增长需要使用)
            uuid:使用随机的字符串作为主键
            native:本地策略(MySQL-使用identity,Oracle-使用sequence)
            -->
            <generator class="native"/>
        </id>
        
        <!-- 配置其他的属性 -->
        <property name="cust_name" column="cust_name"/>
        <property name="cust_user_id" column="cust_user_id"/>
        <property name="cust_create_id" column="cust_create_id"/>
        <property name="cust_source" column="cust_source"/>
        <property name="cust_industry" column="cust_industry"/>
        <property name="cust_level" column="cust_level"/>
        <property name="cust_linkman" column="cust_linkman"/>
        <property name="cust_phone" column="cust_phone"/>
        <property name="cust_mobile" column="cust_mobile"/>
        
    </class>
    
</hibernate-mapping>    

核心配置文件hibernate.cfg.xml

可以参考hibernate包hibernate-release-5.0.7.Final\project\etc\hibernate.properties

<?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>
    
    <!-- 先配置SessionFactory标签,一个数据库对应一个SessionFactory标签 -->
    <session-factory>
        
        <!-- 必须要配置的参数有5个,4大参数,数据库的方言 -->
        <!-- mysql数据库驱动 -->  
        <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
        <!-- mysql数据库名称 -->  
        <property name="hibernate.connection.url">jdbc:mysql:///hibernate_day01</property>
        <property name="hibernate.connection.username">root</property>
        <property name="hibernate.connection.password">root</property>
        
        <!-- 数据库的方言:为每一种数据库提供适配器,方便转换-->
        <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
        
        <!-- 可选配置 -->
        <!-- 显示SQL语句,在控制台显示 -->
        <property name="hibernate.show_sql">true</property>
        <!-- 格式化SQL语句 -->
        <property name="hibernate.format_sql">true</property>
        <!-- 生成数据库的表结构 
            update:如果没有表结构,创建表结构。如果存在,不会创建,添加数据
        -->
        <property name="hibernate.hbm2ddl.auto">update</property>
        
        <!-- 映射配置文件,需要引入映射的配置文件 -->
        <mapping resource="com/itheima/domain/Customer.hbm.xml"/>
        
    </session-factory>
    
</hibernate-configuration>  

测试环境

    /**
     * 测试保存
     */
    // 获取session
    Session session = HibernateUtils.getSession();
    // 开启事务
    Transaction tr = session.beginTransaction();
    // 执行代码
    Customer c = new Customer();
    c.setCust_name("哈哈");
    // 保存
    session.save(c);
    // 提交事务事务
    tr.commit();
    // 释放资源
    session.close();


    /**
     * 测试查询的方法
     */
        // 原来:加载配置文件,获取Factory对象,获取session
        Session session = HibernateUtils.getSession();
        Transaction tr = session.beginTransaction();
        // 创建查询的接口
        Query query = session.createQuery("from Customer");
        // 查询所有的数据 select * from 表
        List<Customer> list = query.list();
        for (Customer customer : list) {
            System.out.println(customer);
        }
        
        // 提交事务
        tr.commit();
        // 释放资源
        session.close();
    }
    /**
     * 测试添加或者修改
     */
    @Test
    public void testSaveOrUpdate(){
        // 原来:加载配置文件,获取Factory对象,获取session
        Session session = HibernateUtils.getSession();
        Transaction tr = session.beginTransaction();
        
        /*// 演示错误
        Customer c = new Customer();
        // c.setCust_id(10L);   千万不能自己设置
        c.setCust_name("测试");
        
        // 保存或者修改
        session.saveOrUpdate(c);*/
        
        // 先查询再改
        Customer c = session.get(Customer.class, 6L);
        c.setCust_name("小泽");
        
        session.saveOrUpdate(c);
        
        // 提交事务
        tr.commit();
        // 释放资源
        session.close();
    }
    /**
     * 测试修改
     */
    @Test
    public void testUpdate(){
        // 原来:加载配置文件,获取Factory对象,获取session
        Session session = HibernateUtils.getSession();
        Transaction tr = session.beginTransaction();
        // 测试查询的方法 2个参数:arg0查询JavaBean的class对象 arg1主键的值
        Customer c = session.get(Customer.class, 6L);
        
        // 设置客户的信息
        c.setCust_name("小苍");
        c.setCust_level("3");
        
        // 修改
        session.update(c);
        
        // 提交事务
        tr.commit();
        // 释放资源
        session.close();
    }
    /**
     * 测试删除的方法
     * 注意:删除或者修改,先查询再删除或者修改
     */
    @Test
    public void testDel(){
        // 原来:加载配置文件,获取Factory对象,获取session
        Session session = HibernateUtils.getSession();
        Transaction tr = session.beginTransaction();
        // 测试查询的方法 2个参数:arg0查询JavaBean的class对象 arg1主键的值
        Customer c = session.get(Customer.class, 7L);
        
        // 删除客户
        session.delete(c);
        
        // 提交事务
        tr.commit();
        // 释放资源
        session.close();
    }
    /**
     * 测试get()方法,获取查询,通过主键来查询一条记录
     */
    @Test
    public void testGet(){
        // 原来:加载配置文件,获取Factory对象,获取session
        Session session = HibernateUtils.getSession();
        Transaction tr = session.beginTransaction();
        // 测试查询的方法 2个参数:arg0查询JavaBean的class对象 arg1主键的值
        Customer c = session.get(Customer.class, 7L);
        System.out.println(c);
        // 提交事务
        tr.commit();
        // 释放资源
        session.close();
    }
    /**
     * 测试工具类
     */
    @Test
    public void testSave2(){
        // 原来:加载配置文件,获取Factory对象,获取session
        Session session = HibernateUtils.getSession();
        Transaction tr = session.beginTransaction();
        Customer c = new Customer();
        c.setCust_name("小风");
        session.save(c);
        // 提交事务
        tr.commit();
        // 释放资源
        session.close();
    }
    /**
     * 测试保存客户
     */
    @Test
    public void testSave(){
        /**
         *  1. 先加载配置文件
         *  2. 创建SessionFactory对象,生成Session对象
         *  3. 创建session对象
         *  4. 开启事务
         *  5. 编写保存的代码
         *  6. 提交事务
         *  7. 释放资源
         */
        /*// 1. 先加载配置文件
        Configuration config = new Configuration();
        // 默认加载src目录下hibernate.cfg.xml的配置文件
        config.configure();
        // 了解,手动加载
        // config.addResource("com/itheima/domain/Customer.hbm.xml");
         */     
        
        // 简写的方法
        Configuration config = new Configuration().configure();
        
        // 2. 创建SessionFactory对象
        SessionFactory factory = config.buildSessionFactory();
        // 3. 创建session对象
        Session session = factory.openSession();
        // 4. 开启事务
        Transaction tr = session.beginTransaction();
        
        // 5. 编写保存的代码
        Customer c = new Customer();
        // c.setCust_id(cust_id);   主键是自动递增了
        c.setCust_name("测试3");
        c.setCust_level("2");
        c.setCust_phone("110");
        
        // 保存数据,操作对象就相当于操作数据库的表结构
        session.save(c);
        
        // 6. 提交事务
        tr.commit();
        // 7. 释放资源
        session.close();
        factory.close();
    }

常用方法

save(obj);
delete(obj);
get(obj);
update(obj);
saveorupdate(obj);
creatrQuery(obj);

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,372评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,368评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,415评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,157评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,171评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,125评论 1 297
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,028评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,887评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,310评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,533评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,690评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,411评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,004评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,659评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,812评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,693评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,577评论 2 353