SSH框架深度学习----Hibernate

以前学习过SSH框架,看过很多视频,也实际应用做了几个小的项目,但是工作了对框架的学习和搭建过程的并没有更深入的学习,所以趁现在手头工作不忙,再深入学习一下SSH框架。

Hibernate是轻量级JavaEE应用的持久层解决方案,Hibernate不仅管理Java类到数据库表的映射(包括Java数据类型到SQL数据类型的映射),还提供数据查询和获取数据的方法,可以大幅度缩短使用JDBC处理数据持久化的时间。

目前的主流数据库依然是关系数据库,而Java语言则是面向对象的编程语言,当把二者结合在一起使用时相当麻烦,而Hibernate则减少了这个问题的困扰,它完成对象模型和基于sql的关系模型的映射关系,使数据库严格的面向对象,减少关系型的过程代码。

Hibernate充当了面向对象的程序设计语言和关系型数据库之间的桥梁,Hibernate允许程序开发者采用面向对象的方式来操作关系数据库。因为有了Hibernate的支持,使得JavaEE应用的OOA(面向对象分析)、OOD(面向对象设计)和OOP(面向对象编程)三个过程一脉相承,成为一个整体。

一.ORM

ORM的全称是Object/Relation Mapping,对象/关系数据库映射,完成面向对象的编程语言到关系型数据库的映射。当ORM框架完成映射后,既可以利用面向对象程序设计语言的简单易用性,又可以利用关系型数据库的技术优势。因此,我们可把ORM框架当成应用程序和数据库的桥梁。不过随着面向对象数据库的广泛使用,ORM工具可能会自动消亡。

面向对象的程序设计语言优势:面向对象的建模、操作;多态、继承;摒弃难以理解的过程;简单易用,易理解。

关系数据库系统的优势:大量数据查找、排序;集合数据连接操作、映射;数据库访问的并发、事务;数据的约束、隔离。

ORM工具的作用就是:把对持久化对象的保存、删除、修改等操作,转换成对数据库的操作。ORM提供了持久化类和数据表之间的映射关系,其中包括:

(1)将持久化类映射成数据表,当我们使用这个持久化类创建实例、修改属性、删除实例时,系统自动会转换为对这个表进行CRUD操作;

(2)将实例对象映射成数据表中的记录;

(3)将对象属性映射成数据表中的字段。

二.Hibernate的配置文件

Hibernate进行持久化操作离不开SessionFactory对象,这个对象是整个数据库映射关系经过编译后的内存镜像,该对象的openSession方法可打开Session对象。该对象通常由Configuration对象来产生。

1.首先需要的就是hibernate.cfg.xml配置文件,配置如下:
其中配置了数据的连接、执行sql时是否在控制台打印sql、事务的配置、实体类映射的.hbm.xml配置等。

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
          "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
          "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<!-- Generated by MyEclipse Hibernate Tools.                   -->
<hibernate-configuration>

<session-factory>

    <property name="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</property>
    <property name="proxool.pool_alias">Diaochaproxool</property>
    <!-- 处理Clob类型 -->
    <property name="hibernate.connection.SetBigStringTryClob">true</property>
    <!--数据库连接配置-->
    <property name="user" value="用户名" />
    <property name="password" value="密码" />
    <property name="useUnicode" value="true" />
    <property name="characterEncoding" value="GBK" />

    <!--当show_sql属性为true时,表示当程序运行时在控制台输出SQL语句,默认为false-->
    <property name="show_sql">false</property>
    <!--指定是否按照标准格式在控制台上输出SQL语句-->
    <property name="format_sql">true</property>
    <!--指定是否在SQL语句中输出便于调试的注释信息-->
    <property name="use_sql_comments">true</property>

    <!-- 事务管理类型,这里我们使用JDBC Transaction -->
    <property name="hibernate.Transaction.factory_class">org.hibernate.Transaction.JDBCTransactionFactory</property>

    <mapping resource="实体类路径/entity/类名一致.hbm.xml" />

</session-factory>

</hibernate-configuration>

2.配置实体类对象的 .hbm.xml 配置文件

实体类对应的 .hbm.xml文件必须要求类属性的个数、类型与数据库表的字段一一对应、保持一致,配置如下:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
    <class name="对应实体类的完整路径" table="对应数据表名" schema="数据库名">
        <id name="id" type="java.lang.String">
            <column name="id" length="64" />
            <!--手动设置id-->
            <generator class="assigned" />
        </id>
        ....
        </property>

    </class>
</hibernate-mapping>

3.Hibernate使用过程

Configuration  cf = new Configuration().configure();//如果想要改变hibernate.cfg.xml文件的路径或者名字,直接在configure()的括号里填上hibernate.cfg.xml的完整路径即可。
SessionFactory sf = cf.buildSessionFactory();
Session session = sf.openSession();
Transaction ts = session.beginTransaction();//开启事务
session.save(实体类);
ts.commit();//提交事务
session.close();

在实际项目开发中,通常会将这一部分封装成类,保证session单例并提高了代码的易用性,如下:

import org.apache.log4j.Logger;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class HibernateFactory {
    private static final Logger logger =Logger.getLogger(HibernateFactory.class);

    private static final Configuration configuration;
    private static final SessionFactory sessionFactory;

    static {
        configuration = new Configuration().configure("dhcc-framework-context/hibernate.cfg.xml");
        //configuration = new Configuration().configure();//这样使用的话,hibernate.cfg.xml名字不能变,且只能放在第一层目录下(即编译后在WEB-INF/classes目录里)
        sessionFactory = configuration.buildSessionFactory();
    }

    public static SessionFactory getSessionFactory() {
        return sessionFactory;
    }

    private static ThreadLocal<Session> data = new ThreadLocal<Session>();

    /**
     * 返回当前线程所对应的session,如果当前线程没有对应的session,就创建一个。
     * 
     * @return
     */
    public static Session getSession() {
        //当hibernate 数据表映射配置文件(.hbm.xml)有错,但不好找错误在哪里时, 可以打开此代码找错。   
        Session session = data.get();
        if (session == null) {
            logger.info("当前没有session,获取新的session.......");
            session = sessionFactory.openSession();
            data.set(session);
        }else{
            if(!session.isOpen() ){
                logger.info("当前有session["+Thread.currentThread().getName() +"],但已经被关闭,重新获取新的session.......");
                session = sessionFactory.openSession();
                System.out.println("---------- HibernateFactory-sessionFactory.openSession()结束!");
                data.set(session);
            }else{
                logger.info("当前有开着的session["+Thread.currentThread().getName() +"],直接返回session.......");
            }

        }
        return session;
    }

    /**
     * 关闭当前线程关联Session,并取消他们的关联
     */
    public static void closeSession() {
        Session session = data.get();
        if (session != null) {
            session.close();
            data.set(null);
        }
    }
}

Hibernate使用自己独有的HQL语言进行数据库操作,完全以面向对象的方式操作数据库,用法与sql有很多相似之处。它提供了save(),delete(),get()等方法完成数据库的增删改查操作。使用方法如下事例:

String hql = "select o from  user  as  o";
Query q = session.createQuery(hql);
List  list  =  q.list();

对于分页查询,SQL中可使用关键字limit start_position,count进行分页显示;Hibernate提供了分布函数:getFirstResult()—起始位置,setMaxResult()—查询个数,完成分页的通用性。

Hibernate的优点:使用O/R Mapping框架,完全的面向对象;但它也有查询速度慢、没有子查询、不能进行多表否定条件的调优等缺点。

解决Hibernate查询速度慢的方案:使用伪面向对象查询,进行调优。

猜你喜欢

转载自blog.csdn.net/qq_36526703/article/details/53540257
今日推荐