内容源自:spring整合hibernate    spring整合注解形式的hibernate

这里和上一部分学习一样用了模板模式, 将hibernate开发流程封装在ORM层提供的模板类HibernateTemplate中,通过在DAO中对模板类的使用,实现对传统hibernate开发流程的代替。

一、先来看看Hibernate的传统开发流程:

1) 配置SessionFactory对象

hibernate.cfg.xml <session-factory>

a 数据源 driver_class url username password

b 映射文件 mapping

c 可选参数 show_sql format_sql dialect ...

2) 创建SessionFactory实例

工厂类 - 解析xml - SessionFactory

3) 获取会话 Session sessionFactory.getSession()

  • 如果是 insert delete update

4) 开启事务 Transaction

session.beginTransaction()

5) 执行操作save() delete() update()

6) 提交/回滚事务 commit() / rollback()

  • 如果是 select

4) 定义执行hql语句

5) 编译hql Query session.createQuery()

6) 执行hql list() unqueObject()

7) 关闭会话 session.close()

spring中hibernate的使用和传统hibernate使用基本类似,同样要在配置文件中配置SessionFactory、数据源等,只不过,spring 要在容器中配置HibernateTemplate,通过将这个bean对象注入到dao层,来完成数据库的操作。

二、整合过程:

1) 添加spring框架支持(core层)

2) 添加spring整合hibernate需要的jar(hibernate目录)

3) 添加hibernate支持(导入3.5/3.6版本jar包)spring4.0中,如果以注解的方式整合hibernate,仅支持hibernate3.6及以上版本

4) 反向生成表对应的javaBean和映射文件

5)编写applicationContext.xml文件添加支持

三、具体实现:

测试项目目录如下:

applicationContext.xml:

<beans xmlns="http://www.springframework.org/schema/beans"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://www.springframework.org/schema/beans
     http://www.springframework.org/schema/beans/spring-beans-3.2.xsd">
         <!--
            StuDaoImpl hibernateTemplate配置成ioc容器
          -->
    <bean id="dao" class="com.etoak.dao.CityDaoImpl">
        <property name="ht" ref="ht"></property>
    </bean>

    <!--
        此时的HibernateTemplate暂时不具备数据库的连接能力
        需要为其提供一个SessionFactory对象
            1 数据源~描述当前需要连接的数据库
            2 映射文件~描述当前需要对哪个表进行操作
            setSessionFactory()
     -->
    <bean id="ht" class="org.springframework.orm.hibernate3.HibernateTemplate">
        <property name="sessionFactory" ref="sf"></property>
    </bean>
    <!--
        配置SessionFactory[接口]对象
            1 实现类
                spring框架内部并没有提供SessionFactory实现类
            2工厂bean
                spring为SessionFactory提供了一个工厂类进行实例化
                    LocalSessionFactoryBean impliments FactoryBean
        如何使用这个工厂配置SessionFactory对象?
            和hibernate配置的方式类似
            1 数据源
                setDataSource(DataSource ds)
            2映射文件
                setMappingResources(String[] mapping)
            3 可选参数
                setHibernateProperties(Properties props)
            list元素:表示调用当前setter方法需要注入的参数类型
                    每在工程中添加一个映射文件,就需要在list元素下添加
                        一个value子元素指向该映射文件
     -->
    <bean id="sf" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
        <property name="dataSource" ref="ds"></property>
        <property name="mappingResources" >
            <list>
                <value>com/etoak/po/City.hbm.xml</value>
            </list>
        </property>
        <property name="hibernateProperties">
            <props>
                <prop key="dialect">org.hibernate.dialect.MySQLDialect</prop>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.format_sql">true</prop>
            </props>
        </property>
    </bean>
    <!--
        配置DataSource数据源

     -->
      <bean id="ds" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
        <property name="url" value="jdbc:mysql://localhost:3306/yitu"></property>
        <property name="username" value="root"></property>
        <property name="password" value="root"></property>
      </bean>

</beans>

CityDaoImpl.java(dao)

package com.etoak.dao;

import java.io.Serializable;
import java.sql.SQLException;
import java.util.List;

import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.HibernateTemplate;

import com.etoak.po.City;

/**
 * 使用hibernate方式对city进行crud操作
 * spring提供的整合方案  HibernateTemplate
 * @author D_xiao
 *
 */
public class CityDaoImpl {
    private HibernateTemplate ht;

    public void setHt(HibernateTemplate ht) {
        this.ht = ht;
    }

    public boolean addCity(City city){
        Serializable se = ht.save(city);
        //se 添加成功后该数据的主键值
        Integer id = (Integer)se;
        return id>0;
    }

    /**
     * 根据主键查询单条数据
     * get  立即加载
     *          一级缓存 - 二级缓存 - 数据库  - null
     * load 延迟加载[数据库连接延迟]
     *      查询阶段
     *          一级缓存 ->终止查询,返回代理对象
     *      使用阶段
     *          二级缓存 ->数据库 -> Exception
     *      代理模式
     *      判断能否使用load方法,
     * 这里不能用load 只能用get
     */
    public City selectCityById(Integer id){
        return ht.get(City.class, id);
    }
    //这里无法控制成功失败,只有在添加事务后才能控制
    public boolean delCityById(Integer id){
        ht.delete(ht.load(City.class, id));//这里可以用load,因为在查询(对象)和使用(删除)中有会话
        return true;
    }

    public boolean updateCity(City city){
        ht.update(city);
        return true;
    }
    //查询批量数据 List<City>
    public List selectAllCity(){
        String hql = "from City";
        List list = ht.find(hql);
        return list;
    }

    //非主键查询单条数据
    public City selectCityByName(String name){
        String hql = "from City where name=?";
        Object[] args = {name};
        List list = ht.find(hql,args);
        if(list.size()!=0)
            return (City)list.get(0);
        else
            return null;

    }

    //查询数据量
    //hibernate3.2之后查询数据量返回类型都为long类型
    public long selectCityCount(){
        String hql = "select count(*) from City";
        List list = ht.find(hql);
        return (long)list.get(0);
    }

    /**
     * 分页查询
     * hibernate中分页查询:
     *      setFirstResult()  setMaxResult()
     * HibernateTemplate 中提供的方法(save update delete get load find)默认封装了hibernate整套流程
     * 但该模板类中爷提供了一部分方法仅封装了hibernate部分功能
     *      execute(HibernateCallback[接口] c1)
     *          T  当前需要查询的数据类型
     * 匿名内部类访问外部属性  需将属性设置为final
     */
    public List<City> selectCityByPage(final int start,final int end){
        return ht.execute(new HibernateCallback<List<City>>(){
            //该方法仅封装了会话session的创建
            @Override
            public List<City> doInHibernate(Session session)
                    throws HibernateException, SQLException {
                Query query = session.createQuery("from City");
                query.setFirstResult(start);
                query.setMaxResults(end);
                return query.list();
            }

        });
    }
}

利用hibernate反向自动生成的配置文件也贴一下吧:

<?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">
<!--
    Mapping file autogenerated by MyEclipse Persistence Tools
-->
<hibernate-mapping>
    <class name="com.etoak.po.City" table="city" catalog="yitu">
        <id name="id" type="java.lang.Integer">
            <column name="id" />
            <generator class="native" />
        </id>
        <property name="pid" type="java.lang.Integer">
            <column name="pid" />
        </property>
        <property name="name" type="java.lang.String">
            <column name="name" length="10" />
        </property>
    </class>
</hibernate-mapping>

下面我们来总结下如何整合注解形式的hibernate。 
我们知道在普通hibernate中,表与实体的映射关系是写在映射关系文件当中的,一个实体类对应一个映射关系配置文件。而在注解形式中是没有这个映射关系文件的,关系直接在实体类中通过注解的方式展现,所以写法上略有些不同。 
下面我们通过一个例子来看看他们的区别。还是使用上面的例子,先去掉这个hibernate反向生成的City.hbm.xml文件。

Dao层里面是不需要修改的,实现方法都一样。 
改一下City.java 和配置文件applicationContext.xml即可

applicationContext.xml: 
两种方式的区别就是sessionFactory的配置上不同。在配置SessionFactory接口对象时,spring框架内部并没有提供SessionFactory实现类,所以我们采用工厂bean的方式来配置。spring提供工厂实现类对SessionFactory进行实例化。整合普通方式采用LocalSessionFactoryBean,整合注解方式采用AnnotationSessionFactoryBean。 
所以上面的配置文件修改如下:

<beans xmlns="http://www.springframework.org/schema/beans"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://www.springframework.org/schema/beans
     http://www.springframework.org/schema/beans/spring-beans-3.2.xsd">
         <!--
            StuDaoImpl hibernateTemplate配置成ioc容器
          -->
    <bean id="dao" class="com.etoak.dao.CityDaoImpl">
        <property name="ht" ref="ht"></property>
    </bean>

    <bean id="ht" class="org.springframework.orm.hibernate3.HibernateTemplate">
        <property name="sessionFactory" ref="sf"></property>
    </bean>

    <!--
        hibernate注解形式(不存在映射文件):
            使用AnnotationSessionFactoryBean工厂bean进行配置
                1 配置数据源 setDataSource
                2 配置映射实体bean  两种方法:
                    a setAnnotatedClasses(Claesses[] class) 指向映射实体bean列表
                      每在工程中添加一个实体bean对象,需要在list中添加一个value指向
                    b setPackagesToScan(String package)
                     扫描实体bean所在的包结构,在包下查找所有的映射
                3 配置可选参数
     -->

    <bean name="sf" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
        <property name="dataSource" ref="ds"></property>
        <!--
        第一种方法映射实体bean
        <property name="annotatedClasses">
            <list>
                <value>com.etoak.po.City</value>
            </list>
        </property> -->
        <!-- 第二种方法映射实体bean -->
        <property name="packagesToScan" value="com.etoak.po"></property><!-- 如果有多个包有映射实体,都在value中写,用逗号隔开 -->
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.show_sql">true</prop>
            </props>
        </property>
    </bean>

      <bean id="ds" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
        <property name="url" value="jdbc:mysql://localhost:3306/yitu"></property>
        <property name="username" value="root"></property>
        <property name="password" value="root"></property>
      </bean>

</beans>

City.java实体类添加注解:

package com.etoak.po;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name="city",catalog="yitu")
public class City implements java.io.Serializable {

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)  //自增长策略
    private Integer id;
    @Column(name="pid")
    private Integer pid;
    @Column(name="name")
    private String name;

    // Constructors

    /** default constructor */
    public City() {
    }

    /** full constructor */
    public City(Integer pid, String name) {
        this.pid = pid;
        this.name = name;
    }
    public Integer getId() {
        return this.id;
    }

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

    public Integer getPid() {
        return this.pid;
    }

    public void setPid(Integer pid) {
        this.pid = pid;
    }

    public String getName() {
        return this.name;
    }

    public void setName(String name) {
        this.name = name;
    }

}

Spring框架学习(4)spring整合hibernate的更多相关文章

  1. Spring框架学习03——Spring Bean 的详解

    1.Bean 的配置 Spring可以看做一个大型工厂,用于生产和管理Spring容器中的Bean,Spring框架支持XML和Properties两种格式的配置文件,在实际开发中常用XML格式的配置 ...

  2. Spring 框架学习(1)--Spring、Spring MVC扫盲

    纸上得来终觉浅,绝知此事要躬行 文章大纲 什么是spring 传统Java web应用架构 更强的Java Web应用架构--MVC框架 Spring--粘合式框架 spring的内涵 spring核 ...

  3. Spring框架学习02——Spring IOC 详解

    1.Spring IOC的基本概念 IOC(Inverse of Control)反转控制的概念,就是将原本在程序中手动创建对象的控制权,交由Spring框架管理.当某个Java对象(调用者)需要调用 ...

  4. Spring框架学习一

    Spring框架学习,转自http://blog.csdn.net/lishuangzhe7047/article/details/20740209 Spring框架学习(一) 1.什么是Spring ...

  5. Spring框架学习1

    AnonymouL 兴之所至,心之所安;尽其在我,顺其自然 新随笔 管理   Spring框架学习(一)   阅读目录 一. spring概述 核心容器: Spring 上下文: Spring AOP ...

  6. Spring MVC 学习笔记12 —— SpringMVC+Hibernate开发(1)依赖包搭建

    Spring MVC 学习笔记12 -- SpringMVC+Hibernate开发(1)依赖包搭建 用Hibernate帮助建立SpringMVC与数据库之间的联系,通过配置DAO层,Service ...

  7. Spring框架学习之IOC(一)

    Spring框架学习之IOC(一) 先前粗浅地学过Spring框架,但当时忙于考试及后期实习未将其记录,于是趁着最近还有几天的空闲时间,将其稍微整理一下,以备后期查看. Spring相关知识 spri ...

  8. Spring框架学习笔记(5)——Spring Boot创建与使用

    Spring Boot可以更为方便地搭建一个Web系统,之后服务器上部署也较为方便 创建Spring boot项目 1. 使用IDEA创建项目 2. 修改groupid和artifact 3. 一路n ...

  9. Spring框架学习总结(上)

    目录 1.Spring的概述 2.Spring的入门(IOC) 3.Spring的工厂类 4.Spring的配置 5.Spring的属性注入 6.Spring的分模块开发的配置 @ 1.Spring的 ...

  10. Spring框架学习笔记(1)

    Spring 框架学习笔记(1) 一.简介 Rod Johnson(spring之父) Spring是分层的Java SE/EE应用 full-stack(服务端的全栈)轻量级(跟EJB比)开源框架, ...

随机推荐

  1. 【Mac电脑】Jenkins的安装

    1.JDK自己下载安装喽, 2.下载Jenkins 下载路径:https://mirrors.tuna.tsinghua.edu.cn/jenkins/war-stable/2.121.1/jenki ...

  2. Razor 部分页面

    最近在和师父一起打野,后台要求挺多的.后台还是用的EF和MVC5,页面使用的razor. 现在是发现好多的页面有太多重复的东西了. 比如说查询页面的字段,比如说列表页,比如说详情方法都有. 灵机一动, ...

  3. 轻松学习LINUX系列教程推出

    本系列多媒体教程已完成的博文: 1.轻松学习Linux之入门篇 http://chenguang.blog.51cto.com/350944/449214 2.轻松学习Linux之本地安装系统 (分区 ...

  4. JS获取网页高度和宽度

    注:此文属于转载自他人博客 网页可见区域宽: document.body.clientWidth 网页可见区域高: document.body.clientHeight 网页可见区域宽: docume ...

  5. 乱侃OOD

    接口代表的就是共同性,所谓面向接口编程,就是要抽象各种不同概念的共同点 然后把这些概念的不同点用具体的类包装起来,这样一看,面向接口编程就等于面向对象编程 其实说白了是一个概念 IOC就是要把对细节的 ...

  6. Codeforces 1131 F. Asya And Kittens-双向链表(模拟或者STL list)+并查集(或者STL list的splice()函数)-对不起,我太菜了。。。 (Codeforces Round #541 (Div. 2))

    F. Asya And Kittens time limit per test 2 seconds memory limit per test 256 megabytes input standard ...

  7. 关于 Unity WebGL 的探索(一)

    到今天为止,项目已经上线一个多月了,目前稳定运行,各种 bug 也是有的.至少得到了苹果的两次推荐和 TapTap 一次首页推荐,也算是结项后第一时间对我们项目的一个肯定. 出于各种各样的可描述和不可 ...

  8. 北邮校赛 I. Beautiful Array(DP)

    I. Beautiful Array 2017- BUPT Collegiate Programming Contest - sync 时间限制 1000 ms 内存限制 65536 KB 题目描述 ...

  9. 【BZOJ 3994】3994: [SDOI2015]约数个数和(莫比乌斯反演)

    3994: [SDOI2015]约数个数和 Description  设d(x)为x的约数个数,给定N.M,求   Input 输入文件包含多组测试数据. 第一行,一个整数T,表示测试数据的组数. 接 ...

  10. PM过程的一些典型场景和问题

    如何进行团队激励 如何进行目标管理 如何进行绩效考核 如何处理团队沟通(技巧) 详述几种软件过程理论 需求分析和度量 测试过程和工具 开发管理过程