前面两篇文章,分别介绍了SpringmvcSpring的搭建方法,本文再搭建hibernate,并建立SSH最基本的代码结构。

Hibernate和前面两个比就比较复杂了,Hibernate是一个orm的框架,也就是负责面向对象中的对象(Object)和关系型数据库这个关系(Relation)之间的映射(Mapping)。因为关系型数据库的思维方式,和编程的时候对于对象的理解是有偏差的,所以也有一些面向对象的数据库,但是随着这些orm框架的完善,面向对象的数据库就销声匿迹了。

当然,我这篇文章也只是搭建环境,并不多讲annotation,这个会专门写一篇来讲。

闲话少说,第一步是安装好数据库,我用的是mysql,安装在本地,本开启了mysql服务。之后看程序怎么改进。

1. pom.xml

第一步加入hibernate的相关jar包,首先在properties标签下面定义一个版本:

<properties>
<spring.version>4.0.4.RELEASE</spring.version>
<hibernate.version>4.3.5.Final</hibernate.version>
</properties>

然后加入hibernate的核心包,因为要让Spring管理一些对象,还要引入spring-orm的包:

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>${hibernate.version}</version>
</dependency>

除此之外,因为我们要用mysql数据库,并使用c3p0连接池,因此需要引入这两个对应的包:

<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.31</version>
</dependency>

2. web.xml

hibernate有两种使用方法,一种是通过一个SessionFactory来获取Session,还有一种是通过EntityManagerFactory来获取entityManager,我忘了什么原因了,刚开始用的EntityManager后来换回了SessionFactory(hibernate3以前用的是SessionFactory),我后面的描述也都是基于sessionFactory了。而不管是Session还是EntityManager,我们都要去创建和管理这个对象,当然,有了Spring,这个事情就不用我们来操心了,只需要在Spring的配置文件里面配置一下我需要的SessionFactory就行了,不过为了每个文件专注一个事情,我又单独配了一个配置文件,而不是用之前Spring的那一个applicationContext.xml,修改之前的contextConfigLocation,加一个新的文件位置:

<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:/META-INF/applicationContext.xml,
classpath:/META-INF/infrastructure.xml</param-value>
</context-param>

除此之外,hibernate本质上不需要在web.xml里面配置什么,但是有一个属性,我觉得很重要,hibernate对对象的管理是基于session的,如果开启了延迟加载,对于关联对象的查询可能会在渲染jsp的时候才发生,但是这个时候hibernate的当前session默认已经关闭了,就会抛异常,所以我们经常需要hibernate在渲染jsp页面的时候还开着session,这就需要在web.xml中配置一个拦截所有请求的filter:

<filter>
<filter-name>hibernateFilter</filter-name>
<filter-class>org.springframework.orm.hibernate4.support.OpenSessionInViewFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>hibernateFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

3. infrastructure.xml

在src/main/resources这个资源包的META-INF目录下创建infrastructure.xml,在这里配置hibernate的SessionFactory:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
"> <context:property-placeholder location="classpath:/META-INF/properties/hibernate.properties" /> <!-- 使用C3P0数据源,MySQL数据库 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close">
<!-- MySQL5 -->
<property name="driverClass" value="${driverClassName}"></property>
<property name="jdbcUrl" value="${url}"></property>
<property name="user" value="${username}"></property>
<property name="password" value="${password}"></property>
<property name="maxPoolSize" value="40"></property>
<property name="minPoolSize" value="1"></property>
<property name="initialPoolSize" value="1"></property>
<property name="maxIdleTime" value="20"></property>
</bean> <!-- session工厂 -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan" value="org.zhangfc.demo4ssh.domain" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
<prop key="hibernate.format_sql">${hibernate.format_sql}</prop>
</props>
</property>
</bean> <bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean> <tx:annotation-driven transaction-manager="transactionManager" /> </beans>

首先要主意我标称玫红的部分,这是实体类的存放package,hibernate就是用这下面的实体类和数据表对应,需要修改成自己的package,可以看到这个文件还是比较长,不利于改参数,所以继续抽取一个属性文件出来,property-placeholder就是这个文件的位置,之后配置一个数据源,用c3p0连接池连接数据库,之后再根据这个数据源配置SessionFactory,进而配置事务,配置SessionFactory的时候有一个属性hibernate.hbm2dll.auto,是配置根据我们对类的定义自动生成数据表及主外键关系的,刚创建工程的时候设置成create,以后可以改成update或者删了这个属性(刚建工程的时候就设置成update也可以自己创建数据表,但是不会打印建表的sql语句),下面来看这个抽取出来的属性文件,在同目录下创建子目录properties,再创建hibernate.properties:

hibernate.dialect=org.hibernate.dialect.MySQLDialect
driverClassName=com.mysql.jdbc.Driver
validationQuery=SELECT 1
url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8
username=root
password= hibernate.hbm2ddl.auto=create
hibernate.show_sql=true
hibernate.format_sql=true

4. applicationContext.xml

还需要改这个文件吗?需要改一点,这个文件之前只有一行:

<context:component-scan base-package="org.zhangfc.demo4ssh.service"/>

SSH最基本的代码结构呢,需要有实体类,也就是持久化对象,这是一些和数据表一一对应的类,这些类我们放在domain这个子package下,然后访问数据库要使用DAO,即数据访问对象,我们为它们创建一个repo包,再加上之前已经有的serivce和controller,基本架子就全了,所以,不光service要交给spring来管理,repo和domain都要让spring来扫描:

<context:component-scan base-package="org.zhangfc.demo4ssh.service"/>
<context:component-scan base-package="org.zhangfc.demo4ssh.domain"/>
<context:component-scan base-package="org.zhangfc.demo4ssh.repo"/>

5. domain.User/repo.UserDao/service.UserService

首先在domain包下创建实体类User,我们就用最简单的只有两个字段,id和username:

@Entity
@Table
public class User implements Serializable {
private static final long serialVersionUID = 172643386440351811L;
private int id;
private String username; @Id
@GeneratedValue
public int getId() {
return id;
} public void setId(int id) {
this.id = id;
}

@Size(min=6)
public String getUsername() {
return username;
} public void setUsername(String username) {
this.username = username;
} }

这里的annotation用的都是JPA的接口,所以都是javax.persistence包下的,annotation加在变量上和getter方法上都可以,只不过加在public域更好一些,这儿为User对象定义了两个成员,id是主键、自增长,还有一个username,并对username做了一个限制,比如长度超过6才可以。

之后定义一个dao来访问数据库,创建一个新的package叫做repo(org.zhangfc.demo4ssh.repo),创建UserDao:

public interface UserDao {
public int save(User u);
public List<User> findAll();
}

创建实现类UserDaoImpl:

@Repository
public class UserDaoImpl implements UserDao { @Autowired
private SessionFactory sessionFactory; public List<User> findAll() {
Criteria criteria = sessionFactory.getCurrentSession().createCriteria(User.class);
return criteria.list();
} }

首先一个annotation注明这是一个repository,需要被Spring管理,然后自动装载之前在配置文件中配置的SessionFactory,获取当前session后获取所有的用户,下面修改之前的UserService代码,service封装业务逻辑层代码,我把每个service方法封装为一个事务,注:上面的SessionFactory获取当前Session是依赖于事务的,如果不在某个事务之内,会报错:No Session found for current thread。

UserService:

public interface UserService {
public void saveUsers(List<User> us);
public List<User> getAllUsers();
}

UserServiceImpl:

@Service
@Transactional
public class UserServiceImpl implements UserService { @Autowired
private UserDao userDao; public void saveUsers(List<User> us) {
for (User u : us) {
userDao.save(u);
}
} public List<User> getAllUsers() {
return userDao.findAll();
} }

这个Transactional的annotation就是指明每个方法是一个事务。最后修改HomeController:

@RequestMapping("")
public String home(){
List<User> us = new ArrayList<User>();
User u = new User();
u.setUsername("zhangsan");
us.add(u);
u = new User();
u.setUsername("wangwu");
us.add(u);
userService.saveUsers(us);
return "index";
} @RequestMapping("/json")
@ResponseBody
public List<User> json(){
return userService.getAllUsers();
}

之后运行程序,数据库会自动创建user表(注意,hibernate.hbm2dll.auto=create的话,每次运行程序都会删了之前的表重建,设置为update也会自动建表,且如果数据表已存在但和类的设置不同,会更新数据表,把类中声明的新的东西加上,但是数据表里有、类里面没有的不会在现有的数据表中删除),运行起来之后,访问http://localhost:8080/demo4ssh/会向user表中插入两条记录,因为userService的方法设置了事务,如果其中的任意一条sql执行失败,都将回滚,比如把wangwu改成lisi,因为长度不够,所以第二次插入时失败,那么zhangsan也不会被插入到数据表中。之后再访问http://localhost:8080/demo4ssh/json:

[{"id":1,"username":"zhangsan"},{"id":2,"username":"wangwu"}]

到此为止,SSH的基本框架就搭建出来了。源码下载

【JavaEE】Springmvc+Spring+Hibernate整合及example的更多相关文章

  1. SpringMVC+Spring+Hibernate整合开发

    最近突然想认真研究下java web常用框架,虽然现在一直在用,但实现的整体流程不是很了解,就在网上搜索资料,尝试自己搭建,以下是自己的搭建及测试过程. 一.准备工作: 1/安装并配置java运行环境 ...

  2. SpringMVC+Spring+hibernate整合及分页

    1. 新建web project 2. 引入jar, 3. 创建包com.tgb.web.controller, 下面创建包(dao,entity,service, config,spring,hib ...

  3. 3.springMVC+spring+Mybatis整合Demo(单表的增删该查,这里主要是贴代码,不多解释了)

    前面给大家讲了整合的思路和整合的过程,在这里就不在提了,直接把springMVC+spring+Mybatis整合的实例代码(单表的增删改查)贴给大家: 首先是目录结构: 仔细看看这个目录结构:我不详 ...

  4. SpringMVC+Spring+Hibernate的小样例

    Strusts2+Spring+Hibernate尽管是主流的WEB开发框架,可是SpringMVC有越来越多的人使用了.确实也很好用.用得爽! 这里实现了一个SpringMVC+Spring+Hib ...

  5. Maven搭建springMVC+spring+hibernate环境

    这次不再使用struts2做控制器,采用spring自己的springMVC框架实现. 首先,改写pom.xml文件,不需要struts2的相关jar了. pom.xml <project xm ...

  6. SpringMVC+Spring+Mybatis整合

    SpringMVC+Spring+Mybatis整合 导包 配置jdbc.properties.log4j.properties jdbc.driver=com.mysql.jdbc.Driver j ...

  7. Struts2+Spring+Hibernate整合开发(Maven多模块搭建)

    Struts2+Spring+Hibernate整合开发(Maven多模块搭建) 0.项目结构 Struts2:web层 Spring:对象的容器 Hibernate:数据库持久化操作 1.父模块导入 ...

  8. Springmvc+Spring+Mybatis整合开发(架构搭建)

    Springmvc+Spring+Mybatis整合开发(架构搭建) 0.项目结构 Springmvc:web层 Spring:对象的容器 Mybatis:数据库持久化操作 1.导入所有需要的jar包 ...

  9. spring+hibernate整合:报错org.hibernate.HibernateException: No Session found for current thread

    spring+hibernate整合:报错信息如下 org.hibernate.HibernateException: No Session found for current thread at o ...

随机推荐

  1. 基于CentOS与VmwareStation10搭建Oracle11G RAC 64集群环境:2.搭建环境-2.8. 配置用户环境

    2.8.配置用户环境 2.8.1. 配置节点RAC1 配置grid用户环境变量: cat >> /home/grid/.bash_profile <<EOF export TM ...

  2. RequireJS全面讲解

    异步模块定义(AMD)  谈起RequireJS,你无法绕过提及JavaScript模块是什么,以及AMD是什么. JavaScript模块只是遵循SRP(Single Responsibility  ...

  3. shareToQQ,qq 4.1.1 for android,闪退

    用shareToQQ函数分享图文消息,在qq 4.1.1 for android版本下打开联系人列表数秒后会闪退!在更高版本的V4.5.2.1,V4.2.1下则没有这个问题(证明各种设置没问题),各位 ...

  4. 经典算法——Jump Game(II)

    Given an array of non-negative integers, you are initially positioned at the first index of the arra ...

  5. Python——在Unicode和普通字符串之间转换

    1.1. 问题 Problem You need to deal with data that doesn't fit in the ASCII character set. 你需要处理不适合用ASC ...

  6. Nginx主动连接与被动连接的差别

    1.主动连接是指Nginx主动发起的同上游server的连接:被动连接是指Nginx接收到的来自client主动发起的连接; 2.主动连接用ngx_peer_connection_t结构体表示:被动连 ...

  7. angularJS学习笔记(二)

    前言 首先,了解 一下ng的一些概念: module 代码的组织单元,其它东西都是定义在具体的模块中的. app 应用业务,需要多个模块的配合完成. service 仅在数据层面实现特定业务功能的代码 ...

  8. spring揭秘读书笔记----ioc的基本概念

    在看ico概念之前,先想一下我们平常需要依赖某个类时会怎么做? 无非是在要用到的地方写如下代码: Person person = new Person(); //然后就可以用person对象来获取Pe ...

  9. centos7单机版安装hbase

    1.首先安装jdk1.8 yum install java-1.8.0-openjdk* -y 2.下载hbase 地址:http://mirrors.shuosc.org/apache/hbase/ ...

  10. 使用Google Https搜索

    一. 将浏览器Google的默认搜索使用https 1. IE浏览器 进入注册表搜索"google.com"将搜索替换成https://www.google.com.hk 2. F ...