Spring框架学习(4)spring整合hibernate
内容源自: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的更多相关文章
- Spring框架学习03——Spring Bean 的详解
1.Bean 的配置 Spring可以看做一个大型工厂,用于生产和管理Spring容器中的Bean,Spring框架支持XML和Properties两种格式的配置文件,在实际开发中常用XML格式的配置 ...
- Spring 框架学习(1)--Spring、Spring MVC扫盲
纸上得来终觉浅,绝知此事要躬行 文章大纲 什么是spring 传统Java web应用架构 更强的Java Web应用架构--MVC框架 Spring--粘合式框架 spring的内涵 spring核 ...
- Spring框架学习02——Spring IOC 详解
1.Spring IOC的基本概念 IOC(Inverse of Control)反转控制的概念,就是将原本在程序中手动创建对象的控制权,交由Spring框架管理.当某个Java对象(调用者)需要调用 ...
- Spring框架学习一
Spring框架学习,转自http://blog.csdn.net/lishuangzhe7047/article/details/20740209 Spring框架学习(一) 1.什么是Spring ...
- Spring框架学习1
AnonymouL 兴之所至,心之所安;尽其在我,顺其自然 新随笔 管理 Spring框架学习(一) 阅读目录 一. spring概述 核心容器: Spring 上下文: Spring AOP ...
- Spring MVC 学习笔记12 —— SpringMVC+Hibernate开发(1)依赖包搭建
Spring MVC 学习笔记12 -- SpringMVC+Hibernate开发(1)依赖包搭建 用Hibernate帮助建立SpringMVC与数据库之间的联系,通过配置DAO层,Service ...
- Spring框架学习之IOC(一)
Spring框架学习之IOC(一) 先前粗浅地学过Spring框架,但当时忙于考试及后期实习未将其记录,于是趁着最近还有几天的空闲时间,将其稍微整理一下,以备后期查看. Spring相关知识 spri ...
- Spring框架学习笔记(5)——Spring Boot创建与使用
Spring Boot可以更为方便地搭建一个Web系统,之后服务器上部署也较为方便 创建Spring boot项目 1. 使用IDEA创建项目 2. 修改groupid和artifact 3. 一路n ...
- Spring框架学习总结(上)
目录 1.Spring的概述 2.Spring的入门(IOC) 3.Spring的工厂类 4.Spring的配置 5.Spring的属性注入 6.Spring的分模块开发的配置 @ 1.Spring的 ...
- Spring框架学习笔记(1)
Spring 框架学习笔记(1) 一.简介 Rod Johnson(spring之父) Spring是分层的Java SE/EE应用 full-stack(服务端的全栈)轻量级(跟EJB比)开源框架, ...
随机推荐
- 182. Duplicate Emails
Write a SQL query to find all duplicate emails in a table named Person. +----+---------+ | Id | Emai ...
- Java8之Stream/Map
本篇用代码示例结合JDk源码讲了Java8引入的工具接口Stream以及新Map接口提供的常用默认方法. 参考:http://winterbe.com/posts/2014/03/16/java ...
- lr_Controller界面图
lr可用运行图介绍: lr集合点策略:
- nginx实现正向代理和反向代理
注意:nginx正向代理有缺陷,如果同时实现http和https正向代理请使用squid软件 (1)正反向代理 正向代理:实现客户端上网 反向代理:代理访问后端web服务器, 区别:正向代理的对象是客 ...
- DDD精彩
MS STST 这难度太高了 有一个就很难的了 也许我工作的环境一般,能把SOLID简要描述一下的,都还没有遇到 SOLID还只属于OOD层次,OOA层面就更加没碰到了 Scrip 因为领域驱动设计的 ...
- Java学习之路(转)
Java学习之路(书籍推荐) 一.基础类 1.<Thinking in java>(阅读2遍),入门第一位是建立正确的概念 2.<Core Java>这本书更贴近实践,更多 ...
- Sqli-labs介绍、下载、安装
SQLI和sqli-labs介绍 SQLI,sql injection,我们称之为sql注入.何为sql,英文:Structured Query Language,叫做结构化查询语言.常见的结构化数据 ...
- 第1天:Ansible安装部署
Ansible介绍 Ansible是一个简单的自动化引擎,可完成配置管理.应用部署.服务编排以及各种IT需求.它是一款使用Python语言开发实现的开源软件,其依赖Jinjia2.paramiko和P ...
- 04、Unity_声音管理器
1.分享一个Unity中用于管理声音的声音管理器,适合于中小型项目,大项目就算了. 2.借鉴了很多的源码,最后修改完成,吸取百家之长,改为自己所用,哈哈. 3.源码奉上: /* * * 开发时间:20 ...
- android用户界面的教程实例---转自qianqianlianmeng的博客
1.android用户界面之AlarmManager教程实例汇总http://www.apkbus.com/android-48405-1-1.html2.android用户界面之文本编辑教程实例汇总 ...