zoukankan      html  css  js  c++  java
  • 01.Hibernate入门

        前言:本文用一个简单的Hibernate应用程序例子来引领初学者入门,让初学者对Hibernate的使用有一个大致的认识。本文例子使用了MySQL数据库、Maven管理工具、Eclipse开发工具,创建的项目是Maven项目但是本质上只是用了Java SE的东西。

    1.在Maven项目中引入Hibernate库

        我们可以在Maven官网上搜索Hibernate库,选择Hibernate版本,复制Maven依赖代码到pom.xml文件引用Hibernate。由于当前Hibernate的最新版是4.3.8.Final所以我的引用如下:
    1. <!-- 依赖项定义 -->
    2. <dependencies>
    3. <dependency>
    4. <groupId>org.hibernate</groupId>
    5. <artifactId>hibernate-core</artifactId>
    6. <version>4.3.8.Final</version>
    7. </dependency>
    8. <dependency>
    9. <groupId>mysql</groupId>
    10. <artifactId>mysql-connector-java</artifactId>
    11. <version>5.1.34</version>
    12. </dependency>
    13. </dependencies>
        如果你没有使用Maven,你也可以到Hibernate官网下载Hibernate引用到项目里,不过我在这里强烈推荐大家使用Maven管理项目,因为Maven管理很方便,它不需要你去网上找项目依赖的Jar文件,一个依赖配置就搞定。并且Maven的官网很强大几乎所有的Java开源项目都可以在这里找到!下面提供Maven的官网和Hibernate的官网:Maven:http://mvnrepository.com/ Hibernate:http://hibernate.org/

    2.搭建数据库环境(MySQL)

        为了测试我在本地计算机安装了Linux虚拟机,并在虚拟机中安装了MySQL数据库。下面是我新建的测试表(tb_teacher):
    1. CREATE TABLE tb_teacher
    2. (
    3. id bigint NOT NULL auto_increment COMMENT 'ID',
    4. no varchar(10) NOT NULL COMMENT '教师编号',
    5. name varchar(50) NOT NULL COMMENT '教师姓名',
    6. sex char(1) NOT NULL COMMENT '教师性别',
    7. job_title varchar(50) NOT NULL COMMENT '职称',
    8. PRIMARY KEY (id)
    9. ) COMMENT = '教师信息表';

    3.设置Hibernate配置文件(hibernate.cfg.xml)

        hibernate.cfg.xml配置文件需要放到项目ClassPath根路径,hibernate.cfg.xml配置文件是Hibernate的核心配置文件,其作用是:设置数据源、配置Hibernate属性、设置映射文件(*.hbm.xml)等。下面是一个简单的配置:
    1. <!DOCTYPE hibernate-configuration PUBLIC
    2. "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
    3. "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
    4. <hibernate-configuration>
    5. <session-factory>
    6. <!-- 设置MySQL的数据库路径、用户名、密码 -->
    7. <property name="hibernate.connection.url">jdbc:mysql://192.168.10.201:3306/Study</property>
    8. <property name="hibernate.connection.username">root</property>
    9. <property name="hibernate.connection.password">lizhiwei</property>
    10. <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
    11. <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
    12. <!-- Hibernate配置 -->
    13. <property name="connection.pool_size">1</property>
    14. <property name="show_sql">true</property>
    15. <property name="current_session_context_class">thread</property>
    16. <property name="hibernate.cache.use_second_level_cache">false</property>
    17. <property name="hibernate.format_sql">true</property>
    18. <!-- 设置实体类到数据库的映射文件 -->
    19. <mapping resource="model/Teacher.hbm.xml"/>
    20. </session-factory>
    21. </hibernate-configuration>
        对于上面的配置的说明:
    1. hibernate.dialect:设置数据库方言,我使用的MySQL数据库就用MySQL数据库的方言。
    2. connection.pool_size:设置数据库连接池大小。
    3. current_session_context_class:与SessionFactory.getCurrentSession()相关,如果得到一个Session是调用这个方法(并非openSession())那么会使用这个属性。
    4. show_sql:配置是否显示Hibernate操作数据库的SQL,调试时非常有用。
    5. hibernate.format_sql:与show_sql配合使用,用于格式化打印的SQL。
    6. hibernate.cache.use_second_level_cache:是否使用Hibernate的二级缓存,关于二级缓存的使用后面的章节会讲到。
    7. <mapping resource="model/Teacher.hbm.xml"/>:设置实体类与数据库表的映射文件,关于这个映射文件的作用和内容会在下面讲到。

    4.创建实体类与其映射文件(Teacher.hbm.xml)

        实体类的创建要与前面新建的表(tb_teacher)对应,下面是我的实体类(Teacher.java):
    1. package model;
    2. /**
    3. * 教师信息表
    4. * */
    5. public class Teacher
    6. {
    7. /** ID */
    8. private Long id;
    9. /** 教师编号 */
    10. private String no;
    11. /** 教师姓名 */
    12. private String name;
    13. /** 教师性别 */
    14. private String sex;
    15. /** 职称 */
    16. private String job_title;
    17. //省略setter、getter、toString...
    18. }
        创建好实体类后,Hibernate并不知道这个实体类会与数据库中的tb_teacher表对应,所以还要创建一个配置文件告诉Hibernate实体类与数据库表的映射细节,配置文件如下(Teacher.hbm.xml):
    1. <!DOCTYPE hibernate-mapping PUBLIC
    2. "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    3. "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
    4. <hibernate-mapping package="model">
    5. <class name="Teacher" table="tb_teacher">
    6. <id name="id" column="id">
    7. <generator class="native"></generator>
    8. </id>
    9. <property name="no" column="no"/>
    10. <property name="name" column="name"/>
    11. <property name="sex" column="sex"/>
    12. <property name="job_title" column="job_title"/>
    13. </class>
    14. </hibernate-mapping>
        注意:这个配置文件的位置要与Teacher.java类在同一个文件夹下,并且并命必须是:[实体类名].hbm.xml。但这不是不必需的,这是Hibernate默认的规则,若要改变就要在hibernate.cfg.xml中加上额外的配置。
        对于Teacher.hbm.xml配置的说明:
    1. package="model":用于设置实体类的命名空间。
    2. name="Teacher" table="tb_teacher":设置实体类名与数据库表名的映射。
    3. <id name="id" column="id">:设置实体类的属性与数据库的主键的映射。
    4. <generator class="native"></generator>:设置主键的生成方式,如:自定义、序列、自增长等。native表示根据底层数据库对自动生成标识的能力自动选择。
    5. <property name="no" column="no"/>:设置实体类属性与数据库字段的映射关系。

    5.编写测试代码(Holle World)

        编写测试代码必然会用到Hibernate API,这里我先看看测试代码和其运行的效果,再简单的分析一下Hibernate API的接口与其使用,代码如下(Test01.java):
    1. package test;
    2. import model.Teacher;
    3. import org.hibernate.Session;
    4. import org.hibernate.SessionFactory;
    5. import org.hibernate.cfg.Configuration;
    6. import org.hibernate.service.ServiceRegistry;
    7. import org.hibernate.service.ServiceRegistryBuilder;
    8. @SuppressWarnings("deprecation")
    9. public class Test01
    10. {
    11. public static void main(String[] args)
    12. {
    13. Configuration cfg = new Configuration();
    14. cfg.configure();
    15. ServiceRegistry sr = new ServiceRegistryBuilder().applySettings(cfg.getProperties()).buildServiceRegistry();
    16. SessionFactory sf = cfg.buildSessionFactory(sr);
    17. System.out.println("连接数据库");
    18. Session session = sf.openSession();
    19. Teacher teacher =(Teacher) session.get(Teacher.class, new Long(1));
    20. System.out.println(teacher);
    21. session.close();
    22. System.out.println("关闭数据库");
    23. System.exit(0);
    24. }
    25. }
        这段代码的作用是从数据库中找到ID==1的Teacher记录并打印在控制台,运行效果如下(省略了部分Hibernate日志):
    1. 连接数据库
    2. Hibernate:
    3. select
    4. teacher0_.id as id1_0_0_,
    5. teacher0_.no as no2_0_0_,
    6. teacher0_.name as name3_0_0_,
    7. teacher0_.sex as sex4_0_0_,
    8. teacher0_.job_title as job_titl5_0_0_
    9. from
    10. tb_teacher teacher0_
    11. where
    12. teacher0_.id=?
    13. tb_teacher [id=1, no=000001, name=教师1, sex=女, job_title=初级教师]
    14. 关闭数据库
        从打印结果中可以看出数据库中的记录“tb_teacher [id=1, no=000001, name=教师1, sex=女, job_title=初级教师]”,还可以看到Hibernate查询所用的SQL语句。

    ​6.Hibernate API接口简介

    (1)Hibernate核心接口介绍
    1. Configuration接口:配置Hibernate,启动Hibernate,创建SessionFactory对象。
    2. SessionFactory接口:初始化Hibernate,充当数据源的代理,创建Session对象。
    3. Session接口:负责保存、更新、删除、加载和查询对象。
    4. Transaction接口:事务管理接口。
    5. Query和Criteria接口:用于执行数据库查询。
    6. Callback接口:Hibernate事件回调接口。
    (2)Configuration接口
        Configuration接口的作用是对Hibernate进行配置,以及对它进行启动。在Hibernate的启动过程中,Configuration类实例首先定位映射文档的位置,读取这些配置,然后创建一个SessionFactory对象。
        Configuration对象的作用是除了有读取配置文件的功能,还能创建SessionFactory对象。通常,一个应用程序会创建一个Configuration对象,然后利用Configuration实例建立唯一的SessionFactory实例,这就意味着Configuration对象只存在于系统的 初始化阶段,然后所有的持久化操作都能通过这个唯一的SessionFactory实例来进行。
        Configuration对象只有在Hibernate 进行初始化的时候才需要创建,当使用Configuration对象的实例创建了SessionFactory对象的实例后,其配置信息已经绑定在他返回的SessionFactory对象实例中。因此,一般情况下,得到SessionFactory对象后,Configuration对象的使命就结束了。
        重要方法:
        public Configuration configure (*)
            在参数中指定要加载的配置文件
        public SessionFactory buildSessionFactory()
            根据配置文件实例化一个新的SessionFactory对象,这个SessionFactory将是不可变的,所以在创建了SessionFactory对象后,对Configuration对象作出的所有修改不会影响以前创建出的SessionFactory对象。
    (3)SessionFactory接口
        这里用到了一个设计模式—工厂模式,用户程序从工厂类SessionFactory中取得Session的实例。SessionFactory不是轻量级的!它的设计者的意图是让它能在整个应用共享。典型地来说,一个项目通常只需要一个SessionFactory就够了,但是当你的项目要操作多个数据库时,那你必须为每个数据库指定一个SessionFactory。一个SessionFactory实例对应一个数据存储源,应用从SessionFactory中获得Session实例。它具有如下特点:
    1. 它是线程安全的,这意味着它的同一个实例可以被应用的各个线程共享。
    2. 它是重量级的,这意味着不能随意创建或销毁它的实例。
    3. 之所以说SessionFactory是重量级的,是因为它需要一个很大的缓存,用来存放预定义的SQL语句以及映射元数据等。用户还可以为SessionFactory配置一个缓存插件,这个缓存插件被称为Hibernate的第二级缓存,该缓存用来存放被工作单元读过的数据,将来其它工作单元可能会重用这些数据,因此这个缓存中的数据能够被所有工作单元共享,一个工作单元通常对应一个数据库事务。SessionFactory接口负责初始化Hibernate。
        重要方法:
        public Sessioin openSession()
            创建一个数据库连接,并把他放在Session对象中,并返回
        public Session openSession(Connection connection)
            创建一个Session对象,并把参数给出的 connection对象放在其中
        public boolean isClosed()
            判断当前SessionFactory对象是否关闭了
        public void close()
            关闭SessionFactory以及释放所有的SessionFactory涉及到的资源(缓存,数据库连接池等)但在调用此方法之前,应该确定没有当前对象创建的 Session没有关闭
    (4)Session接口
        Session接口对于Hibernate 开发人员来说是一个最重要的接口。然而在Hibernate中,实例化的Session是一个轻量级的类,创建和销毁它都不会占用很多资源。这在实际项目中  确实很重要,因为在客户程序中,可能会不断地创建以及销毁Session对象,如果Session的开销太大,会给系统带来不良影响。Session具有一下特点:
    1. 不是线程安全的,因此在设计软件架构时,应该避免多个线程共享同一个Session实例。
    2. Session实例是轻量级的,所谓轻量级,是指它的创建和销毁不需要消耗太多的资源。这意味着在程序中可以经常创建和销毁Session对象,例如为每个客户请求分配单独的 Session实例,或者为每个工作单元分配单独的Session实例。
    3. Session有一个缓存,被称为Hibernate的第一级缓存,它存放被当前工作单元加载的对象。每个Session实例都有自己的缓存,这个Session实例的缓存只能被当前工作单元访问。Session接口负责执行被持久化对象的CRUD操作 (CRUD的任务是完成与数据库的交流,添加、更新、删除、加载和查询对象,包含了很多常见的SQL语句)。
        在Hibernate的设计者的头脑中,他们将session看作介于数据连接与事务管理一种中间接口。我们可以将session想象成一个持久对象的缓冲区,Hibernate能检测到这些持久对象的改变,并及时刷新数据库。我们有时也称Session是一个持久层管理器,因为它包含这一些持久层相关的操作,诸如存储持久对象至数据库,以及从数据库中获得它们。请注意,Hibernate 的session不同于JSP应用中的HttpSession。以后会将HttpSesion对象称为用户session。
        重要方法:
        public Transaction beginTransaction()
            在数据库中重新开始一个事务
        public Transaction getTransaction()
            返回和当前session联系的Transaction对象
        public Connection connection close()
            结束当前的Session对象
        public void clear()
            清空Session,清除所有保存在当前Session缓存中的实体对象,终止所有正在执行的方法(eg: save() , update() ,delete() .....)
        public Serializable save(Object object)
            对当前参数指定的对象进行持久化(系统会首先赋予参数对象一个标识符OID),他相当于insert语句 后面在详细介绍
        public Connection connection()
            得到当前Session 中包含的Connection对象。
        public boolean contains(Object object)
            判断参数给出的对象(持久化类)是否在当前Session的缓存中 
        public void evict(Object object)
            将参数给出的Object从当前Session对象类中删除,使这个对象从持久态变成游离态,这种状态的改变不会引起对数据库的同步
        public Object load(Class theclass ,Serializable id)
            返回第一个参数指定类对应的表中,第二个参数指定的行(第二个参数就是要取得对象的OID,他对应表中主键列的值)
        public void update(Object object)
            更新一个对象到数据库中
        public void delete (Object object)
            从数据库中删除和参数指定的对象对应的记录
        public Object get(Class class,Serializable id)
            和load()方法一样区别在于,如果数据库表中没有对应的记录,get()方法返回null,load()方法将报异常
    (5)Transaction接口
        Transaction接口是一个可选的API,你可以选择不使用这个接口,取而代之的是Hibernate的设计者自己写的底层事务处理代码。它将应用代码从底层的事务实现中抽象出来——这可能是一个JDBC事务(Connection事务,基于数据库的事务),一个JTA事务(基于分布式的事务,同时管理多个数据库之间的事务)或者甚至是一个公共对象请求代理结构(CORBA)——允许应用通过一组一致的API控制事务边界。这有助于保持Hibernate应用在不同类型的执行环境或容器中的可移植性。
        Transaction tx = session.beginTransaction();
        注意:使用Hibernate进行操作时(增、删、改)必须显示的调用Transaction(默认:autoCommit=false)。
        重要方法:
        public void commit()
            刷新当前的Session以及结束事务的工作,提交事务
        public void rollback()
            强迫回滚当前事务 
        public boolean isActive()
            这个事务是否存活
    (6)Query和Criteria接口
        它们是Hibernate的查询接口,用于向数据库查询对象,以及控制执行查询的过程。query实例封装了一个HQL(Hibernate Query Language)查询语句,HQL是面向对象的,它引用类名及类的属性名,而不是表名及表的字段名。Criteria接口完全封装了基于字符串形式的查询语句,比Query接口更加面向对象,Criteria接口更擅长于执行动态查询。 Query接口让你方便地对数据库及持久对象进行查询,它可以有两种表达方式:HQL语言或本地数据库的SQL语句。Query经常被用来绑定查询参数、限制查询记录数量,并最终执行查询操作。
        Criteria接口与Query接口非常类似,它允许你创建并执行面向对象的标准化查询。
        值得注意的是Query接口也是轻量级的,它不能在Session之外使用。Session接口的find()方法也具有数据查询功能,但它只是执行一些简单的HQL查询语句的快捷方法,它的功能远没有Query接口强大。
    (7)Callback接口
        当一些有用的事件发生时—例如持久对象的载入、存储、删除时,Callback接口会通知Hibernate去接收一个通知消息。一般而言,Callback接口在用户程序中并不是必须的,但要在项目中创建审计日志时,可能会用到它。
    -------------------------------------------------------------------------------------------------------------------------------




  • 相关阅读:
    ES6 学习记录
    Windows 服务开发 以及 重启IIS应用池
    IIS部署.net core 3.1踩坑总结
    VS 2019背景全透明以及插件、特效
    深拷贝和浅拷贝的区别
    Vue全家桶以及常用知识点
    C#设计模式
    博客园装扮教程
    Exp5 单元测试
    Exp4 代码评审
  • 原文地址:https://www.cnblogs.com/LiZhiW/p/4264049.html
Copyright © 2011-2022 走看看