Hibernate框架学习

 

  • 什么是框架

框架就是一个半成品的项目,我们书写项目可以从半成品的项目开始写,这样能够大大的提高开发效率。

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

  • 什么是Hibernate框架

这个框架应用于DAO层

ORM:Object relaction mapping

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

 

 

Hibernate框架搭建

 

1、导包

导入required目录下的所有包,然后在导入数据库驱动包

2、准备一个实体类

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

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

  • 属性的类型应是包装类型

  • 必须拥有一个主键

3、准备数据库

数据库必须由我们自己建立,数据库表,可以由hibernte自动创建,如果手动创建,表中的字段要和实体类一一对应。

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

创建一个  实体类名+.hbm+.xml

建议这个文件的目录和实体类在同一目录下

Column:与数据库字段有关

 

<hibernate-mapping>
    <class name="cn.hd.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>
        <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/hibernate01</property>
        <!-- 数据库连接用户名 -->
        <property name="hibernate.connection.username">root</property>
        <!-- 数据库连接密码 -->
        <property name="hibernate.connection.password">123456</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="hibernate.connection.isolation">4</property>

        <mapping resource="cn/hd/bean/User.hbm.xml"></mapping>


    </session-factory>
</hibernate-configuration>

 

6、书写测试代码

 

public static void main(String[] args) {
    //读取配置文件
    Configuration cfg = new Configuration();
    cfg.configure();
    //创建sessionFaction
    SessionFactory sessionFactory = cfg.buildSessionFactory();
    //获得一个session
    Session session = sessionFactory.openSession();
    //开启事务
    Transaction transaction=session.beginTransaction();
    User user = new User();
    user.setName("大红");
    user.setSex("女");
    user.setAge(20);
    user.setBalance(28000);
    session.save(user);
    //提交事务
    transaction.commit();
    //释放资源
    session.close();
    sessionFactory.close();
}

 

配置文件详解

1、映射文件

<!--下面class中的类的路径,下面的class name属性可以简写-->
<hibernate-mapping>
    <!--映射类和数据库表之间的关系-->
    <!--name属性是实体类名 写完整路径名-->
    <!--table属性 数据库表名字-->
<class name="cn.hd.bean.User" table="t_user">
    <!--映射文件中必须拥有主键-->
    <id name="id" column="id">
        <!--主键生成策略
        identity:mysql自动递增
        increment:
        sequence:Orancel数据库中的自动递增
        native:自动递增(3和1)
        assigned
        uuid:百度
        -->
        <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>
 

2、核心配置文件详解

名字和位置都必须按照规定来

<hibernate-configuration>
    <session-factory>
        <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">123456</property>

        <!--方言 必须要设置

        -->
        <property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>

        <!--在控制台展示sql语句 不必须-->
        <property name="hibernate.show_sql">true</property>
        <!--sql语句格式化输出-->
        <property name="hibernate.format_sql">true</property>
<!--
        1、update 如果映射文件和数据库表保持一致就不修改,
        如果没有就自动创建表
        2、create 每次执行都会重新创建一个表
        3、create-drop 先将原来表删除 然后重新创建
        4、validate 只做校验,不修改表
-->
        <property name="hibernate.hbm2ddl.auto">update</property>

        <!--事务的隔离界别
        1
        2
        4
        8

        脏读
        幻读
        不可重复读
        串行化
        -->
        <property name="hibernate.connection.isolation">4</property>

        <!--扫描映射文件
        class 必须 映射文件和配置文件名字和路径保持一致
        package 扫描该报下的所有配置文件
        resource 指定某个确定xml配置文件
        -->
        <mapping resource="cn/hd/bean/User.hbm.xml"></mapping>


    </session-factory>
</hibernate-configuration>

3、HibernateAPI详解

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(20);
        user.setSex("女");
        user.setBalance(28000);

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

    }
}

 

 

 

 

Crud

保存 save(里面不允许有id)

更新 update

删除 delete

查找 get

 

 

 

 

 

 

Hibernate对象的状态

(下面id为主键)

瞬时状态:一个对象既没有id也没有和session绑定的对象

持久化状态:一个对象没有id也和session绑定在一起

游离状态:有id没有和session绑定

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

 

saveOrUpdate

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

 

 

 

Hibernate 查询

  1. hql

               hql是hibernate的独家语言。            

 @Test
public void fun(){
    //select * from t_user
    String hql = "from User";
    Query query = session.createQuery(hql);
    List<User> list = query.list();
    System.out.println(list);
}

//占位符查询
@Test
public void fun1(){
    //select * from t_user where name = ?
    //不会出现表名字和字段名,只会出现类名和类的属性名
    String hql = "from User where name = ?";
    Query query = session.createQuery(hql);
    //设置参数的时候,下标是从0开始
    query.setParameter(0,"狗子");
    List<User> list = query.list();
    System.out.println(list);
}

//占位符的方式有两种
//字符串的方式:+str
@Test
public void fun2(){
    /*String hql = "from User where name = :name";
    Query query = session.createQuery(hql);
    //设置参数的时候,下标是从0开始
    query.setParameter("name","狗子");
    //List<User> list = query.list();
    //System.out.println(list);
    User user= (User) query.uniqueResult();
    System.out.println(user);*/

    String hql="from User where name = :name and balance< :balance";
    Query query=session.createQuery(hql);
    //设置参数的时候, 下标是从0 开始
    query.setParameter("balance",12900);
    query.setParameter("name","张三");
    //        List<User> list=query.list();
    //       System.out.println(list);
    User user=(User)query.uniqueResult();
    System.out.println(user);

}

@Test
public void fun3(){
    String hql = "from User";
    Query query = session.createQuery(hql);
    //从第0条数据查找两个
    query.setFirstResult(0);
    query.setMaxResults(2);
    List<User> list = query.list();
    System.out.println(list);
}

  1. Criteria

or() 或者

and()  并且

equal() 等于

notEqual  不等于

like   模糊

isNull   为空

in()

 gt()大于

ge()   大于等于

lt  小于

lt()小于等于

Between  在,,,,之间

 

  1. 使用session创建criteriaBuilder

使用工厂类 创建criteriaQuery

指定根元素

添加条件

将条件封装到query

把query传给session.createrQuery

得到结果集

3、sql原生态的查询方式

应用的环境

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

criteria 推荐使用 只适用于单表查询

sql 不推荐 非常非常复杂的查询,推荐使用sql

 

 

事务

 

事务的出现就是为了解决事务安全

 

同时对两张表进行操作,当操作完第一张表,然后出现了异常导致第二张表的数据出现了问题,这样的情况就叫做事务安全。

 

事务特性:

原子性  一致性  持久性

 

由于有了事务,就有了问题叫做事务线程安全。

  1. 脏读数据

         张三 发货1 和李四 付钱2

             2开启的事务

             1 发货 事务的提交

              2 事务回滚

  1. 不可重复读

           酒店 两个柜台 A B 客户C

             C找到了A柜台 2201

           身份证找到了 2201房间没有了

           客户D 找到了柜台B 住房2201

  1. 虚读(幻读)

             数据库中又100条订单,读取了一次100条

              另外一个事务插入进来增加了一条订单,101

               有读取一次 发现前后读取的数据不一致

 

 

为了解决以上3个问题,事务隔离,隔离性 4中级别

1读未提交    哪种都不解决  (效率最高 最不安全)

2读已提交    脏读

4可重复读    脏读和不可重复读(最常用的Mysql默认的级别就是4)

8串行化      所有的问题都解决(效率最低)

 

 

 

 

Hibernate中事务的应用

事务应该在service层开启和提交或者回滚

 

事物的开启需要 session

获得session有两种方式:

       openSession 每次打开都是一个新的线程

       getCurrentSession 线程绑定的session

service层有session

dao层也有session    这两个session必须保证是同一个session

这样的事务的提交才能起作用

Hibernate框架中所有增删改 都必须提交事务才能最终修改到数据库,所以在增删改操作中必须使用getCurrentSession

 

使用currentSession必须再配置文件中假如属性

<property name="hibernate.current_session_context_class">thread</property>

 

 

 

表与表之间的关系


1对1关系  账号
1对多关系   
多对多关系

 

 

 

Hibernate维护一对多关系

  1. 在实体类中加上对应的属性

           职工类 加入一个 企业类型属性

           企业类 假如职工的集合 set

  1. 在配置文件中增加以下代码

多的一方

<many-to-one name="enterprise" class="cn.hd.bean.Enterprise" column="enterpriseId"></many-to-one>

一的一方

<set name="employees">
    <key column="enterpriseId"></key>
    <one-to-many class="cn.hd.bean.Employee"></one-to-many>
</set>

 

  1. 在代码中维护关系时

要为两方都添加对应的属性

 

 

 

级联操作

cascade

delete

create

save-update

加在多的一方 在代码中就要使用多的一方维护或者一的一方维护

<many-to-one cascade="save-update" name="enterprise" class="cn.hd.bean.Enterprise" column="enterpriseId"></many-to-one>

el.setEnterprise(enterprise);
e2.setEnterprise(enterprise);

 

加在一的一方就要用一的一方维护

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

enterprise.getEmployees().add(el);
enterprise.getEmployees().add(e2);
 
 

关系的维护

inverse true 就是放弃维护关系

让一的一方放弃(字段存在多的一方)

 

多对多关系

<set name="teachers" table="teacher_student" inverse="true">
    <key column="stuId"></key>
    <many-to-many column="teaId" class="cn.hd.bean.Teacher"></many-to-many>
</set>

 

 

 

 

Hibernate查询的方式

  1. crud

          get方法 需要主键和.class文件

  1. hql 比较常见(一般查询)
  2. criteria 适用于表单
  3. sql 适用于复杂查询
  4. 对象导航查询

分页查询

排序查询

基本条件查询

模糊查询

 

 

 

多表查询

  1. 笛卡尔积

         A集合 B集合

         A集合中和B集合中所有的元素,自由组合生成新的数据

  1. 内连接

         隐式内连接

SELECT * from t_employee,t_enterprise WHERE t_employee.enterpriseId=t_enterprise.id;

         显示内连接

SELECT * from t_employee t1 INNER JOIN t_enterprise t2 on t1.enterpriseId = t2.id;

  1. 外连接

          右外连接

SELECTSELECT * from t_employee t1 RIGHT JOIN t_enterprise t2 on t1.enterpriseId = t2.id;

左外连接和右外连接没有什么太大的区别

 

 

 

 

Hibernate实现多表查询

迫切内连接

String hql = "from Enterprise e inner join fetch e.employess";

内连接

String hql = "from Enterprise e inner join e.employess";

  区别就是:结果的封装一个是数组(普通),一个是对象(迫切);

 

 

 

 

检索策略

 

Hibernate缓存技术

Hibernate默认开启一级

二级缓存(废弃)redis

 

Hibernate批量抓取

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值