【Java中级】6.0 SSH之Hibernate框架(二)——使用Hibernate完成CRM客户管理(下)

1.0 导入Junit的jar包

在项目的实际开发中,我们需要在完成每层的功能代码实现之后去对该功能的代码进行测试,这是因为如果在所有的代码都写完之后在测试的话,会造成调试困难,代码修改起来也很繁琐,这样开发效率会大大降低,不利于项目的开发。这时候需要用到Junit包。导入Junit如下所示:


image.png

image.png

image.png

image.png

image.png
2.0 编写测试代码

5.3.15版本代码如下:

package com.edp.learn;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.Service;
import org.hibernate.service.ServiceRegistry;
import org.junit.Test;

/**
 * Hibernate入门案例
 * 
 * @author EdPeng
 * @version 创建时间 2020年1月15日上午9:37:42 
 * 类说明
 */

public class HibernateDemo1 {
    @Test
    // 保存客户的案例
    public void demo1() {
        // 4.3版本以下的方法
//      //1.加载hibernate的核心配置文件
//      Configuration  configuration = new Configuration().configure();
//      //这样才知道连接的是哪个数据库,采用的是何种方言
//      
//      //2.创建一个SessionFactory对象,类似于JDBC中连接池
//      SessionFactory sessionFactory=configuration.buildSessionFactory();
//      //3.通过SessionFactory,获取Session对象。类似于JDBC中的Collection
//      //相当于Hibernate已经和MySQL数据库建立起连接了
//      Session session = sessionFactory.openSession();
//      //4.手动开启事务:在hibernate5以后,不用手动开启事务,但这是为了去兼容hibernate3
//      Transaction transaction = session.beginTransaction();
//      //5.编写代码
//      Customer customer=new Customer();
//      customer.setCust_name("张三");
//      session.save(customer);
//      //6.事务提交
//      transaction.commit();
//      //等同于session.getTransaction().commit();
//      //7.资源释放
//      session.close();
//      Hibernate5.3时的方法
        //1.加载hibernate的核心配置文件
        //这样才知道连接的是哪个数据库,采用的是何种方言
        //2.创建一个SessionFactory对象,类似于JDBC中连接池
        StandardServiceRegistry  sr = new StandardServiceRegistryBuilder().configure().build(); 
        //3.通过SessionFactory,获取Session对象。类似于JDBC中的Collection
        //相当于Hibernate已经和MySQL数据库建立起连接了
        SessionFactory sf = new MetadataSources(sr).buildMetadata().buildSessionFactory();       
        
        Session session = sf.openSession();
        //4.手动开启事务:在hibernate5以后,不用手动开启事务,但这是为了去兼容hibernate3
        Transaction ts = session.beginTransaction();
        //5.编写代码
        Customer customer = new Customer();
        customer.setCust_name("张三");
        session.save(customer);
        //6.事务提交
        ts.commit();
//      等同于session.getTransaction().commit();
        //7.资源释放
        session.close();

    }
}

5.4.10版本代码如下:

package com.edp.learn;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.Service;
import org.hibernate.service.ServiceRegistry;
import org.junit.Test;

/**
 * Hibernate入门案例
 * 
 * @author EdPeng
 * @version 创建时间 2020年1月15日上午9:37:42 
 * 类说明
 */

public class HibernateDemo1 {
    @Test
    // 保存客户的案�?
    public void demo1() {
        // 4.3版本以下5.4以上的方式
        //1.加载hibernate的核心配置文件�?
        Configuration  configuration = new Configuration().configure();
        //这样才知道连接的是哪个数据库,采用的是何种方言
        
        //2.创建1个SessionFactory对象,类似于JDBC中连接池
        SessionFactory sessionFactory=configuration.buildSessionFactory();
        //3.通过SessionFactory,获取Session对象。类似于JDBC中的Collection
        //相当于Hibernate已经和MySQL数据库建立起连接池
        Session session = sessionFactory.openSession();
        //4.手动开启事务:在hibernate4以后,不用手动开启事务,但这是为了去兼容hibernate3
        Transaction transaction = session.beginTransaction();
        //5.编写代码
        Customer customer=new Customer();
        customer.setCust_name("张三");
        session.save(customer);
        //6.事务提交
        transaction.commit();
        //等同于session.getTransaction().commit();
        //7.资源释放
        session.close();

//      
//      //2.创建1个SessionFactory对象,类似于JDBC中连接池
//      StandardServiceRegistry  sr = new StandardServiceRegistryBuilder().configure().build(); 
//      
//      //3.通过SessionFactory,获取Session对象。类似于JDBC中的Collection
//      //相当于Hibernate已经和MySQL数据库建立起连接
//      SessionFactory sessionFactory = new MetadataSources(sr).buildMetadata().buildSessionFactory();       
//      
//      Session session = sessionFactory.openSession();
//      //4.手动开启事务:在hibernate5以后,不用手动开启事务,但这是为了去兼容hibernate3
//      Transaction ts = session.beginTransaction();
//      //5.编写代码
//      Customer customer = new Customer();
//      customer.setCust_name("李四");
//      session.save(customer);
//      //6.事务提交
//      ts.commit();
////        等同于session.getTransaction().commit();
//      //7.资源释放
//      session.close();
//      sessionFactory.close();

    }
}

在4.3以下版本中,需要用到Configuration 类,5.3版本也用到,但是作为内嵌使用,没有分开表示出来。其底层代码如下:


image.png

image.png

image.png

当前我用的hibernate版本为5.3.15,连接方式与众不同。
值得注意的是hibernate.cfg.xml文件也需要做相对的修改,以用于匹配hibernate5.3.15和MySQL8.0.xx版本(我的为8.0.18):

<?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>
    <!-- 根标签 -->
    <session-factory>
        <!-- 连接数据库的基本参数。 -->
        <!--<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property> -->
        <!-- MySQL8.0以后,用的连接驱动改变了,driver必须加上.cj -->
        <property name="hibernate.connection.driver_class">com.mysql.cj.jdbc.Driver</property>
        
        <!--MySQL8.0以后, url为jdbc:mysql://localhost:3306/test后面加?useSSL=false&serverTimezone=UTC -->
        <property name="hibernate.connection.url">jdbc:mysql:///hibernate_learn?useSSL=false&amp;serverTimezone=UTC</property>
        <!-- &符号在Hibernate不可用,需写成&amp;使用MySQL8Dialect -->
        <!-- jdbc:mysql://localhost:3306/hibernate_learn连接本地库可以省略,所以这里用/// -->
        <property name="hibernate.connection.username">root</property>
        <property name="hibernate.connection.password">bywwcnll</property>

        <!-- 配置hibernate的方言 告诉hibernate要识别MySQL的“方言”(这样,hibernate就能帮开发者生成MySQL识别的SQL语句) -->
        <!-- name="hibernate.dialect":表示Hibernate的方言就是MySQL -->
        <property name="hibernate.dialect">org.hibernate.dialect.MySQL8Dialect</property>
        <!--<property name="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property> -->
        <!--<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property> -->
        
        <!-- 可选配置 -->
        <!-- 打印SQL语句 -->
        <property name="hibernate.show_sql">true</property>
        <!-- 格式化SQL,使SQL语句在打印的时候更加漂亮 -->
        <property name="hibernate.format_sql">true</property>
        
        
        <!-- 告诉核心配置文件,我要加载哪个映射 -->
        <mapping resource="com/edp/learn/Customer.hbm.xml" />
    </session-factory>
</hibernate-configuration>

5.3.15版本运行结果如下:


image.png

5.4.10版本运行结果如下:


image.png

可见,如果你的hibernate核心配置文件名不为hibernate.cfg.xml,则需要如下编写代码:

        StandardServiceRegistry  sr = new StandardServiceRegistryBuilder()
                                  .configure("路径/自命名称.hbm.xml").build(); 

5.3.15版本运行后,查看数据库:


image.png

5.4.10版本运行后,查看数据库:


image.png

成功运行hibernate。

3.0 hibernate常见的配置

3.1 XML提示的配置
当我们的电脑处于联网状态时,如下图所示:


image.png

eclipse会自动连接绿色标记的网址,从网络上得到提示,提供开发人员此类XML文件的代码提示,但当不处于联网状态时,则没有任何提示,这时候需要我们自行配置。
首先我们需要在hibernate解压后的文件夹中找到两个文件:


image.png

提取出来,或者记住路径。然后打开Peferences:
image.png

搜索“xml ca”即可找到我们要找的“xml Catalog”,然后如下图指示
image.png

image.png

1是文档路径,2选Uri,3是复制如下内容得到的:


image.png

文档选择相应的文档:
image.png

最后点击OK,再点击Apply and Close。
image.png

凡是XML文件需要代码提示的都是如此配置。不仅仅限制于hibernate。
4.0 Hibernate映射的配置

首先我们先参考已经写过的配置:

<?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>
    <!-- hibernate-mapping是根标签 -->
    <!-- 建立类与表的映射 -->
    <class name="com.edp.learn.Customer" table="cst_customer">
        <!-- name:哪个类,全路径,table:哪个表 -->

        <!-- Id:建立类中的属性与表中的主键对应 -->
        <id name="cust_id" column="cust_id">
            <!-- name:在类中的名字 column:表中的字段;此处为一样的名称 -->
            <generator class="native" />
            <!-- 组件都有一种生成策略,此处使用一种本地策略。 -->
        </id>
        <!-- 建立类中的普通属性和表的字段的对应 -->
        <!-- 除了主键以外的属性,都用property -->
        <property name="cust_name" column="cust_name" />
        <!-- 客户的名称 -->
        <property name="cust_source" column="cust_source" />
        <!-- 客户的来源 -->
        <property name="cust_industry" column="cust_industry" />
        <!-- 客户所属行业 -->
        <property name="cust_level" column="cust_level" />
        <!-- 客户的级别 -->
        <property name="cust_phone" column="cust_phone" />
        <!-- 客户的固定电话 -->
        <property name="cust_mobile" column="cust_mobile" />
        <!-- 客户的移动电话 -->
    </class>

</hibernate-mapping>
4.1 class标签的配置

标签作用

建立类与表的映射关系

常用属性

name:类的全路径
table:表名(类名和表名一致,table可以省略。)
catalog: 数据库名,可以不用写。

在本例中,如果使用catalog属性,代码示范如下:

<class name="com.edp.learn.Customer" table="cst_customer" catalog="hibernate_learn">

再如上的代码中,在 class标签中,nametable不一致, table标签必须声明,不然Hibernate会自动创建一个名为Customer的数据库。

4.2 id标签的配置

标签作用

用来建立类中的属性与表中的主键的对应关系。

常用属性名称 属性说明
name 类中的属性名
column 表中的字段名(类中的属性名和表中的字段名如果一致,column可以省略。)
length 长度
type 数据类型

主键中没有not-null属性,因为主键一定是非空的。

length: hibernate可以根据你的映射自动建表,只要运行自己的程序就可以帮你把表建立起来,在没有给定长度的情况下,会使用默认长度255。
自动创建表的配置代码如下:

        <!-- 可选配置 -->
        <!-- 打印SQL语句 -->
        <property name="hibernate.show_sql">true</property>
        <!-- 格式化SQL,使SQL语句在打印的时候更加漂亮 -->
        <property name="hibernate.format_sql">true</property>
        <!-- 自动创建表 -->
        <property name="hibernate.hbm2ddl.auto">update</property>
        
        <!-- 告诉核心配置文件,我要加载哪个映射 -->
        <mapping resource="com/edp/learn/Customer.hbm.xml" />
4.3 property标签的配置

标签作用

标签用来建立类中的普通属性与表的字段的对应关系。

常用属性名称 属性说明
name 类中的属性名
column 表中的字段名
length 长度
type 类型
not-null 是否非空,设置非空
unique 是否唯一,设置唯一

其中, type有三种写法。

  1. Java写法
<property name="cust_name" column="cust_name" length="32"
            type="java.lang.String" />
  1. Hibernate写法
        <property name="cust_source" column="cust_source" length="32"
            type="string" />
  1. MySQL数据库写法
<property name="cust_industry" length="32">
            <column name="cust_industry" sql-type="varchar"></column>
        </property>

但是,type我们一般不用去写,Hibernate会帮我们自动转换。
not-null标签,如下写法表示不能为空,unique标签表示不唯一:

        <property name="cust_name" column="cust_name" length="32" not-null="true" unique="false" />

property标签部分,完整代码如下:

<!-- 建立类中的普通属性和表的字段的对应 -->
        <!-- 除了主键以外的属性,都用property -->
        <property name="cust_name" column="cust_name" length="32" not-null="true" unique="false" />
        <!-- 客户的名称 -->
        <property name="cust_source" column="cust_source" length="32"
            type="string" />
        <!-- 客户的来源 -->
        <property name="cust_industry" length="32">
            <column name="cust_industry" sql-type="varchar"></column>
        </property>
        <!-- 客户所属行业 -->
        <property name="cust_level" column="cust_level" />
        <!-- 客户的级别 -->
        <property name="cust_phone" column="cust_phone" />
        <!-- 客户的固定电话 -->
        <property name="cust_mobile" column="cust_mobile" />
        <!-- 客户的移动电话 -->

property标签和id标签中,namecolumn一致, column标签可以不用声明。

5.0 Hibernate核心的配置
5.1 必须的配置
  1. 连接数据库的基本的参数

驱动类
url路径
用户名
密码

  1. 方言
5.2 可选的配置

显示SQL
格式化SQL
自动建表

none 不使用Hibernate的自动建表
create 如果数据库中已经有表,删除原有的表,重新创建新的表。如果没有表,新建表。(主要是做测试时使用)
create-drop 如果数据库已经有表,删除原有表,执行操作,删除这个表.如果没有表,新建一个,使用完删除该表。(主要是做测试时使用)
update 使用原来的表,如果没有,创建新的表。(可以更新表结构)
validate 如果没有表,不会创建表。只会使用数据库中原有的表。(校验映射和表结构是否一致)

在开发中,我们一般用updatevalidate属性。
测试create-drop 属性,想看到效果,需要在代码中把工厂给关了:

        //7.资源释放
        session.close();
        sessionFactory.close();

sessionFactory.close();语句执行时,就会删除之前新建的表。
示范代码如下:

        <!-- 打印SQL语句 -->
        <property name="hibernate.show_sql">true</property>
        <!-- 格式化SQL,使SQL语句在打印的时候更加漂亮 -->
        <property name="hibernate.format_sql">true</property>
        <!-- 自动创建表-->
        <property name="hibernate.hbm2ddl.auto">update</property>
5.3 映射文件的引入

引入映射文件的位置,示范代码如下:

<!-- 告诉核心配置文件,我要加载哪个映射 -->
        <mapping resource="com/edp/learn/Customer.hbm.xml" />
6.0 Hibernate的核心配置方式
6.1 属性文件的方式

属性文件的名字一般为:Hibernate.properties
属性文件的写法和XML文件基本一致,具体参考上一篇我的文章中的最后附文Hibernate.properties中具体内容,示范代码如下:

        hibernate.connection.driver_class=com.mysql.cj.jdbc.Driver
        …
        hibernate.show_sql=true

但是,属性文件的方式不能引入映射文件(需要手动编写代码加载映射文件)。

6.2 XML文件的方式(一般情况用这种)

XML文件的名字一般为:hibernate.cfg.xml

END

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