zoukankan      html  css  js  c++  java
  • Hibernate框架学习之基础使用

    Hibernate框架概述

    1.简介

    • Hibernate是一个开放源代码的对象关系映射框架
    • 它对JDBC进行了非常轻量级的对象封装
    • 它将POJO与数据库表建立映射关系,是一个全自动的orm框架
    • hibernate可以自动生成SQL语句,自动执行,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库
    • Hibernate可以应用在任何使用JDBC的场合,既可以在Java的客户端程序使用,也可以在Servlet/JSP的Web应用中使用
    • 持久层的ORM框架

    ORM:Object Relational Mapping(对象关系映射)。
    指的是将一个Java中的对象与关系型数据库中的表建立一种映射关系,从而操作对象就可以操作数据库中的表。

    2.优点

    • 对JDBC访问数据库的代码进行了轻量级封装,简化了数据访问层繁琐重复性的代码,减少了内存消耗,加快了运行效率
    • 是一个基本JDBC的主流持久化框架,很大程度上简化了DAO层的编码工作
    • 性能非常好, 映射灵活性比较好,支持多关系数据库,一对一,一对多,多对多的各种复杂关系
    • 可扩展性强,源代码及API开放,当本身功能不够用时,可以自行编码进行扩展

    Hibernate的基本使用

    1.导入jar包

    再导入jar前我们先来了解一下hibernate的目录结构

    • documentation Hibernate开发的文档
    • lib Hibernate开发的jar包
      -required
      Hibernate开发的必须的依赖包
      -optional
      Hibernate开发的可选的jar包
    • project
      Hibernate提供的参考项目

    除了上述hibernate中必须导入的jar包外我们还需要导入数据库的驱动包,连接池jar包。

    2.配置文件

    1. 要使用hibernate我们首先需要配置一下核心配置文件hibernate.cfg.xml
    <!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.cj.jdbc.Driver</property>
    		<property name="hibernate.connection.url">jdbc:mysql:///hibernate?useSSL=false&amp;serverTimezone=UTC</property>
    		<property name="hibernate.connection.username">root</property>
    		<property name="hibernate.connection.password">123456</property>
    		<!-- 配置Hibernate的方言 -->
    		<property name="hibernate.dialect">org.hibernate.dialect.MySQL8Dialect</property>
    		<!-- 打印SQL -->
    		<property name="hibernate.show_sql">true</property>
    		<!-- 格式化SQL -->
    		<property name="hibernate.format_sql">true</property>
    		<!-- 自动创建表 -->
    		<property name="hibernate.hbm2ddl.auto">update</property>
            <!--加载映射文件-->
    		<mapping resource="com/thinmoon/domain/Customer.hbm.xml"/>
    	</session-factory>
    </hibernate-configuration>
    

    hibernate.hbm2ddl.auto各种操作的一个解析

    属性 含义
    none 不使用hibernate的自动建表
    create 如果数据库中已经有表,删除原有表,重新创建,如果没有表,新建表
    create-drop 如果数据库中已经有表,删除原有表,执行操作,删除这个表。如果没有表,新建一个,使用完了删除该表。最后数据库中一个表没有,为了做测试用。把sessionFactory也close掉时才有效果
    update 如果数据库中有表,使用原有表,如果没有表,创建新表
    更新表结构,如果column没有时会创建新的一列
    validate 如果没有表,不会创建表。只会使用数据库中原有的表
    校验映射和表结构是否一致,不一致就会报错
    1. 创建映射关系配置文件,我们知道hibernate可以让我们使用面向对象的方法操纵数据库,所以我们必须得建立类与表之间的映射关系才能让hibernate正确的去操纵,其中配置文件命名格式我们一般是类名.hbm.xml

      <?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>
          <!--建立类与表的映射关系-->
          <class name="com.thinmoon.domain.Customer" table="customer">
              <!--建立主键映射关系-->
              <id name="cust_id" column="cust_id">
                  <!--设置主键增长方式-->
                  <generator class="native"/>
              </id>
              <!--建立属性之间的映射关系-->
              <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>
      

      Customer类:

      @Setter @Getter
      public class Customer {
      
          long cust_id;
          String cust_name;
          String cust_source;
          String cust_industry;
          String cust_level;
          String cust_phone;
          String cust_mobile;
      }
      

    3.操纵数据库

    先来看一个小demo:

    public class HibernateTest {
        @Test
        public void testM(){
            //1.加载配置文件 hibernate.cfg.xml
            Configuration configure = new Configuration().configure();
            //2.创建sessionFactory 相当于jdbc的连接池
            SessionFactory sessionFactory = configure.buildSessionFactory();
            //3.获取session连接对象 相当于jdbc中的连接对象
            Session session = sessionFactory.openSession();
    
            Customer customer = new Customer();
            customer.setCust_name("thinmoon");
            customer.setCust_level("2");
    
            session.save(customer);
    
            session.close();
            sessionFactory.close();
        }
    }
    

    接下来我们对上面对象分别做一个解释:

    Configuration

    Configuration是Hibernate的配置对象,作用是对Hibernate 进行配置,以及对它进行启动。在Hibernate 的启动过程中,Configuration 类的实例首先定位映射文档的位置,读取这些配置,然后创建一个SessionFactory对象。虽然Configuration 类在整个Hibernate 项目中只扮演着一个很小的角色,但它是启动hibernate 时所遇到的第一个对象。通过这个对象去加载它里面的配置,把里面的数据内容或得到,才能进行后面的工作。
    作用:

    1. 加载核心配置文件,其中核心配置文件可以是xml形式,也可以是properties形式

      • 核心配置文件是属性文件名称为:hibernate.properties
      configuration cfg = new configuration()
      
      • 核心配置文件是一个xml名称为:hibernate.cfg.xml
      configuration cfg = new configuration();
      cfg.config()
      
    2. 加载映射文件

      属性文件是没有办法加载映射,可以通过config加载映射文件

      configuration.addResource("映射文件的全路径");
      

      xml可以直接在配置文件中配置即可。

    SessionFactory

    SessionFactory接口负责初始化Hibernate,并负责创建Session对象。需要注意的是SessionFactory并不是轻量级的,因为一般情况下,一个项目通常只需要一个SessionFactory就足够。当需要操作多个数据库时,可以为每个数据库指定一个SessionFactory。SessionFactory
    内部维护了Hibernate的连接池和Hibernate的二级缓存,一个项目只需要创建一个就行了,因为里面有连接池,通常连接池创建一个就可以。

    hiberante5.0后内部自带有连接池如果我们想用第三方的连接池需要额外配置,下面是配置c3p0的例子(应为hibernate对c3p0支持比较好)。首先我们需要导入jar包在hibernate的lib目录中的optional中有c3p0的jar包。接着在hibernate.cfg.xml中进行配置。

    <!--配置c3p0-->
    
    		<property name="connection.provider_class">org.hibernate.c3p0.internal.C3P0ConnectionProvider</property>
    		<!--在连接池中可用的数据库连接的最少数目 -->
    		<property name="c3p0.min_size">5</property>
    		<!--在连接池中所有数据库连接的最大数目  -->
    		<property name="c3p0.max_size">20</property>
    		<!--设定数据库连接的过期时间,以秒为单位,
            如果连接池中的某个数据库连接处于空闲状态的时间超过了timeout时间,就会从连接池中清除 -->
    		<property name="c3p0.timeout">120</property>
    		<!--每3000秒检查所有连接池中的空闲连接 以秒为单位-->
    		<property name="c3p0.idle_test_period">3000</property>
    
    

    既然我们上面说了一个项目一般只要一个SessionFactory所以我们就有必要专门为它抽取出一个工具类出来:

    public class HibernateUtil {
        public static final SessionFactory sessionFactory;
        static {
            //1.加载配置文件 hibernate.cfg.xml
            Configuration configure = new Configuration().configure();
            //2.创建sessionFactory 相当于jdbc的连接池
            sessionFactory = configure.buildSessionFactory();
    
        }
        public static Session openSession(){
            //3.获取session连接对象 相当于jdbc中的连接对象
            Session session = sessionFactory.openSession();
            return session;
        }
    }
    
    
    Session

    session代表的是hibernate与数据库的连接对象,与数据库交互的桥梁,通过它来完成与数据库的增删改查的工作

    使用session进行增删改查很简单:

    方法 代码 解释
    保存方法 save(Object obj)
    查询方法 get(T.class,id)
    load(T.class,id)
    get(T.class,id)
    2.查询之后,返回的是真实对象本身
    3.没有查询到指定的id,返回的是一个空值

    load(T.class,id)
    1.查询之后返回的是一个代理对象,使用的是第三方的代理机制,javassist.jar
    2.没有查询到结果直接报一个异常
    修改 void update(Object obj) 直接创建对象修改,如果没有指定其它的字段,会把其它的字段设置为null。
    建议先把要修改的记录查询出来之后再修改相应的对象
    删除 void delete(Object obj) 直接创建对象删除,不支持级联删除
    建议查询之后再删除,支持级联删除
    保存或更新 void saveOrUpdate(Object obj) 没有设置id,是保存的操作
    设置了id是修改的操作,如果设置的id没有,就会报错
    查询所有 Query query = session.createQuery("from Customer");
    List list = query.list()
    使用HQL的方式
    HQL:Hibernate Query Language 面向对象的查询语言

    demo:

    public class HibernateTest {
        @Test
        public void testSave(){
            Session session = HibernateUtil.openSession();
            Transaction transaction = session.beginTransaction();
            Customer customer = new Customer();
            customer.setCust_name("thinmoon111");
            customer.setCust_level("3");
    
            session.save(customer);
            transaction.commit();
            session.close();
    
        }
    
        @Test
        public void testDelete(){
            Session session = HibernateUtil.openSession();
            Transaction transaction = session.beginTransaction();
    
            Customer customer = session.get(Customer.class, 1L);
            System.out.println(customer);
            session.delete(customer);
    
            transaction.commit();
            session.close();
    
        }
    
        @Test
        public void testUpdate(){
            Session session = HibernateUtil.openSession();
            Transaction transaction = session.beginTransaction();
    
            Customer customer = session.get(Customer.class, 2L);
            System.out.println(customer);
            customer.setCust_level("10");
            session.update(customer);
    
            transaction.commit();
            session.close();
    
        }
    
        @Test
        public void testHQL(){
            Session session = HibernateUtil.openSession();
            Transaction transaction = session.beginTransaction();
    
            Query query = session.createQuery("from com.thinmoon.domain.Customer");
            List<Customer> list = query.list();
            for (Customer c: list) {
                System.out.println(c);
            }
    
            transaction.commit();
            session.close();
    
        }
    
    }
    
    

    归纳

    配置文件hibernate.cfg.xml

    <!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.cj.jdbc.Driver</property>
    		<property name="hibernate.connection.url">jdbc:mysql:///hibernate?useSSL=false&amp;serverTimezone=UTC</property>
    		<property name="hibernate.connection.username">root</property>
    		<property name="hibernate.connection.password">15160673718wen</property>
    		<!-- 配置Hibernate的方言 -->
    		<property name="hibernate.dialect">org.hibernate.dialect.MySQL8Dialect</property>
    		<!-- 打印SQL -->
    		<property name="hibernate.show_sql">true</property>
    		<!-- 格式化SQL -->
    		<property name="hibernate.format_sql">true</property>
    		<!-- 自动创建表 -->
    		<property name="hibernate.hbm2ddl.auto">update</property>
    
    		<!--配置c3p0-->
    
    		<property name="connection.provider_class">org.hibernate.c3p0.internal.C3P0ConnectionProvider</property>
    		<!--在连接池中可用的数据库连接的最少数目 -->
    		<property name="c3p0.min_size">5</property>
    		<!--在连接池中所有数据库连接的最大数目  -->
    		<property name="c3p0.max_size">20</property>
    		<!--设定数据库连接的过期时间,以秒为单位,
            如果连接池中的某个数据库连接处于空闲状态的时间超过了timeout时间,就会从连接池中清除 -->
    		<property name="c3p0.timeout">120</property>
    		<!--每3000秒检查所有连接池中的空闲连接 以秒为单位-->
    		<property name="c3p0.idle_test_period">3000</property>
    
    		<!--添加映射文件-->
    		<mapping resource="com/thinmoon/domain/Customer.hbm.xml"/>
    	</session-factory>
    </hibernate-configuration>
    
  • 相关阅读:
    OpenWrt配置绿联的usb转Ethernet网口驱动
    SQL_wm_concat函数实验:实现字段合并
    BingMap频繁Add Pushpin和Delete Pushpin会导致内存泄露
    比較C++和Java 二
    【JAVASE】Java同一时候抛出多个异常
    uva 1463
    Android 撕衣服(刮刮乐游戏)
    轻松掌握一致性哈希算法
    Oracle之sql语句优化
    Eclipse导出Library
  • 原文地址:https://www.cnblogs.com/ThinMoon/p/12482562.html
Copyright © 2011-2022 走看看