Hibernate学习——Day01

前言

记录我的Hibernate学习之路

开始

一、web内容基础

1.JavaEE三层结构
(1)表现层web层:Struts2 框架(MVC是一个表现层的设计模型)
(2)业务层sevice层:spring框架
(3)持久层 DAO层:Hibernate框架
DAO层是对数据库进行CRUD(增删改查)操作的。
Hibernate只能和数据库打交道(操作数据库)

2.MVC思想
(1)M:Model模型
(2)V:View视图
(3)C:Controller控制器

二、Hibernate框架概述

什么是Hibernate框架:
(1)Hibernate框架是应用在JavaEE三层结构中DAO层的框架
(2)在DAO层里面使用Hibernate对数据库做CRUD操作,Hibernate底层代码就是JDBC,Hibernate就是对JDBC进行封装,不需要写复杂的sql语句。
(3)Hibernate是一个开源的轻量级框架
(4)Hibernate版本:
Hibernate3.X
Hibernate4.X
Hibernate5.X(学习)

三、ORM思想介绍

1.Hibernate使用orm思想对数据库进行CRUD操作
2.在Web阶段学习JavaBean,更正确的叫法为实体类
3.orm,即object relational mapping,对象关系映射
文字描述:
(1)让实体类和数据库表进行一一的对应关系,让实体类和数据库表进行对应,让实体类中的属性和表中的字段进行对应
(2)不需要直接操作数据库,而操作表对应实体类对象
画图描述:
这里写图片描述
这里写图片描述

四、Hibernate入门

1.搭建Hibernate环境
导入Hibernate的jar包,使用Hibernate的时候,有很多日志信息输出,有时候需要导入一些其他支持日志的jar包
不要忘记mysql驱动的一些jar包

2.创建实体类
使用Hibernate的时候,不需要自己手动创建数据库表,Hibernateyou自动建表功能

3.配置实体类和数据库表的基本对应关系,映射关系
通过Hibernate配置文件来实现这种映射关系
(1)创建一个xml格式的配置文件
映射配置文件的名称和位置没有固定要求,但一般使用的是xxxx.hbm.xml
(hibernate mapping),并且在实体类所在包中创建
图1
(2)配置文件是xml格式,在配置文件中首先引入xml约束
在hibernate里面引入的约束一般是dtd约束

<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

(3)配置映射关系

<hibernate-mapping package="com.how2java.pojo">
   <!-- 表示类Product对应表product_ -->
    <class name="Product" table="product_">
        <!-- 表示属性id,映射表里的字段id -->
        <id name="id" column="id">
            <!--<generator class="native"> 意味着id的自增长方式采用数据库的本地方式    -->
            <generator class="native">
            </generator>
        </id>
         <!-- 配置其他属性和表字段的对应 -->
        <property name="name" />
        <property name="price" />
        <many-to-one name="category" class="Category" column="cid"/>

         <set name="users" table="user_product" lazy="false">
            <key column="pid" />
            <many-to-many column="uid" class="User" />
        </set>  

    </class>

</hibernate-mapping>

4.创建Hibernate核心配置文件
(1)核心配置文件格式也是xml,但是核心配置文件名称和位置是固定的。
位置:必须在src下面
名称:必须hibernate.cfh.xml
可见上3.(1)中图项目架构的位置

(2)引入dtd约束

<!DOCTYPE hibernate-configuration PUBLIC
       "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

(3)Hibernate操作过程中,只会加载核心配置文件,其他文件不会加载
第一部分:配置数据库的相关信息

第二部分:配置Hibernate相关信息

第三部分:把映射文件放到核心配置文件中

<!-- hibernate配置文件 -->
<hibernate-configuration>

    <session-factory>
        <!-- 第一部分:配置数据库的相关信息 -->
        <!-- Database connection settings -->
        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="connection.url">jdbc:mysql://localhost:3306/test?characterEncoding=UTF-8</property>
        <property name="connection.username">root</property>
        <property name="connection.password">admin</property>

        <!-- 第二部分:配置Hibernate相关信息 -->
        <!-- SQL dialect -->
        <!-- 这表示使用MYSQL方言。 什么方言呢? 
            因为在代码层面,开发人员不用关心底层到底用Oracle还是Mysql,写的代码都是一样的。 
            可是Oracle和Mysql所用的sql语句的语法是有所区别的,那么这件事就交给Hibernate来做了。
            这个时候就需要告诉Hibernate底层用的是什么数据库,它才知道应该用什么样的“方言” 去对话。 -->
        <property name="dialect">org.hibernate.dialect.MySQLDialect</property>

        <!-- 这是Hibernate事务管理方式,即每个线程一个事务 -->
        <property name="current_session_context_class">thread</property>

        <!-- 这表示是否在控制台显示执行的sql语句 -->
        <property name="show_sql">true</property>
        <!-- 这表示是否在控制台显示执行的sql语句格式化 -->
        <property name="hibertate.format_sql">true</property>

        <!-- 这表示是否会自动更新数据库的表结构,有这句话,其实是不需要创建表的,因为Hibernate会自动去创建表结构 
            原因:使用update:如果已经有表,更新,如果没有则创建-->
        <property name="hbm2ddl.auto">update</property>


        <!-- 第三部分:把映射文件放到核心配置文件中 -->
        <!-- 这表示Hibernate会去识别Product这个实体类 下面同理 -->
        <mapping resource="com/how2java/pojo/Product.hbm.xml" />
        <mapping resource="com/how2java/pojo/Category.hbm.xml" />
        <mapping resource="com/how2java/pojo/User.hbm.xml" />

    </session-factory>

</hibernate-configuration>

5.实现添加操作
(1)加载Hibernate核心配置文件
(2)创建SessionFactory对象
(3)使用SessionFactory创建Session对象
(4)开启事务
(5)写具体CRUD逻辑
(6)提交事务
(7)关闭资源

package com.how2java.test;

import java.util.HashSet;
import java.util.Set;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

import com.how2java.pojo.Category;
import com.how2java.pojo.Product;
import com.how2java.pojo.User;

public class TestHibernate {
    public static void main(String[] args) {

        //加载Hibernate核心配置文件
        //到src下面找到名称是hibernate.cfg.mxl
        //Configuation cfg = new Configuation().configure();
        //创建SessionFactory对象
        //SessionFactory sessionFactory = cfg.buildSessionFactoty();
        //读取hibernate.cfg.xml文件内容,创建SessionFactory
        //在这个过程中,根据映射关系,在数据库中把表创建
        SessionFactory sf = new Configuration().configure().buildSessionFactory();

        //使用SessionFactory创建Session对象
        Session s = sf.openSession();

        //开启事务
        //hibernate中的事务由s.beginTransaction();开始
        s.beginTransaction();

        /*插入
        for(int i=0;i<10;i++) {
            Product p = new Product();
            p.setName("iphone"+i);
            p.setPrice(i);
            s.save(p);
        }

        new 了一个Product();,在数据库中还没有对应的记录,这个时候Product对象的状态是瞬时的。 

        通过Session的save把该对象保存在了数据库中,
        该对象也和Session之间产生了联系,此时状态是持久的。

        最后把Session关闭了,这个对象在数据库中虽然有对应的数据,
        但是已经和Session失去了联系,相当于脱离了管理,状态就是脱管的

        Product p = new Product();
        p.setName("p1");
        System.out.println("此时p是瞬时状态");
        s.save(p);
        System.out.println("此时p是持久状态");
        s.getTransaction().commit();
        s.close();
        System.out.println("此时p是脱管状态");
        sf.close();


        调用Session的get方法,根据id获取对象。 除了id之外,还需要传递一个类对象,
                 毕竟需要知道获取的是哪个对象

        除了使用get方法,还可以使用load获取对象。 请参考get和load的区别

        Product p =(Product) s.get(Product.class, 6);

        System.out.println("id=6的产品名称是: "+p.getName());

                        删除一条数据
        s.delete(p);

                       修改数据
        System.out.println(p.getName());

        p.setName("iphone-modified");

        s.update(p);


        TestHibernate 测试many-to-one关系
        Category c =new Category();
        c.setName("c1");
        s.save(c);

        Product p = (Product) s.get(Product.class, 8);
        p.setCategory(c);
        s.update(p);


        TestHibernate 测试one-to-many关系
        Category c = (Category) s.get(Category.class, 1);
        Set<Product> ps = c.getProducts();
        for (Product p : ps) {
            System.out.println(p.getName());
        }


        //TestHibernate 测试many-to-many关系
        //增加3个用户
        Set<User> users = new HashSet();
        for (int i = 0; i < 3; i++) {
            User u =new User();
            u.setName("user"+i);
            users.add(u);
            s.save(u);
        }

        //产品1被用户1,2,3购买
        Product p1 = (Product) s.get(Product.class, 1);

        p1.setUsers(users);
        s.save(p1);
        */

        //hibernate中的事务由s.getTransaction().commit();结束
        //在同一个事务中执行的操作,一方失败,则全部失败。
        //因为这两个操作都是在一个事务中,而且第二个操作失败了,所以最后的结果是两个操作都没有生效
        //在Mysql中,只有当表的类型是INNODB的时候,才支持事务,所以需要把表的类型设置为INNODB,否则无法观察到事务.
        s.getTransaction().commit();
        s.close();
        sf.close();
    }

}

看到效果:
(1)是否生成表
(2)看表中是否有记录
我做了好多例子,都在上面代码的注释里,这里就不展示了。

五.Hibernate配置文件详解

1.Hibernate映射配置文件
(1)映射配置文件的名称和位置没有固定要求
(2)映射配置文件中,标签name写实体类相关内容,其中class标签中的name属性值写实体类的路径,id标签和property标签 的name属性值写实体类属性名称
(3)id标签和peoperty标签,column属性可以不写,此时默认和name属性一样
(4)property标签中还有一个type属性,设置生成表的字段的数据类型,一般不用。因为Hibernate会自动生成相应的数据类型。

2.Hibernate核心配置文件
(1)配置要写在标签内
(2)配置时:数据库的部分是必须的,Hibernate部分是可选的,映射文件是必须的
(3)核心配置文件名称和位置是固定的
名称: hibernate.cfg.xml
位置:src下面

六、Hibernate核心api

1.Configuation

Configuration cfg = new Configuration();
cfg.configure();

到src下面找到名称是hibernate.cfg.xml配置文件,找到对象,把配置文件放到对象里面(加载核心配置文件),也有自定义路径的配置方式。

2.SessionFactory
(1)使用Configuration的对象可以创建SessionFactory对象

SessionFactory sessionFactory = cfg.buildSessionFactory();

创建SessionFactory过程中做的事情:
根据核心配置文件,有数据库配置,有映射文件部分,到数据库中根据映射关系把表创建

(2)创建SessionFactory的过程中,要不断的创建表,特别消耗资源,在Hibernate操作中,建议一个项目一般创建一个SessionFactory对象
具体实现:
写一个工具类,使用静态代码块实现,因为静态代码块只会实现一次,并且在类加载的时候执行。
这里写图片描述

3.Session
(1)Session 类似于JDBC中的 connection
(2)调用session中不同的方法来完成CRUD操作
添加save方法
修改update方法
删除delete方法
根据id查询get方法
(3)session对象是单线程对象
表示session对象不能共用,只能自己使用

4.Transaction
事务对象
(1)开启事务

Transaction  tx = session.beginTransaction();

(2)事务的提交和回滚方法

tx.commit();
tx.rollback();

(3)事务的四个特性
原子性,一致性,隔离性,持久性

七、解决配置文件没有提示问题

(1)可以上网
(2)把约束文件引入到eclipse中

猜你喜欢

转载自blog.csdn.net/zyw644451/article/details/80359839