前面简单的的学习了如何使用Struts2和Hibernate,学习了基本的配置方法和使用方法,最后需将新学习的表现层框架Struts2和持久层框架Hibernate,和Spring整合起来,以一个简单的验证登录案例,来理解其基本使用方法。
Spring和Hibernate的整合
Spring和Hibernate整合就是为了让Spring管理Hibernate的session和sessionFactory。类似Mybatis,在里面配置管理sessionFactory和MappingConfigurer。
(1)导包
Hibernate使用相关包: hibernate-core包,MySql-connector包,javassist包
连接池:dbcp,或者使用阿里的c3p0,这里使用c3p0
Spring使用相关包:spring-orm(对象关系映射包)
测试相关包:junit包
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.boe</groupId> <artifactId>SSH05-ssh</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>war</packaging> <dependencies> <!-- 导入Hibernate核心包 --> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>3.6.9.Final</version> </dependency> <!-- 导入数据库驱动包 --> <!-- MySql --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.46</version> </dependency> <!-- oracle --> <dependency> <groupId>com.oracle</groupId> <artifactId>ojdbc6</artifactId> <version>11.2.0.1.0</version> </dependency> <!-- 导入javassit.jar包 --> <dependency> <groupId>javassist</groupId> <artifactId>javassist</artifactId> <version>3.8.0.GA</version> </dependency> <!--导入junit测试包--> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> </dependency> <!-- 导入Spring-orm包 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-orm</artifactId> <version>3.0.5.RELEASE</version> </dependency> <!-- 导入数据库连接池相关的包,这里选择阿里的c3p0 --> <dependency> <groupId>c3p0</groupId> <artifactId>c3p0</artifactId> <version>0.9.1</version> </dependency> <!-- 配置struts2相关的包 --> <dependency> <groupId>org.apache.struts</groupId> <artifactId>struts2-core</artifactId> <version>2.3.8</version> </dependency> <dependency> <groupId>org.apache.struts</groupId> <artifactId>struts2-spring-plugin</artifactId> <version>2.3.8</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>3.0.5.RELEASE</version> </dependency> <dependency> <groupId>org.apache.struts</groupId> <artifactId>struts2-json-plugin</artifactId> <version>2.3.8</version> </dependency> </dependencies> </project>
(2)配置文件
与MyBatis类似,MyBatis在与Spring整合之前,需要一个专门的MyBatis配置文件,其中有配置数据库连接以及Mapper映射文件的位置,如果与Spring整合后,MyBatis的相关连接配置和Mapper配置都放到了Spring配置文件中。与MyBatis类似,Hibernate与Spring整合后,也是在Spring的配置文件中进行数据库连接配置,以及配置Mapper文件xxx.hbm.xml文件,因此配置文件需要一个spring-*.xml,以及若干类名.hbm.xml文件。
spring-*.xml
(2-1)需配置数据库连接池,这次用的c3p0配置dataSource bean,与MyBatis类似,也需要配置sessionFactory,在sessionFactory里面有hibernatePropeties属性和mappingLocation属性,这两个属性可以完成以前hibernate.cfg.xml的部分配置,如dialect,show_sql,format_sql等配置在hibernatePropeties,而映射文件配置在mappingLocation属性下面。
(2-2)配置hibernateTemplate,如果不整合spring,需要手动得到session对象,然后再调用session对象的query方法获得query对象,最后使用list方法得到查询对象,整合后直接使用hibernateTemplate的API可以直接得到查询对象,因此需要配置。
(2-3)配置事物传播属性,与MyBatis类似,只是具体的实现类不一样,需要引入的属性也不一样,这里需要引入sessionFactory,初始化transactionManager。
<?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:context="http://www.springframework.org/schema/context" xmlns:util="http://www.springframework.org/schema/util" xmlns:jee="http://www.springframework.org /schema/jee" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jpa="http://www.springframework.org/schema/data/jpa" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-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/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd"> <!-- 注意spring-tx的版本是3.0 --> <!-- 配置组件扫描 --> <context:component-scan base-package="*"></context:component-scan> <!-- 添加注解驱动 --> <mvc:annotation-driven></mvc:annotation-driven> <!-- 配置数据库连接 --> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="driverClass" value="com.mysql.jdbc.Driver" /><!-- MyBatis使用driverClassName --> <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/ssh" /><!-- MyBatis使用url --> <property name="user" value="root" /><!-- MyBatis使用username --> <property name="password" value="2688" /><!-- MyBatis也使用password --> <property name="maxPoolSize" value="10" /><!-- MyBatis使用maxActive --> </bean> <!-- 配置sessionFactory --> <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> <!-- 把上面配置的dataSource注入到sessonFactory的dataSource属性 --> <property name="dataSource" ref="dataSource"></property> <!-- 配置hibernate相关参数,如dialect,设置打印和格式化sql,设置Mapper映射文件位置 --> <property name="hibernateProperties"> <props> <prop key="hibernateProperties.dialect">org.hibernate.dialect.MySQLDialect</prop> <prop key="hibernateProperties.show_sql">true</prop> <prop key="hibernateProperties.format_sql">true</prop> </props> </property> <!-- 配置类名.hbm.xml文件的位置 --> <property name="mappingLocations"> <list> <value>classpath:Mapper/user.hbm.xml</value> </list> </property> </bean> <!-- 配置事务管理 --> <bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"><!-- 与MyBatis下的有不同 --> <property name="sessionFactory" ref="sessionFactory"></property> </bean> <!-- 配置事务注解驱动 --> <tx:annotation-driven transaction-manager="txManager"/> <!-- 配置HibernateTemplate CRUD方法--> <!-- CRUD:增加(Create)、读取(Retrieve)(重新得到数据)、更新(Update)和删除(Delete) --> <bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate"> <property name="sessionFactory" ref="sessionFactory"></property> </bean> </beans>
user.hbm.xml
user.hbm.xml跟以前一样,配置class,里面添加user实体类和t_user表的映射关系。
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <!-- 配置映射文件,名字一般用实体类类名.hbm.xml --> <hibernate-mapping> <!-- 创建表和实体类的映射关系 --> <class name="Entity.User" table="cn_user"> <!-- 配置属性 --> <id name="id" column="id" type="string"></id> <property name="name" column="name" type="string"></property> <property name="password" column="password" type="string"></property> <property name="token" column="token" type="string"></property> <property name="nick" column="nick" type="string"></property> </class> </hibernate-mapping>
(3)实现类
package Entity; import java.io.Serializable; public class User implements Serializable{ private static final long serialVersionUID = -7728746060923203214L; private String id; private String name; private String password; private String token; private String nick; public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getToken() { return token; } public void setToken(String token) { this.token = token; } public String getNick() { return nick; } public void setNick(String nick) { this.nick = nick; } @Override public String toString() { return "User [id=" + id + ", name=" + name + ", password=" + password + ", token=" + token + ", nick=" + nick + "]"; } }
(4)建表 cn_user
(5)测试Service层+DAO层
DAO层需要建立接口,以及接口的实现类,MyBatis是不需要创建实现了的,Hibernate需要。
DAO层:
package DAO; import Entity.User; public interface userDAO { //常用方法 public void save(User user); public void update(User user); public void delete(User user); //验证登录的方法,根据用户名查找user信息 public User findUserByName(String name); }
package DAO; import java.util.List; import javax.annotation.Resource; import org.springframework.orm.hibernate3.HibernateTemplate; import org.springframework.stereotype.Repository; import org.springframework.transaction.annotation.Transactional; import Entity.User; /** * 登录验证实现类 * @author yangchaolin */ @Repository("userDAO") @Transactional public class userDAOImpl implements userDAO{ @Resource(name="hibernateTemplate") HibernateTemplate hibernateTemplate=null; public void save(User user) { } public void update(User user) { } public void delete(User user) { } //实现登录验证逻辑 public User findUserByName(String name) { //得到一个User对象,通过HQL语句 /** * 如果只是使用Hibernate框架: * (1)需要先得到session * (2)然后编写HQL * (3)调用session.query(hql)方法获得query对象,如果HQL语句中需要传入参数使用setXxx()方法 * (4)通过query对象得到我们需要的查询结果 */ //Spring和MyBatis整合后,直接使用HibernateTemplate来实现 String hql="from User where name=:name"; List list=hibernateTemplate.findByNamedParam(hql, "name", name); //list只有一个元素,获取第一个 User user=(User) list.get(0); System.out.println("DAO层:"+user); return user; } }
Service层:
package Service; import Entity.User; public interface userService { public User checkUserPassword(String name,String password); }
package Service; import javax.annotation.Resource; import org.springframework.stereotype.Service; import DAO.userDAO; import Entity.User; @Service("userService") public class userServiceImpl implements userService{ //注入DAO层 @Resource(name="userDAO") userDAO dao; //service层具体业务逻辑实现 public User checkUserPassword(String name, String password) { User user=dao.findUserByName(name); System.out.println("Service层:"+user); if(user!=null) { String passwordFromDB=user.getPassword(); if(passwordFromDB.equals(password)) { return user; } return null; } return user;//如果user为空返回null } }
测试类:
package testCase; import org.junit.Before; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import DAO.userDAO; import Entity.User; import Service.userService; public class testSSH { String config="config/spring-mvc.xml"; private ApplicationContext ac; @Before public void initTest() { ac=new ClassPathXmlApplicationContext(config); } //测试DAO @Test public void testLogin() { userDAO dao=ac.getBean("userDAO",userDAO.class); User user=dao.findUserByName("messi"); System.out.println(user); } //测试Service @Test public void testService() { userService service=ac.getBean("userService",userService.class); String name="messi"; String password="123456"; User user=service.checkUserPassword(name, password); System.out.println("Service层:"+user); } }
测试结果:
测试没有问题就可以接下来整合Struts2+Spring了。
Struts2和Spring的整合
配置跟以前学习的一样,需要导入关键包,以及配置struts.xml和web.xml
(1)导包 struts2-core,struts2-spring-plugin,spring-webmvc,如果测试返回为json,可以导包struts2-json-plugin,以及整合到前面的导包文件了,可以参考前面内容。
(2)配置spring-*.xml(组件扫描),配置struts.xml,还有web.xml(配置listener,context-param,filter)
这里主要再复习下,配置listener的作用是使用它来启动spring容器,而启动容易需要读取配置文件,不配置的话就是默认读取WEB-INF下的applicationContext.xml,如果配置了context-param就会从配置地址读取,filter的配置相当如以前的servlet的配置。
web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5"> <display-name>SSH05-ssh</display-name> <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file> <welcome-file>default.html</welcome-file> <welcome-file>default.htm</welcome-file> <welcome-file>default.jsp</welcome-file> </welcome-file-list> <!-- 配置spring相关 --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:config/spring-*.xml</param-value> </context-param> <listener> <listener-class> org.springframework.web.context.ContextLoaderListener </listener-class> </listener> <!-- 配置struts2相关 --> <filter> <filter-name>mvc</filter-name> <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class> <init-param> <param-name>config</param-name> <param-value> struts-default.xml,struts-plugin.xml, config/struts.xml </param-value> </init-param> </filter> <filter-mapping> <filter-name>mvc</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> </web-app>
struts.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" "http://struts.apache.org/dtds/struts-2.3.dtd"> <!-- dtd文件导入的作用:决定了xml文件可以使用什么标签 --> <struts> <package name="demo" namespace="/login" extends="struts-default"> <!-- 进入登录页面 --> <action name="toLogin" > <result name="success" type="dispatcher"> /WEB-INF/login.jsp </result> </action> <!-- 进入登录验证 --> <action name="login" class="loginCheck"> <result name="success"> /WEB-INF/helloStruts.jsp </result> </action> </package> </struts>
(3)filter实现类
package Filter; import javax.annotation.Resource; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Controller; import Entity.User; import Service.userService; /** * 控制层 * @author yangchaolin */ @Controller("loginCheck") @Scope("prototype") public class loginCheck { //定义属性,需要和form表单中的一致 private String username; private String password; private String message; public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } //注入业务层 @Resource(name="userService") userService service; //默认实现方法 public String execute() { User user=service.checkUserPassword(username, password); if(user!=null) { message="Hello Struts2+Spring+Hibernate"; return "success"; }else { message="username or password is error"; return "success"; } } }
(4)jsp页面,登录页面和返回登录信息页面
<%@page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8" %> <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>基本属性提交方式-登录</title> </head> <body style="font-family:'微软雅黑';font-size:20px;"> <form action="login.action" method="post"> <div> <label>用户名:</label> <input type="text" name="username" /> </div> <div> <label>密码:</label> <input type="password" name="password" /> </div> <div> <input type="submit" value="登录" /> </div> </form> </body> </html>
<%@page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Struts2+Spring+Hibernate</title> </head> <body style="font-family:'微软雅黑';font-size:20px;"> <!-- 使用EL表达式从服务端获取数据 --> <h1>${message}</h1> </body> </html>
(5)登录测试
这样就完成了一个简单的Struts2+Spring+Hibernate搭建,并实现简单登录逻辑。
结论
整合Struts2+Spring+Hibernate,需要熟悉没有和Spring整合之前如何配置,有了Spring部分内容在Spring-*.xml文件中进行了集成,另外Spring帮忙自动管理Struts2和Hibernate组件。