内容源自: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. AC日记——统计和 洛谷 P2068

    统计和 思路: 水题: 代码: #include <bits/stdc++.h> using namespace std; #define maxn 100005 int n,m,tree ...

  2. WebDriver自动化测试工具(1)---环境搭建

    Webdriver是一个前端自动化测试工具,可以模拟用户点击链接,填写表单,点击按钮等操作,下面介绍其使用 一.下载WebdriverC#类库以及对应浏览器驱动 http://www.selenium ...

  3. React Native学习

    学习 首先,假使你已经安装了Nodejs 6,也有使用npm进行Nodejs的包管理 npm install -g react-native-cli 也可以使用yarn作为包管理工具 npm inst ...

  4. Bootstrap 实现CRUD示例及代码

    https://github.com/wenzhixin/bootstrap-table-examples/blob/master/crud/index.html <!DOCTYPE html& ...

  5. JS内存管理与垃圾回收

    内存分配 var n = 374; // 为数字分配内存 var s = 'sessionstack'; // 为字符串分配内存 var o = { a: 1, b: null }; // 为对象及其 ...

  6. 2. 创建一个简单的Maven项目

    ☞ 创建项目 选定一个目录,如E:\workspace\maven,新建的项目将放在这个目录. 运行CMD,切换到该目录. 执行mvn archetype:generate直到输出"Choo ...

  7. 【解决问题】centOS 7 设置固定IP,无法上外网

    使用Xenserver搭建服务器集群,在安装centOS时候,发现如果将服务器IP设置成为static ip,只能内网互通,无法上外网(ping www.baidu.com 失败) 网上搜索了一下,发 ...

  8. 【BZOJ 3672】 3672: [Noi2014]购票 (CDQ分治+点分治+斜率优化)**

    3672: [Noi2014]购票 Description  今年夏天,NOI在SZ市迎来了她30周岁的生日.来自全国 n 个城市的OIer们都会从各地出发,到SZ市参加这次盛会.        全国 ...

  9. 对有些反编译不成功的apk,请更新最新的apktool.jar、 dex2jar试试

    韩梦飞沙  韩亚飞  313134555@qq.com  yue31313  han_meng_fei_sha 对有些反编译不成功的apk,请更新最新的apktool.jar. dex2jar试试 a ...

  10. VB程序打包方法之如何在发布安装之后不带源码

    很久之前,我发表了一片博客是VB程序如何打包,在那里面我总结了两个方法.有兴趣可以看看我的这篇博客http://blog.csdn.net/lu930124/article/details/88467 ...