Hibernate知识体系总结(一)

    前言:JavaEE开发的三层架构:客户端->WEB层->业务逻辑层->持久层

客户端:PC、APP
WEB层:Servlet+JSP、Struts、SpringMVC
业务层:JavaBean、Spring
持久层:JDBC、DBUtils、 Hibernate、MyBatis

       理论上Servlet+JSP,JavaBean和JDBC可以开发所有的系统,但是一般公司都不会使用这种方式开发,效率太慢,性能差。企业会使用SSH(Struts,Spring,Hibernate)和SSM(SpringMVC,Spring,MyBatis)去开发,今天为大家带来的是Dao层框架Hibernate的知识体系。
       一共分为三部分介绍:
           1、Hibernate的简单使用(本文介绍)
           2、Hibernate的详细讲解(Hibernate知识体系总结二https://www.jianshu.com/p/c8149129fa1b)
           3、Hibernate表的关联关系(Hibernate知识体系总结三)
           4、Hibernate案例(Hibernate知识体系总结三)

一、简介:

       Hibernate是一个开源的ORM(Oobject Relational Mapping对象关系映射)框架,关系型数据库和对象之间的桥梁。在JDBC的基础上进行了封装,可以使用面向对象的思想进行操作数据库。
             对象<——>O/R映射<——>关系型数据库

二、特点:

1、简化了数据访问层的重复代码,减少了内存消耗,加快了运行效率
2、减少了DAO层的编码工作
3、映射灵活性好,支持一对一,一对多,多对多各种复杂关系
4、可扩展性强,由于开源,可以自行编码扩展

三、使用:

1、创建Java项目,笔者是用的是Intelli IDEA进行开发的,相关的配置见另一篇文章https://www.jianshu.com/p/3efaf423f8c1
2、下载Hibernate,链接如下:https://sourceforge.net/projects/hibernate/files/hibernate-orm/
这边下载的是hibernate-release-5.4.8.Final.zip

image.png

documentation:API文档
libs:jar包,required目录下面为必须jar
project:hibernate相关的源代码
3、准备数据库和表,这边创建的是一张学生成绩表
create database hibernate_summary;
create table grades(
id bigint(32) not null comment 'id(主键)',
s_id int(10) not null comment '学号',
s_name varchar(32) not null comment '学生姓名',
s_source varchar(10) not null comment '学生分数',
s_class varchar(32) not null comment '学生班级',
primary key (id)
)engine=innodb default charset=utf8;
数据表.png

4、创建实体类和对应的映射文件, 创建成绩类Grades,并在同包名下新建Grades.hbm.xml映射文件(一般命名为xxx.hbm.xml),在该文件中定义了实体类与表的映射关系
image.png

/**
 *  Hibernate持久化类编写规则:
 *  1、需要提供无参构造方法,底层使用反射生成类的实例
 *  2、属性私有化,提供共有get/set方法
 *  3、属性尽量使用包装类,包装类多一个null类型,这样就容易区分是否有存入数据
 *  4、需要有唯一表示OID与表的主键对应
 *  5、尽量不要使用final,导致延迟加载策略失效
 */
public class Grades {

    private Long id;
    private Integer s_id;
    private String s_name;
    private String s_source;
    private String s_class;

    public Integer getS_id() {
        return s_id;
    }

    public void setS_id(Integer s_id) {
        this.s_id = s_id;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getS_name() {
        return s_name;
    }

    public void setS_name(String s_name) {
        this.s_name = s_name;
    }

    public String getS_source() {
        return s_source;
    }

    public void setS_source(String s_source) {
        this.s_source = s_source;
    }

    public String getS_class() {
        return s_class;
    }

    public void setS_class(String s_class) {
        this.s_class = s_class;
    }
}

<?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 package="com.hibernate.domain">
    <!--
        class标签:建立类与表的映射关系
        name:类型全路径
        table:表名
    -->
    <class name="com.hibernate.domain.Grades" table="grades">
        <!--
            id标签:类中属性和表中主键的映射
            name:类中属性 column:表中字段
            注意:如果类中属性和表中字段名称一致,column可省略不写
        -->
        <id name="id" column="id">
            <!--
                自然主键:将具有业务含义的字段作为主键,比如身份证号码,存在且唯一
                代理主键:不具有业务含义,通常为整数类型,一般取名id

            generator:主键生成策略(7种)
                identity:主键自增,由数据库维护,录入时不需要指定主键
                sequence(了解):oracle中的主键策略
                increment(了解):主键自增,由hibernate维护,每次都会查找最大id,然后+1,生产中不使用,存在线程安全问题
                hilo(了解):hibernate维护,自增,高低位算法,开发中不使用
                native:hilo+sequence+identity 自动三选一策略
                uuid:生成随机数作为主键,主键类型必须是string类型
                assigned:自然主键生成策略,hibernate不会管理主键值,由开发人员自己录入
            -->
            <generator class="native"/>
        </id>
        <!--
            property标签:类中属性和表中字段ß的映射
        -->
        <property name="s_id"/>
        <property name="s_name"/>
        <property name="s_source"/>
        <property name="s_class"/>
    </class>
</hibernate-mapping>

5、创建Hibernate核心配置文件,在src下面创建hibernate.cfg.xml文件(默认名称),用于配置数据库链接,全局属性置以及加载映射文件,发布后会在项目的WEB-INF/classes目录下

<?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>
        <!-- 数据库url -->
        <property name="hibernate.connection.url">jdbc:mysql:///hibernate_summary?useUnicode=true&amp;characterEncoding=UTF-8&amp;useSSL=false&amp;autoReconnect=true</property>
        <!-- 数据库连接用户名 -->
        <property name="hibernate.connection.username">root</property>
        <!-- 数据库连接密码 -->
        <property name="hibernate.connection.password">root</property>
        <!-- 数据库方言
            不同的数据库中,sql语法略有区别. 指定方言可以让hibernate框架在生成sql语句时.针对数据库的方言生成.
            sql99标准: DDL 定义语言  库表的增删改查
                      DCL 控制语言  事务 权限
                      DML 操纵语言  增删改查
            注意: MYSQL在选择方言时,请选择最短的方言.
         -->
        <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
        <!--是否打印sql语句-->
        <property name="hibernate.show_sql">true</property>
        <!--是否格式化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>
        <!--
            指定hibernate操作数据库时的隔离级别
            ## specify a JDBC isolation level
            #hibernate.connection.isolation 1|2|4|8
            0001   1    读未提交
            0010   2    读已提交
            0100   4    可重复读
            1000   8    串行化
        -->
        <property name="hibernate.connection.isolation">4</property>
        <!--指定session与当前线程绑定-->
        <property name="hibernate.current_session_context_class">thread</property>

        <!-- 引入orm元数据
            路径书写: 填写src下的路径
         -->
        <mapping resource="com/hibernate/domain/Grades.hbm.xml"/>
    </session-factory>
</hibernate-configuration>

6、编写测试代码,并查看数据库

/**
 * 通过Hibernate往数据库添加数据
 */
public class TestHibernate {

    public static void main(String[] args) {
        //准备数据
        Grades grades = new Grades();
        grades.setS_id(302003);
        grades.setS_name("小周3");
        grades.setS_class("三零二班");
        grades.setS_source("99");

        //1.加载hibernate.cfg.xml配置文件
        Configuration configuration = new Configuration().configure();
        //2.创建SessionFactory
        SessionFactory sessionFactory = configuration.buildSessionFactory();
        //3.创建session对象
        Session session = sessionFactory.openSession();
        //4.开启事务
        Transaction tx = session.beginTransaction();
        //5.保存分数
        session.save(grades);
        //6.提交事务
        tx.commit();
        //7.关闭资源
        session.close();
    }
}

控制台打印的sql语句:
sql日志.png

新添加的数据:
数据库.png

7、封装获取Session工具类HibernateUtil,并测试使用

public class HibernateUtil {

    private static SessionFactory sessionFactory;

    static {
        //1.加载hibernate.cfg.xml配置文件
        Configuration configuration = new Configuration().configure();
        //2.创建SessionFactory,一个web项目只能有一个sessionFactory对象
        sessionFactory = configuration.buildSessionFactory();
    }

    /**
     * 直接创建一个新的Session实例,使用后需要手动调用close方法关闭
     * @return
     */
    public static Session openSession() {
        Session session = sessionFactory.openSession();
        return session;
    }

    /**
     * 创建的session实例会绑定到当前县城,提交或回滚是会自动关闭ß
     * @return
     */
    public static Session getCurrentSession() {
        Session session = sessionFactory.getCurrentSession();
        return session;
    }
}
/**
 * 通过Hibernate往数据库添加数据
 */
public class TestHibernate {

    private static GradesService gradesService = new GradesServiceImpl();

    public static void main(String[] args) {
        //准备数据
        Grades grades = new Grades();
        grades.setS_id(302004);
        grades.setS_name("小周4");
        grades.setS_class("三零二班");
        grades.setS_source("99");

        gradesService.addGrade(grades);
    }
}
public class GradesServiceImpl implements GradesService {

    private GradesDao gradesDao = new GradesDaoImpl();

    @Override
    public void addGrade(Grades grades) {
        Session session = HibernateUtil.getCurrentSession();
        Transaction transaction = session.beginTransaction();
        try {
            gradesDao.addGrade(grades);
        } catch (Exception e) {
            transaction.rollback();
            e.printStackTrace();
        }
        transaction.commit();
    }
}
public class GradesDaoImpl implements GradesDao {

    @Override
    public void addGrade(Grades grades) {
        Session currentSession = HibernateUtil.getCurrentSession();
        currentSession.save(grades);
    }
}
数据库.png

至此Hibernate的简单使用已告一段落,未完待续~
Hibernate知识体系总结(二):https://www.jianshu.com/p/c8149129fa1b

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容