Hibernate框架学习笔记

1、什么是框架?

框架就是一个半成品的项目,提高开发效率

PS:不必纠结于框架本身的实现,只要学会如何使用这个框架即可。

 

2、什么是Hibernate框架?

         这个框架应用于DAO层

实体类和数据表之间建立了联系,通过操作对象,直接对数据库进行修改。

简介

Hibernate的优点及好处:

  1. Hibernate对jdbc 访问数据库的代码做了轻量级的封装,大大简化了数据访问层繁琐的重复性代码,并且减少内存消耗,加快了运行效率。
  2. Hibernate是一个基于JDBC的主流持久化框架,是一个优秀的ORM实现,它很大程度的简化了DAO(Data Access Object,数据访问对象)层编码工作
  3. Hibernate 的性能非常好,映射的灵活性很出色,它支持很多关系型数据库,从一对一到多对多的各种复杂关系。
  4. 可扩展性强,由于源代码的开源以及API的开放,当本身功能不够用时,可以自行编码进行扩展。

Hibernate操作数据库的时候,可以面向对象的方式来完成,不需要书写SQL语句。

3、hibernate框架搭建

1、导包

        

导入驱动包

2、准备一个实体类

(1)所有的属性应该设置为私有,并添加get-set方法

(2)构造函数要么不写,如果要写至少写两个(必须包含一个空的)

(3)属性的类型应是包装类型

(4)必须拥有一个主键

3、准备数据库

         数据库必须由我们自己建立,数据库表,可以由hibernate自动创建,

如果手动创建,表中字段要和实体类一一对应。

4、创建实体类和数据表之间的映射配置文件

创建一个 实体类名+.hbm+.xml 的映射文件(推荐这个文件的目录和实体类在同一目录下)

<hibernate-mapping>
    <class name="cn.fdw.bean.User" table="t_user">
        <id name="id" column="id">
            <generator class="native"></generator>
        </id>
        <property name="name" column="name"></property>
        <property name="sex" column="sex"></property>
        <property name="age" column="age"></property>
        <property name="balance" column="balance"></property>
    </class>
</hibernate-mapping>

5、书写核心配置文件

 名字为hibernate.cfg.xml

 必须放在src下

导入约束:

 <!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>
        <!-- 数据库驱动 -->
       
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
        <!-- 数据库url -->
       
<property name="hibernate.connection.url">jdbc:mysql:///hibernate01</property>
        <!-- 数据库连接用户名 -->
       
<property name="hibernate.connection.username">root</property>
        <!-- 数据库连接密码 -->
       
<property name="hibernate.connection.password">1234</property>

        <!--数据库方言-->
       
<property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>

        <property name="hibernate.show_sql">true</property>
        <property name="hibernate.format_sql">true</property>

        <property name="hibernate.hbm2ddl.auto">update</property>

        <property name="connection.isolation">4</property>

        <mapping resource="cn/fdw/bean/User.hbm.xml"></mapping>
    </session-factory>
</hibernate-configuration>

6、书写测试代码

package cn.fdw.test;

import cn.fdw.bean.User;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;

public class Demo {
    public static void main(String[] args) {
        //1、读取配置文件
        Configuration cfg = new Configuration().configure();
        //2、创建sessionFactory
        SessionFactory sessionFactory = cfg.buildSessionFactory();
        //3、获得一个session
       
Session session = sessionFactory.openSession();
        //开启事务
        Transaction transaction = session.beginTransaction();
        //---------------------------------------------
       
User user = new User();
        user.setName("马云");
        user.setAge(99);
        user.setSex("");
        user.setBalance(500);

        session.save(user);
        //---------------------------------------------
        //
提交事务
        transaction.commit();
        //释放资源
        session.close();
        sessionFactory.close();

    }
}

配置文件详解

实体类映射配置文件:

<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<!-- package属性:填写一个包名.在元素内部凡是需要书写完整类名的属性,可以直接写简答类名了. -->
<hibernate-mapping package="cn.fdw.bean">
    <!--
      class
元素: 配置实体与表的对应关系的
         name: 完整类名
         table:数据库表名
    -->
   
<class name="User" table="t_user">
        <!-- id元素:配置主键映射的属性
        name: 填写主键对应属性名
        column(可选): 填写表中的主键列名.默认值:列名会默认使用属性名
        type(可选):填写列(属性)的类型.hibernate会自动检测实体的属性类型.
               
每个类型有三种填法: java类型|hibernate类型|数据库类型
        not-null(可选):配置该属性()是否不能为空. 默认值:false
        length(
可选):配置数据库中列的长度. 默认值:使用数据库类型的最大长度
 -->
       
<id name="id" column="id">
            <!--主键生成策略
            native:自动递增(31
            identitymySQL 自动递增
            increment:每次插入前会先查询表中id最大值,+1表示新主键值
            sequence Oracle 自动递增
            assigned:
            UUID
:产生随机字符串作为主键. 主键类型必须为string 类型.
            -->
           
<generator class="native"></generator>
        </id>
        <!-- property元素:id之外的普通属性映射
        name: 填写属性名
        column(可选): 填写列名
        type(可选):填写列(属性)的类型.hibernate会自动检测实体的属性类型.
               
每个类型有三种填法: java类型|hibernate类型|数据库类型
        not-null(可选):配置该属性()是否不能为空. 默认值:false
        length(
可选):配置数据库中列的长度. 默认值:使用数据库类型的最大长度
 -->
       
<property name="name" column="name"></property>
        <property name="sex" column="sex"></property>
        <property name="age" column="age"></property>
        <property name="balance" column="balance"></property>
    </class>
</hibernate-mapping>

主配置文件详解,放在src下:

<!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>
        <!-- 数据库驱动 -->
       
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
        <!-- 数据库url -->
       
<property name="hibernate.connection.url">jdbc:mysql:///hibernate01</property>
        <!-- 数据库连接用户名 -->
       
<property name="hibernate.connection.username">root</property>
        <!-- 数据库连接密码 -->
       
<property name="hibernate.connection.password">1234</property>

        <!-- 数据库方言
    不同的数据库中,sql语法略有区别. 指定方言可以让hibernate框架在生成sql语句时.针对数据库的方言生成.
    sql99
标准: DDL 定义语言  库表的增删改查
              DCL 控制语言  事务 权限
              DML 操纵语言  增删改查
    注意: MYSQL在选择方言时,请选择最短的方言.  -->
       
<property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>

        <!-- hibernate生成的sql语句打印到控制台 -->
       
<property name="hibernate.show_sql">true</property>
        <!-- hibernate生成的sql语句格式化(语法缩进) -->
       
<property name="hibernate.format_sql">true</property>

        <!--
        ## auto schema export 
自动导出表结构. 自动建表
        #hibernate.hbm2ddl.auto create    自动建表.每次框架运行都会创建新的表.以前表将会被覆盖,表数据会丢失.(开发环境中测试使用)
        #hibernate.hbm2ddl.auto create-drop
自动建表.每次框架运行结束都会将所有表删除.(开发环境中测试使用)
        #hibernate.hbm2ddl.auto update(
推荐使用) 自动生成表.如果已经存在不会再生成.如果表有变动.自动更新表(不会删除任何数据).
        #hibernate.hbm2ddl.auto validate  
校验.不自动生成表.每次启动会校验数据库中表是否正确.校验失败.
        -->
        
<property name="hibernate.hbm2ddl.auto">update</property>

        <!--事务隔离级别-->
       
<property name="connection.isolation">4</property>
        <!-- 引入orm元数据
         路径书写: 填写src下的路径
       -->
       
<mapping resource="cn/fdw/bean/User.hbm.xml"></mapping>
    </session-factory>
</hibernate-configuration>

Hibernate API 详解

package cn.fdw.test;

import cn.fdw.bean.User;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;

public class Demo {
    public static void main(String[] args) {
        //1、读取配置文件
        Configuration cfg = new Configuration().configure();
        //2、创建sessionFactory
        /*
        * 1
、创建 session connection
        * 2
、创建的时候会检查数据的信息,去更新数据库的结构
        * */
       
SessionFactory sessionFactory = cfg.buildSessionFactory();
        //3、获得一个session
        /*
        * 1
、获得事务  crud(增查改删)
        * */
       
Session session = sessionFactory.openSession();
        //开启事务
        Transaction transaction = session.beginTransaction();
        //---------------------------------------------
       
User user = new User();
        user.setName("马云");
        user.setAge(99);
        user.setSex("");
        user.setBalance(500);

        session.save(user);
        //---------------------------------------------
        //
提交事务
        transaction.commit();
        //回滚·事务
//       transaction.rollback();
        //
释放资源
        session.close();
        sessionFactory.close();

    }
}

crud(增查改删)

save 保存(增)

update:修改

delete:删除

get查询

Hibernate对象状态

瞬时状态 一个对象,无id,没有与session绑定

持久化状态  有id ,与session绑定

游离/托管 状态 有id,没与session绑定

 

Hibernate 提供的四个curd不是增删改查的I意思,而是改变对象的状态,从而达到修改数据库的目的。

 

SaveOrUpdate

持久化状态的对象 随着对象的数据更改,数据库会自动更新

 

Hibernate 查询

 

1、hql

hql 是hibernate的独家语言

 

2、criteria

or()或者               and() 并且                   equal 等于               notequal 不等于

Like           Isnull         In                        Gt 大于            Ge  大于等于                  Lt   小于

Le  小于等于                            Between  在….之间

  1. 使用session 创建 criteriaBuilder类

CriteriaBuilder cb = session.getCriteriaBuilder();

 

  1. 用 工厂类 即cb 产生 criteriaQuery

CriteriaQuery<User> query = cb.createQuery(User.class);

 

  1. 指定根元素

Root<User> root = query.from(User.class);

  1. 将条件封装到query

Predicate predicate = cb.notEqual(root.get("name"), "马云");
Predicate predicate1 = cb.gt(root.get("age"), 18);
query.where(cb.and(predicate,predicate1));

  1. 把query 传给createQuery  得到结果集

List<User> list = session.createQuery(query).list();
System.out.println(list);

3、SQL 原生态查询方式

@Test
public void fun(){
    String sql = "select * from t_user WHERE name=?";
    NativeQuery nativeQuery = session.createNativeQuery(sql, User.class);

    nativeQuery.setParameter(1,"马云");

    List<User> list = nativeQuery.list();
    System.out.println(list);
}

 

hql (推荐) 适用于一些简单的查询

criteria (推荐) 只适用于单表查询

SQL  (不推荐) 非常复杂的查询

Hibernate 中事务的应用

         事务应该在service 层 开启、提交和回滚。

事务的开启             需要session

获得session 有 两种方式:

  1. openSession  每次打开都是一个新的
  2. getCurrentSession  线程绑定的session    

service 层有session

dao层 有 session            这两个session必须保证是同一个session,这样事务的提交才能起作用

hibernate 框架中所有增删改查 都必须提交事务,才能最终修改到数据库

所以 在 增删改 操作中 必须使用 getCurrentSession

 

使用CurrentSession 必须在主配置文件中加入

<!--事务线程绑定--> <property name="hibernate.current_session_context_class">thread</property>