一、Hibernate框架快速入门

作者: 明天你好向前奔跑 | 来源:发表于2017-06-27 13:19 被阅读69次

    Hibernate快速入门


    一、Hibernate的介绍

    Hibernate是轻量级JavaEE应用的持久层解决方案,是一个关系数据库ORM框架。

    ORM:Object Relational Mapping,对象关系映射

    优点:

    • Hibernate是基于jdbc的主流持久化框架。
    • Hibernate是一个开源的ORM框架,。
    • Hibernate对JDBC数据库的操作进行了封装,简化了数据库操作的代码,提高了开发效率。
    • 程序员能够利用Hibernate框架更好的使用面向对象的编程思维来操纵数据库。

    二、 Hibernate使用入门

    1. 创建java项目
    2. 导入Hibernate所需jar包与数据库驱动连接
    3. 创建数据库表
    4. 创建javaBean实体类
    5. 编写数据库表与javaBean实体类的映射(配置)文件
    6. 编写Hibernate的核心配置文件
    7. 使用Hibernate

    1. 导入jar包

    • 数据库驱动
    • Hibernate所需jar包
    • 日志记录jar包
    需要导入的jar包 jar包解释

    2. 创建数据库表

    CREATE DATABASE hibernate_day01;
    USE hibernate_day01;
    
    CREATE TABLE USER(
        uid INT PRIMARY KEY AUTO_INCREMENT,
        uname VARCHAR(20),
        upassword VARCHAR(20)
    );
    

    3. 创建实体类(略)

    4. 编写数据库表与javaBean实体类的映射(配置文件)

    1. 在javaBean的同级目录下创建文件名为 实体类名.hbm.xml的配置文件.如:User.hbm.xml

    2. 导入配置文件的DTD约束:mapping

    3. class标签定义javaBean与数据库表的映射

    4. id标签定义javaBean与数据库表中的主键的映射关系

    5. property标签定义普通字段的映射关系

       <?xml version="1.0" encoding="UTF-8"?>
       
       <!-- 引入DTD约束 -->
       <!-- 找到buildPath之后的Hibernate的Liberaries,打开hibernate的核心包:hibernate-core-5.0.7.Final.jar -->
       <!-- 打开和新包下的org.hibernate包,找到dtd结尾的映射配置文件mapping.dtd与hibernate的核心配置文件configuration.dtd -->
       <!-- 找到两个文件的dtd约束,copy到对应的xml配置文件中 -->
       
       <!DOCTYPE hibernate-mapping PUBLIC 
           "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
           "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
       
       <hibernate-mapping>
           <!-- 创建javaBean实体类与数据库表的映射 -->
           <class name="com.itdream.domain.User" table="user">
               <!-- javaBean与表的主键的映射,相同时,column可省略 -->
               <id name="uid" column="uid"></id>
       
               <!-- 创建javaBean于表的普通字段的映射,相同时column可省略 -->
               <property name="uname" column="uname"></property>
               <property name="upassword" column="upassword"></property>
           </class>
       </hibernate-mapping>
      

    5. 编写Hibernate的核心配置文件

    1. 在src目录下创建文件名为 ``hibernate.cfg.xml```的配置文件.
    2. 导入配置文件的DTD约束:configuration
    3. <hibernate-mapping></hibernate-mapping>标签中分为三部份:以property标签标记
      1. 必要的配置信息 : 连接数据库的基本参数

      2. Hibernate的属性

        2.1 : Hibernate的方言 : 根据配置生成对应的SQL语句,实现了跨数据域,切换数据库只需更改这里的配置即可

      3. Hibernate加载映射文件,<maping resource="相对路径" />

    Hibernate核心配置文件的一些属性
    
        <?xml version="1.0" encoding="UTF-8"?>
        <!-- 引入DTD约束 -->
        <!DOCTYPE hibernate-configuration PUBLIC
            "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
            "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
        
        <!-- Hibernate核心配置 -->
        <hibernate-configuration>
            <session-factory>
                <!-- 1.必要的配置信息:连接数据库的基本参数 -->
                <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
                <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/hibernate_day01</property>
                <property name="hibernate.connection.username">root</property>
                <property name="hibernate.connection.password">root</property>
    
                <!-- 2. 与本地线程绑定 -->
                <property name="hibernate.current_session_context_class">thread</property>
                
                <!-- 3. Hibernate的属性 -->
                <!-- Hibernate的方言:根据配置的方言生成对应的SQL语句.实现了跨数据库 .切换数据库时只需要更改此处的配置即可-->
                <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
                
                <!-- Hibernate显示SQL语句 -->
                <property name="hibernate.show_sql">true</property>
                <!-- Hibernate格式化SQL语句 -->
                <property name="hibernate.format_sql">true</property>
                
                <!-- Hibernate的hbm2ddl,定义hibernate对数据库表格的创建方式,开发一般用none -->
                <!-- 取值:none,create,create-drop,update,validate -->
                <property name="hibernate.hbm2ddl.auto">none</property>
                
                <!-- 4. Hibernate加载映射 -->
                <mapping resource="com/itdream/domain/User.hbm.xml"/>       
            </session-factory>
        </hibernate-configuration>
    
    

    6. 使用Hibernate完成用户User的注册

    1. 创建Hibernate的配置对象Configuration
    2. 通过配置对象,获取SessionFactory工厂对象
    3. 通过工厂对象获取Session对象
    4. 开启事务
    5. 实现自己的业务逻辑
    6. 提交事务
    7. 关闭资源

    代码实现:

    
        @Test
            //Hibernate入门案例,存储用户到MySQL数据库
            public void test01() {
                //1. 创建Hibernate配置对象
                Configuration configuration = new Configuration();
                //默认加载放在src下以hibernate.cfg.xml命名的Hibernate核心配置文件
                //1.1 加载配置文件
                configuration.configure();
                //2. 通过配置对象创建SessionFactory对象
                SessionFactory sessionFactory = configuration.buildSessionFactory();
                //3. 通过工厂对象获取Session对象
                Session session = sessionFactory.openSession();
                //4. 开启事务
                Transaction transaction = session.beginTransaction();
                //5. 实现自己的业务逻辑
                
                User user = new User();
                user.setUname("唐嫣");
                user.setUpassword("123");
                //实现了insert into user values(null,'唐嫣','123')的操作
                session.save(user);
                
                //6. 提交事务
                transaction.commit();
                //7. 释放资源
                session.close();
                sessionFactory.close();
            }
    

    三、Hibernate配置文件如何导入DTD约束

    1. 导入Hibernate的jar包后build path会产生对应的liberary
    2. 在liberary中找到Hibernate的核心jarhibernate-core-5.0.7.Final.jar
    3. 找到核心jar中的org.hibernate包,点击打开这个包
    4. 分别找到hibernate-mapping-3.0.dtdhibernate-configuration-3.0.dtd的dtd约束
    5. copy两个dtd文件中的约束
    
        hibernate-mapping-3.0.dtd:
    
        <!DOCTYPE hibernate-mapping PUBLIC  
            "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
            "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
    
    
        hibernate-configuration-3.0.dtd:
    
        <!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
    

    6.点开eclipse的window的prference的属性,设置约束的编写提示。
    7.找到xml catalog的窗口,点击add

    导入DTD编写提示一

    8.将约束中双引内的http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd 或(mapping) 填入key的输入框,key type选URI,Location选择FileSystem找到对应的DTD文件导入即可.

    导入DTD编写提示二

    四、 Hibernate的相关API

    1. Configuration对象

    1. 用于配置并且启动Hibernate框架。

    2. Hibernate框架通过该对象来获得对象-关系映射文件中的元数据,以及动态配置Hibernate的属性。

    3. 可以创建SessionFactory对象。

      //获取Configuration对象
      Configuration conf = new Configuration();

      //加载配置文件: 以默认方式加载,配置文件必须放在src目录下,并以hibernate.cfg.xml命名
      conf.configure();//推荐:

      conf.configure(String path);//不推荐

    4. 如果hibernate.cfg.xml中没有使用mapping标签加载映射文件,可以使用该配置对象加载。

      configuration.addResource(String path);
      不推荐该方式,推荐在核心配置文件中直接配置映射文件的加载路径。

    2. SessionFactory : Session工厂对象

    SessionFactory接口负责Hibernate的初始化,以及创建Session对象。它在Hibernate中起到一个缓冲区的作用,Hibernate可以将自动生成的SQL语句、映射语句以及某些可以可重复利用的数据放在这个缓冲区中。同时它还保存了对数据库配置的所有映射关系,维护了二级缓存。

    SessionFactory的实例通过Configuration获取:

    SessionFactory factory = configuration.buildSessionFactory();
    

    Session具有以下特点:

    1. 它是线程安全的,他的同一个实例可以被多个线程共享。
    2. 它是重量级的,因此不能随意的销毁和创建。
    

    由于这个特点,因此一个项目中只需要一个SessionFactory对象,因此对其抽取一个工具类,使其只创建一次,并且能够提供Session对象。

        
        /**
         * 1. 完成SessionFactory的初始化
         * 2. 提供Session对象的获取
         */
        public class HibernateUtils {
            
            //声明SessionFactory对象,将其实例化放在static静态代码块中,保证其在一开始就完成初始化
            private static SessionFactory sf = null;
            
            static {
                //1. 创建Hibernate配置对象
                Configuration configuration = new Configuration();
                //2. 加载配置文件:hibernate.cfg.xml,默认加载src目录下的hibernate.cfg.xml
                configuration.configure();
                
                //3. 实例化SessionFactory对象
                sf = configuration.buildSessionFactory();
                
                //4. 关闭虚拟机时,释放SessionFactory
                Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
                    
                    @Override
                    public void run() {
                        System.out.println("虚拟机关闭,释放SessionFactory资源");
                        sf.close();
                    }
                }));
            }
            
            
            //提供获取Session对象的方法
            public static Session openSession() {
                return sf.openSession();
            }
            
            
            //获得当前线程中的绑定的Session
            //注意:必须配置
            //return 
            public static Session getCurrentSession() {
                return sf.getCurrentSession();
            }
        }
    
    

    3. Session对象

    Session是应用程序与数据库之间交互操作的一个单线程对象,它的主要功能是为持久化对象提供增,删,改,查的操作。

    通过SessionFactory对象获得Session对象,获取Session实例有两种方式:

    1. 采用openSession方式:
    
    Session session = sessionFactory.openSession();
    
    
    2. 采用getCurrentSession方式:
    
    Session session = sessionFactory.getCurrentSession();
    

    他们的区别:

    1. openSession获取的Session对象,SessionFactory会直接创建一个Session实例,在使用完成后需要调用close方法手动关闭。
    2. getCurrentSession方法获取的Session对象实例会被绑定到当前线程中,它在事务提交或回滚后会自动删除。
    

    Session是线程不安全的,多个并发线程同时操作一个Session对象会导致Session数据存取的混乱,(方法内部定义与使用Session对象时,不会出现线程问题),因此应该避免成员位置定义Session,而在局部位置定义Session对象实例,从而避免线程问题。

    Session对象的几个API方法:

    • save(obj) : 增
    • get/load(obj,id) : 取
    • delete(obj) : 删,两种方式,直接删,先获取再删除.推荐先获取在删除。
    • update(obj) : 改,两种方式,直接修改,先获取再修改.推荐先获取再修改.防止数据丢失
    • createQuery("hql") : 获得Query对象
    • createCriteria(Class) : 获得Criteria对象

    测试:

    
        public class HibernateTest2 {
        
            @Test
            //使用Hibernate向数据库中保存数据
            public void save() {
                //1.创建Hibernate配置对象
                //2.创建SessionFactory对象
                //3.获取Session对象
                Session session = HibernateUtils.openSession();
                //4.开启事务
                Transaction transaction = session.beginTransaction();
                //5.实现业务逻辑
                User user = new User();
                user.setUname("林志玲");
                user.setUpassword("123");
                session.save(user);
                
                //6.提交事务
                transaction.commit();
                //7.关闭资源
                session.close();
            }
            
            
            @Test
            //根据主键获取user对象
            public void get() {
                //1. 获取Hibernate配置对象
                //2. 通过配置对象获取SessionFactory工厂对象
                //3. 获取Session对象
                Session session = HibernateUtils.openSession();
                //4. 开启事务
                Transaction transaction = session.beginTransaction();
                //5. 实现业务逻辑
                //参数1:javaBean的实体类 ; 参数2: 序列化,根据表的主键查找对应的javaBean对象
                User user = session.get(User.class, 1);
                System.out.println(user);
                //6. 提交事务
                transaction.commit();
                //7. 释放资源
                session.close();
            }
            
            
            @Test
            //根据主键获取user对象
            public void load() {
                //1. 创建配置对象
                //2. 通过配置对象获取SessionFactory工厂对象
                //3. 获取Session对象
                Session session = HibernateUtils.openSession();
                //4. 开启事务
                Transaction transaction = session.beginTransaction();
                //5. 实现业务逻辑
                //与get用法一致
                User user = session.load(User.class, 2);
                System.out.println(user);
                //6. 提交事务
                transaction.commit();
                //7. 关闭资源
                session.close();
            }
            
            
            //根据主键更改user对象的值
            @Test
            public void update() {
                //1.获取Hibernate配置对象
                //2.通过配置对象获取SessionFactory工厂对象
                //3.获取Session对象
                Session session = HibernateUtils.openSession();
                //4.开启事务
                Transaction transaction = session.beginTransaction();
                //5.实现业务逻辑
                //首先通过主键获取到对象,然后在对对象进行修改,这样在更改对象的值的时候就不会发生丢失
                User user = session.get(User.class, 1);
                user.setUpassword("999");
                session.update(user);
                //6.提交事务
                transaction.commit();
                //7.释放资源
                session.close();
            }
            
            @Test
            //根据主键删除对应user对象
            public void delete() {
                //1. 获取Hibernate配置对象
                //2. 通过配置对象获取SessionFactory工厂对象
                //3. 获取Session对象
                Session session = HibernateUtils.openSession();
                //4. 开启事务
                Transaction transaction = session.beginTransaction();
                //5. 实现业务逻辑
                //首先获取到这个要删除的对象然后删除
                User user = session.get(User.class, 2);
                session.delete(user);
                //6. 提交事务
                transaction.commit();
                //7. 关闭资源
                session.close();
            }
        }
    
    

    get与load的区别:

    get方法 : 立即加载策略:执行get,立即发送SQL语句
    
    
    load方法 : 延迟加载(懒加载):执行load,不会发送sql语句;只要在真正使用数据的时候,才会发送sql语句。
    

    4. Transction

    负责事务管理

    • 常用API :

      • beginTransction() : 开启事务
      • commit() : 提交事务
      • roolback() : 回滚事务
    • 特点

      • Hibernate框架默认情况下事务不自动提交,需要手动提交事务
      • 如果没有开启事务,每一个Session操作,都相当于一个独立的事务
      • 每段事务隐藏着异常,需要手动添加try/catch

    五、Hibernate整合C3P0实现连接池

    hibernate中可以使用默认的连接池,无论功能与性能都不如C3PO。

    步骤:

    1. 找到Hibernate中的c3p0的jar包添加到项目中
    2. 修改hibernate.cfg.xml的配置文件,添加属性,Hibernate会自动发现所配置的信息,选择c3p0作为连接池。
    
         <!-- C3P0的供应商 -->
         <property name="hibernate.connection.provider_class">org.hibernate.c3p0.internal.C3P0ConnectionProvider</property>
         <!-- 最小连接 -->
         <property name="hibernate.c3p0.min_size">5</property>
         <!-- 最大连接数 -->
         <property name="hibernate.c3p0.max_size">20</property>
         <!-- 连接超时时长 -->
         <property name="hibernate.c3p0.timeout">120</property>
         <!-- 每120秒检查空闲连接 -->
         <property name="hibernate.c3p0.idle_test_period">120</property>
         <!-- 最大statments数量 -->
         <property name="hibernate.c3p0.max_statements">120</property>  
         <!-- 连接用完后,每次增加的连接数 -->
         <property name="hibernate.c3p0.acquire_increment">2</property> 
         <!-- 每次都验证连接是否可用 -->
         <property name="hibernate.c3p0.validate">false</property>
    

    3.查看连接池是否起作用

    方法1:

    修改log4j的log4j.properties,修改log4j.rootLogger=Info,这样降低记录与显示日志的级别.
    运行程序时如果能看到控制台出现[org.hibernate.connection.C3P0ConnectionProvider]说明
    Hibernate已经选择了C3P0作为连接池
    
    方法1

    方法2:

    在mysql中使用命令show processlist查看连接数,如连接池中配置最小5个连接时将显示:
    
    方法2

    六、 日志集成

    • JCL规范。Java Commen logger
    • SLF4J规范。Simple Logger fade for Java。
    • log4j:实现。

    规范的出现是因为在一个程序中多个框架用到了不同的日志系统,日志杂乱。规范提供统一解决方案。
    规范和实现的整合,需要中间整合桥梁。

    Log4j与slf4j集成步骤:

    • 导入jar包

      • slf4j-api-x.x.x.jar : 规范接口jar
      • slf4j-log4j12-x.x.x.jar : log4j与Slf4j整合的jar
      • log4j-x.x.x.jar : log4j实现日志规范的jar
    • 在src目录下编写log4j.properties配置文件

        ##设置日志记录到控制台的方式
        log4j.appender.stdout=org.apache.log4j.ConsoleAppender
        log4j.appender.stdout.Target=System.err
        log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
        log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
        ##设置日志记录到文件的方式
        log4j.appender.file=org.apache.log4j.FileAppender
        log4j.appender.file.File=c\:mylog.log
        log4j.appender.file.layout=org.apache.log4j.PatternLayout
        log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
        ##日志输出的级别,以及配置记录方案
        log4j.rootLogger=info, stdout, file 
      
    • 代码中调用Log4j

      • 初始化(引入的包为slf4j的,使用规范接口编程)

          Logger logger = LoggerFactory.getLogger(Clazz);
        
      • 调用

          logger.trace();
          logger.debug();
          logger.info();
          logger.warn();
          logger.error();
        

    日志级别:

    trance
    debug
    info
    warn
    error
    fatal
    

    Log4j日志配置规则介绍【参考log4j介绍】:

    日志记录器:rootLogger
    日志输出源:appender
    日志布局器:layout
    

    真实使用导入jar包,配好log4j.properties就可以使用c3p0连接池了.

    相关文章

      网友评论

        本文标题:一、Hibernate框架快速入门

        本文链接:https://www.haomeiwen.com/subject/cmqecxtx.html