做一下笔记(参考Spring 事务管理高级应用难点剖析: 第 2 部分):
调用私有方法:下面的私有方法test出现异常,会受到事务控制
package com.tch.test.template.service; import java.util.Date; import java.util.List; import javax.annotation.Resource; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import com.tch.test.template.dao.QQServiceGroupDao; import com.tch.test.template.po.QQServiceGroup; @Service("xxService") public class QQServiceGroupServiceImpl implements QQServiceGroupService { @Resource(name="QQServiceGroupDao") private QQServiceGroupDao QQServiceGroupDao; @Override @Transactional(rollbackFor=Exception.class) public void addQQServiceGroup(LBQQServiceGroup group) throws Exception { test(group); } private void test(QQServiceGroup group) throws Exception { QQServiceGroupDao.saveEntity(group); throw new Exception("私有方法异常"); } }
1.private 方法上面使用spring注解事物能起作用吗?
不能,因为spring的事务无非是通过两种方式:一种是JDK的Proxy代理(实现相同接口),另一种是使用cglib(通过继承该类,并重写方法),无论哪种,对于私有方法都不能实现代理,也就不能实现事务管理了。
2.既使用了hibernate又使用了ibatis或者jdbc的话,使用spring配置事物该怎么配置?
3.有三个方法 a,b,c
a调用b,
c也调用b,
现在要求a调用b的时候,b的事务传播特性是required(也就是共用一个事物)
并且c调用b的时候,b的事务传播特性是独立的(也就是b单独使用一个事物)
4.没有实现接口的类,配置注解事务能起作用吗?
可以;
这时候的事务是通过cglib扩展字节码的方式实现的(也就是上面说到的继承并重写方法的方式),
如果是实现了接口的类,它的事务是通过JDK自带的Proxy实现同样的接口的代理类实现的,
平时我们使用接口的方式的好处是方便以后扩展实现类
5.不能受到spring事务管理的方法:
如果是 基于接口的动态代理:除 public 外的其它所有的方法都不能使用spring事务,此外 public static 也不能被增强
如果是 基于 CGLib 的动态代理:private、static、final 的方法不能受到spring事务管理
Maven依赖:
<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/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.tch.test</groupId> <artifactId>template</artifactId> <packaging>war</packaging> <version>1.0.0</version> <name>template Maven Webapp</name> <url>http://maven.apache.org</url> <dependencies> <!-- junit --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>${junit-version}</version> <scope>test</scope> </dependency> <!-- spring-context --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring-version}</version> </dependency> <!-- spring-orm --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-orm</artifactId> <version>${spring-version}</version> </dependency> <!-- hibernate --> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>${hiberante-version}</version> </dependency> <!-- hibernate-proxool --> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-proxool</artifactId> <version>${hiberante-version}</version> </dependency> <!-- struts2 --> <dependency> <groupId>org.apache.struts</groupId> <artifactId>struts2-core</artifactId> <version>${struts2-version}</version> </dependency> <!-- struts2-spring-plugin --> <dependency> <groupId>org.apache.struts</groupId> <artifactId>struts2-spring-plugin</artifactId> <version>${struts2-version}</version> </dependency> <!-- mysql --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>${mysql-version}</version> </dependency> <!-- log4j --> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>${log4j-version}</version> </dependency> <!-- slf4j-log4j --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>${slf4j-version}</version> </dependency> <!-- aspectjrt --> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjrt</artifactId> <version>${aspectj-version}</version> </dependency> <!-- aspectjweaver --> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>${aspectj-version}</version> </dependency> </dependencies> <build> <finalName>template</finalName> </build> <properties> <junit-version>4.11</junit-version> <spring-version>3.2.6.RELEASE</spring-version> <hiberante-version>3.6.10.Final</hiberante-version> <struts2-version>2.3.16</struts2-version> <mysql-version>5.1.28</mysql-version> <log4j-version>1.2.17</log4j-version> <slf4j-version>1.7.5</slf4j-version> <aspectj-version>1.7.4</aspectj-version> </properties> </project>
如果要修改struts2的拦截地址后缀为 *.htm和 *.action则需要在struts.xml或者struts.properties中配置:
在struts.xml中配置的话:
<constant name="struts.action.extension" value=",htm,action"></constant>或则在struts.properties中配置:
struts.action.extension=,htm,action前面的逗号是为了可以拦截不加后缀的请求,例如: http://localhost:8080/ssh/show.htm 、 http://localhost:8080/ssh/show.action 、 http://localhost:8080/ssh/show 三种方式
这里的hibernate功能没有真正的使用
首先当然是jar包了:
struts2里面的Jar包:下载的struts2压缩包里面的struts-2.3.15.1\apps\struts2-blank,直接引入,另外就是struts2-spring-plugin-2.3.15.1.jar这个struts2和spring整合的jar
hibernate: hibernate3.jar是肯定的,另外就是hibernate-distribution-3.6.10.Final\lib\required下面的必须的包,以及jpa下面的hibernate-jpa-2.0-api-1.0.1.Final.jar
spring: spring.jar
cglib-nodep-2.1_3.jar
slf4j-api-1.5.0.jar
slf4j-log4j12-1.5.0.jar
还有就是连接数据库的(mysql为例:)mysql-connector-java-5.0.8-bin.jar
所有的包在图片里面有汇总
好了,下面开始进入正题:
web.xml:
<?xml version="1.0" encoding="UTF-8"?> <web-app id="WebApp_9" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> <display-name>Struts Blank</display-name> <!-- 指定spring配置文件applicationContext.xml(可以多个)的位置 --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath*:applicationContext.xml</param-value> </context-param> <!-- 服务器启动的时候加载spring --> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!-- 配置struts2的filter --> <filter> <filter-name>struts2</filter-name> <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class> </filter> <filter-mapping> <filter-name>struts2</filter-name> <url-pattern>*.action</url-pattern> </filter-mapping> <!-- 配置字符编码过滤器 --> <filter> <filter-name>encodingFilter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>utf-8</param-value> </init-param> </filter> <filter-mapping> <filter-name>encodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app>
applicationContext.xml:注解事务管理,需要在方法上加@Transactional(propagation=Propagation.REQUIRED,rollbackFor=Exception.class)
<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:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"> <!-- 启动注入功能 --> <context:annotation-config /> <!-- 启动扫描component功能 --> <context:component-scan base-package="com.tch.test" /> <!-- 启动注解实物配置功能 --> <tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/> <!-- 数据源 --> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"></property> <property name="url" value="jdbc:mysql://localhost:3306/test"></property> <property name="username" value="root"></property> <property name="password" value="root"></property> </bean> <!-- 事务管理器 --> <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory" /> </bean> <!-- 使用xml和注解同时来映射实体类 --> <bean class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean" id="sessionFactory"> <property name="dataSource" ref="dataSource"></property> <property name="packagesToScan"> <list> <value>com.tch.test.ssh.entity.annotation</value><!-- 注解的实体类所在的包,例如下面的Student.class --> </list> </property> <property name="mappingLocations"> <list> <value>classpath*:com/tch/test/ssh/entity/*.hbm.xml</value><!-- 指定xml格式的映射文件位置 --> </list> </property> <property name="hibernateProperties"> <props> <prop key="hibernate.show_sql">true</prop> <prop key="hibernate.hbm2ddl.auto">update</prop> </props> </property> </bean> <!--读取数据库配置文件 <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> <property name="mappingLocations"> <value>classpath:com/tch/test/ssh/entity/*.hbm.xml</value> </property> <property name="hibernateProperties"> <props> <prop key="hibernate.show_sql">true</prop> </props> </property> </bean> --> </beans>
xml文件配置的事务管理方式:这种方式不需要在方法上加@Transactional(propagation=Propagation.REQUIRED,rollbackFor=Exception.class)
<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:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"> <!-- 启动注入功能 --> <context:annotation-config /> <!-- 启动扫描component功能 --> <context:component-scan base-package="test,com.tch.test" /> <!-- 不启动注解实物配置功能 <tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/> --> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <tx:method name="get*" read-only="true"/> <tx:method name="select*" read-only="true"/> <tx:method name="*" propagation="REQUIRED" rollback-for="java.lang.Exception"/> </tx:attributes> </tx:advice> <aop:config> <aop:pointcut expression="execution(* com.tch.test.ssh..*.*(..))" id="testpointcut"/> <aop:advisor advice-ref="txAdvice" pointcut-ref="testpointcut"/> </aop:config> <!-- 数据源 --> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"></property> <property name="url" value="jdbc:mysql://localhost:3306/test"></property> <property name="username" value="root"></property> <property name="password" value="root"></property> </bean> <!-- 事务管理器 --> <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory" /> </bean> <!--读取数据库配置文件 --> <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> <property name="mappingLocations"> <value>classpath:com/tch/test/ssh/entity/*.hbm.xml</value> </property> <property name="hibernateProperties"> <props> <prop key="hibernate.show_sql">true</prop> </props> </property> </bean> <!-- 使用xml和注解同时来映射实体类 --> <!-- <bean class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean" id="sessionFactory"> <property name="dataSource" ref="dataSource"></property> <property name="packagesToScan"> <list> <value>com.tch.test.ssh.entity.annotation</value><!-- 注解的实体类所在的包,例如下面的Student.class --> </list> </property> <property name="mappingLocations"> <list> <value>classpath*:com/tch/test/ssh/entity/*.hbm.xml</value> </list> </property> <property name="hibernateProperties"> <props> <prop key="hibernate.show_sql">true</prop> <prop key="hibernate.hbm2ddl.auto">update</prop> </props> </property> </bean> --> </beans>
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"> <struts> <constant name="struts.enable.DynamicMethodInvocation" value="true" /> <constant name="struts.devMode" value="true" /> <!-- 自定义package,在里面加入拦截器栈,注意最后要加上默认拦截器栈,并将自定义的拦截器栈作为默认的拦截器栈,后面的package直接继承该package即可实现所有action加入拦截功能 --> <package name="mypackage" extends="struts-default"> <interceptors> <interceptor name="checkLogin" class="checkLogin"></interceptor> <interceptor-stack name="myStack"> <interceptor-ref name="checkLogin"/> <interceptor-ref name="defaultStack"/> </interceptor-stack> </interceptors> <default-interceptor-ref name="myStack"/> </package> <package name="default" namespace="/" extends="mypackage"> <default-action-ref name="index" /> <global-results> <result name="error">/error.jsp</result> </global-results> <global-exception-mappings> <exception-mapping exception="java.lang.Exception" result="error" /> </global-exception-mappings> <action name="show" class="userAction" method="select"> <result>/WEB-INF/pages/User.jsp</result> </action> <action name="goEdit" class="userAction" method="goEdit"> <result>/WEB-INF/pages/editUser.jsp</result> </action> <!-- 使用通配符 --> <action name="*User" class="userAction" method="{1}User"> <result type="redirectAction"> <param name="actionName">show</param> <param name="namespace">/</param> </result> </action> </package> </struts>
拦截器:
package com.tch.test.ssh.interceptor; import java.util.Date; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import org.apache.struts2.StrutsStatics; import org.springframework.stereotype.Component; import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.interceptor.Interceptor; import com.tch.test.ssh.entity.User; import com.tch.test.ssh.info.LoginInfo; import com.tch.test.ssh.info.UserInfo; @Component("checkLogin") public class CheckLoginInterceptor implements Interceptor { private static final long serialVersionUID = 1L; public CheckLoginInterceptor(){ System.out.println("CheckLoginInterceptor拦截器创建"); } @Override public String intercept(ActionInvocation invocation) throws Exception { System.out.println("interceptor............................"); HttpServletRequest request = (HttpServletRequest) invocation.getInvocationContext().get(StrutsStatics.HTTP_REQUEST); String url = request.getRequestURI(); if(url.contains("/ssh/login.action")){ //登陆 return invocation.invoke(); } //已经登陆 HttpSession session = request.getSession(); Date current_login_time = (Date) session.getAttribute("login_time"); User user = (User) session.getAttribute("login_user"); if(user == null || user.getId() == null || current_login_time == null){ //session中没有相关信息,则重新登录 return "login"; } LoginInfo info = (LoginInfo)UserInfo.LOGIN_USERS.get(user.getId()); if(info != null && info.getLoginTime() != null){ Date latest_login_time = info.getLoginTime(); if(latest_login_time.getTime() > current_login_time.getTime()){ ActionContext.getContext().put("errorMessage", "账号在别处登录,当前用户被强制退出 !"); session.invalidate(); System.out.println("*****************删除session*************"); return "error"; } } return invocation.invoke(); } @Override public void destroy() { } @Override public void init() { } }
action:
package com.tch.test.ssh.web.action; import java.util.List; import java.util.Set; import javax.annotation.Resource; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; import com.opensymphony.xwork2.ActionSupport; import com.tch.test.ssh.entity.Priority; import com.tch.test.ssh.entity.User; import com.tch.test.ssh.service.IPriorityService; import com.tch.test.ssh.service.IUserService; @Component("userAction") @Scope("prototype") public class UserAction extends ActionSupport { private static final long serialVersionUID = 1L; private User user; private List<Priority> priorities; @Resource(name="userService") private IUserService userService; @Resource(name="priorityService") private IPriorityService priorityService; private List<User> users; private List<String> priorityName; public List<String> getPriorityName() { return priorityName; } public void setPriorityName(List<String> priorityName) { this.priorityName = priorityName; } public String select() throws Exception{ users = userService.select(); System.out.println("所有用户数:"+users.size()); return "success"; } public String addUser() throws Exception{ System.out.println("add .. "+user); userService.add(user); return "success"; } public String goEdit() throws Exception{ user = userService.getUserById(user.getId()); priorities = priorityService.getPriorityByUserId(user.getId()); System.out.println(user); return "success"; } /** * 删除用户 * @return * @throws Exception */ public String deleteUser() throws Exception{ userService.deleteUser(user.getId()); return "success"; } /** * 修改用户信息 * @return * @throws Exception */ public String editUser() throws Exception{ try { Set<Priority> priorities = priorityService.getPrioritiesByNames(priorityName); user.setPriorities(priorities); userService.editUser(user); } catch (Exception e) { e.printStackTrace(); } return "success"; } public User getUser() { return user; } public void setUser(User user) { this.user = user; } public List<Priority> getPriorities() { return priorities; } public void setPriorities(List<Priority> priorities) { this.priorities = priorities; } public List<User> getUsers() { return users; } public void setUsers(List<User> users) { this.users = users; } }
service接口:
package com.tch.test.ssh.service; import java.util.List; import java.util.Set; import com.tch.test.ssh.entity.Priority; public interface IPriorityService { /** * 根据id获取user对象 * @param id * @return */ List<Priority> getPriorityByUserId(Integer id) throws Exception; /** * 根据id获取实体对象 * @param id * @return */ Priority getEntity(Integer id) throws Exception; /** * 根据name获取实体对象 * @param id * @return */ Set<Priority> getPrioritiesByNames(List<String> names) throws Exception; /** * 测试事务 * @throws Exception */ void testTransaction() throws Exception; }
package com.tch.test.ssh.service; import java.util.List; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; import com.tch.test.ssh.entity.User; public interface IUserService { /** * 测试事务特性 */ @Transactional(propagation=Propagation.REQUIRED,rollbackFor=Exception.class) void testTransaction() throws Exception; /** * 添加user对象 * @param id * @return */ void add(User user) throws Exception; /** * 查询所有user对象 * @param id * @return */ List<User> select() throws Exception; /** * 根据id获取user对象 * @param id * @return */ User getUserById(Integer id) throws Exception; /** * 根据id获取user对象 * @param id * @return */ void editUser(Integer id, List<String> priorities) throws Exception; /** * 根据id获取实体对象 * @param id * @return */ User getEntity(Integer id) throws Exception; }
service实现类:
package com.tch.test.ssh.service; import java.util.List; import javax.annotation.Resource; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; import com.tch.test.ssh.dao.IPriorityDao; import com.tch.test.ssh.entity.Priority; @Service("priorityService") public class PriorityServiceImpl implements IPriorityService { @Resource(name="priorityDao") private IPriorityDao priorityDao; @Override @Transactional(propagation=Propagation.REQUIRED,rollbackFor=Exception.class) public List<Priority> getPriorityByUserId(Integer id) throws Exception{ return priorityDao.getPriorityByUserId(id); } @Override @Transactional(propagation=Propagation.REQUIRED,rollbackFor=Exception.class) public void testTransaction() throws Exception { Priority p = new Priority(); p.setName("测试"); priorityDao.save(p); boolean b=true; if(b){ throw new Exception("priority 抛出异常。。。。"); } } }
package com.tch.test.ssh.service; import java.util.List; import javax.annotation.Resource; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; import com.tch.test.ssh.dao.IUserDao; import com.tch.test.ssh.entity.User; @Service("userService") @Transactional(propagation=Propagation.REQUIRED) public class UserServiceImpl implements IUserService { @Resource(name="userDao") private IUserDao userDao; @Override @Transactional(propagation=Propagation.REQUIRED,rollbackFor=Exception.class) public void add(User user) throws Exception { userDao.save(user); } @Override @Transactional(propagation=Propagation.REQUIRED,rollbackFor=Exception.class) public void editUser(Integer id, List<String> priorities) throws Exception{ userDao.editUser(id, priorities); } @Override @Transactional(propagation=Propagation.REQUIRED,rollbackFor=Exception.class) public User getUserById(Integer id) throws Exception { return userDao.get(id); } @Override @Transactional(propagation=Propagation.REQUIRED,rollbackFor=Exception.class) public List<User> select() throws Exception { return userDao.getAll(); } @Override @Transactional(propagation=Propagation.REQUIRED,rollbackFor=Exception.class) public User getEntity(Integer id) throws Exception { return userDao.get(id); } @Override @Transactional(propagation=Propagation.REQUIRED,rollbackFor=Exception.class) public void testTransaction() throws Exception { User user = new User(); user.setName("service"); user.setPassword("service"); add(user); userDao.testTransaction(); } }
dao:
首先是dao基础接口
package com.tch.test.ssh.dao; import java.io.Serializable; import java.util.List; public interface BaseDao<E, PK extends Serializable> { /** * CreaEed on 2013-9-16 * <p>DiscripEion:保存对象</p> * @reEurn void */ void save(E entity); /** * CreaEed on 2013-9-16 * <p>DiscripEion:更新对象</p> * @reEurn void */ void update(E entity); /** * CreaEed on 2013-9-16 * <p>DiscripEion:删除对象</p> * @reEurn void */ void delete(E entity); /** * CreaEed on 2013-9-16 * <p>DiscripEion:根据id查询对象</p> * @reEurn void */ E get(PK id); /** * CreaEed on 2013-9-16 * <p>DiscripEion:查询全部对象</p> * @reEurn void */ List<E> getAll(); /** * Created on: 2013-12-4 * <p>Discription: 保存全部</p> * @param entities * @return void */ void saveAll(List<E> entities); }
dao基础实现类:
package com.tch.test.ssh.dao; import java.io.Serializable; import java.lang.reflect.ParameterizedType; import java.util.List; public class BaseDaoImpl<E, PK extends Serializable> extends CommomDao implements BaseDao<E,PK>{ private Class<E> clazz; @SuppressWarnings("unchecked") public BaseDaoImpl(){ this.clazz = (Class<E>)((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0]; } @Override public void delete(E entity) { getHibernateTemplate().delete(entity); } @SuppressWarnings("unchecked") @Override public E get(PK id) { return (E)getHibernateTemplate().get(clazz, id); } @SuppressWarnings("unchecked") @Override public List<E> getAll() { return getHibernateTemplate().loadAll(clazz); /*String hql = "from "+clazz.getName(); System.out.println("hql: "+hql); return getSession().createQuery(hql).list();*/ } @Override public void save(E entity) { getHibernateTemplate().save(entity); } @Override public void update(E entity) { getHibernateTemplate().update(entity); } @Override public void saveAll(List<E> entities) { getHibernateTemplate().saveOrUpdateAll(entities); } }
dao接口的demo:
package com.tch.test.ssh.dao; import com.tch.test.ssh.entity.MyTime; public interface TimeDao extends BaseDao<MyTime, Integer>{ }
dao实现类的demo:
package com.tch.test.ssh.dao; import org.springframework.stereotype.Repository; import com.tch.test.ssh.entity.MyTime; @Repository("TimeDao") public class TimerDaoImpl extends BaseDaoImpl<MyTime, Integer> implements TimeDao{ }
package com.tch.test.ssh.dao; import javax.annotation.Resource; import org.hibernate.SessionFactory; import org.springframework.orm.hibernate3.support.HibernateDaoSupport; public class CommomDao extends HibernateDaoSupport{ @Resource(name="sessionFactory") public void setSuperSessionFactory(SessionFactory sessionFactory){ this.setSessionFactory(sessionFactory); } }
package com.tch.test.ssh.dao; import java.util.List; import com.tch.test.ssh.entity.Priority; public interface IPriorityDao extends BaseDao<Priority,Integer>{ /** * 根据id获取user对象 * @param id * @return */ List<Priority> getPriorityByUserId(Integer id) throws Exception; }
package com.tch.test.ssh.dao; import java.util.List; import com.tch.test.ssh.entity.User; public interface IUserDao extends BaseDao<User,Integer> { /** * 根据id获取user对象 * @param id * @return */ void editUser(Integer id, List<String> priorities) throws Exception; /** * 测试事务 */ void testTransaction() throws Exception; }
package com.tch.test.ssh.dao; import java.util.ArrayList; import java.util.List; import org.springframework.stereotype.Repository; import com.tch.test.ssh.entity.Priority; @Repository("priorityDao") public class PriorityDaoImpl extends BaseDaoImpl<Priority,Integer> implements IPriorityDao { /** * 根据用户id查询用户权限 * @param id * @return */ @SuppressWarnings("unchecked") @Override public List<Priority> getPriorityByUserId(Integer id) throws Exception { List<Priority> priorities = new ArrayList<Priority>(); String sql = " select p.id,p.name from User u , Priority p , User_Priority up where u.id = :id and u.id = up.userId and p.id = up.priorityId "; List<Object[]> result = getSession().createSQLQuery(sql).setInteger("id", id).list(); if(result != null && result.size()>0){ Priority temp = null; for(Object[] obj:result){ temp = new Priority(); temp.setId(Integer.parseInt(obj[0].toString())); temp.setName(obj[1].toString()); priorities.add(temp); } } return priorities; } }
package com.tch.test.ssh.dao; import java.util.List; import org.hibernate.Session; import org.springframework.stereotype.Repository; import com.tch.test.ssh.entity.User; @Repository("userDao") public class UserDaoImpl extends BaseDaoImpl<User,Integer> implements IUserDao{ @Override public void testTransaction() throws Exception { User user = new User(); user.setName("test"); user.setPassword("password"); getHibernateTemplate().save(user); boolean b=true; if(b){ throw new Exception("priority 抛出异常。。。。"); } } /** * 修改用户权限 * @param id * @param priorities */ @Override public void editUser(Integer id, List<String> priorities) throws Exception{ //删除已有的 Session session = getSessionFactory().openSession(); String sql = " delete up from User_Priority up where up.userId = :userId "; session.createSQLQuery(sql).setInteger("userId", id).executeUpdate(); //再重新插入 sql = " insert into User_Priority(userId,priorityId) values(:userId,:priorityId) "; String sql2 = " select id from priority where name = :name "; for(String p:priorities){ Integer pId = (Integer) session.createSQLQuery(sql2).setString("name", p).uniqueResult(); session.createSQLQuery(sql).setInteger("userId", id).setInteger("priorityId", pId).executeUpdate(); } } }
实体类:Priority.java
package com.tch.test.ssh.entity; import java.util.Set; /** * Priority entity. @author MyEclipse Persistence Tools */ public class Priority implements java.io.Serializable { // Fields private static final long serialVersionUID = 1L; private Integer id; private String name; private Set<User> users; // Constructors /** default constructor */ public Priority() { } @Override public String toString() { return "Priority [id=" + id + ", name=" + name + "]"; } /** full constructor */ public Priority(String name) { this.name = name; } // Property accessors public Integer getId() { return this.id; } public void setId(Integer id) { this.id = id; } public String getName() { return this.name; } public Set<User> getUsers() { return users; } public void setUsers(Set<User> users) { this.users = users; } public void setName(String name) { this.name = name; } }
User.java
package com.tch.test.ssh.entity; import java.util.Set; /** * User entity. @author MyEclipse Persistence Tools */ public class User implements java.io.Serializable { // Fields private static final long serialVersionUID = 1L; private Integer id; private String name; private String password; private Set<Priority> priorities; // Constructors @Override public String toString() { return "User [id=" + id + ", name=" + name + ", password=" + password + ", priorities=" + priorities + "]"; } /** default constructor */ public User() { } /** full constructor */ public User(String name, String password) { this.name = name; this.password = password; } // Property accessors public Integer getId() { return this.id; } public void setId(Integer id) { this.id = id; } public String getName() { return this.name; } public void setName(String name) { this.name = name; } public Set<Priority> getPriorities() { return priorities; } public void setPriorities(Set<Priority> priorities) { this.priorities = priorities; } public String getPassword() { return this.password; } public void setPassword(String password) { this.password = password; } }
映射文件:(没有配置表关联关系):
注解的实体映射文件:
package com.tch.test.ssh.entity.annotation; import java.io.Serializable; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; @Entity @Table(name="student") public class Student implements Serializable { private static final long serialVersionUID = 1L; @Id @GeneratedValue(strategy=GenerationType.IDENTITY) private Integer id; private String name; private int age; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }
User.hbm.xml
<?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.tch.test.ssh.entity.User" table="user" catalog="test"> <id name="id" type="java.lang.Integer"> <column name="id" /> <generator class="identity" /> </id> <property name="name" type="java.lang.String"> <column name="name" length="20"> <comment>姓名</comment> </column> </property> <property name="password" type="java.lang.String"> <column name="password" length="20"> <comment>密码</comment> </column> </property> <set name="priorities" table="User_Priority" inverse="false"> <key column="userId"></key> <many-to-many class="com.tch.test.ssh.entity.Priority" column="priorityId"></many-to-many> </set> </class> </hibernate-mapping>
Priority.hbm.xml
<?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.tch.test.ssh.entity.Priority" table="priority" catalog="test"> <id name="id" type="java.lang.Integer"> <column name="id" /> <generator class="identity" /> </id> <property name="name" type="java.lang.String"> <column name="name" length="20"> <comment>模块名</comment> </column> </property> <set name="users" table="User_Priority" inverse="true"> <key column="priorityId"></key> <many-to-many class="com.tch.test.ssh.entity.User" column="userId"></many-to-many> </set> </class> </hibernate-mapping>
页面:User.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <%@taglib uri="/struts-tags" prefix="s"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>My JSP 'User.jsp' starting page</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <style type="text/css"> *{ margin:0; padding:0; color:#666; } body{ background-color: #fff; } table{ margin:20px auto; } a{ text-decoration: none; color:red; } tr{ height:35px; cursor:pointer; } #_table2{ margin-top: 20px; } .detail ._mouseover{ background-color:#eee; } input[type='text'],input[type='password']{ height:30px; border:1px solid black; background-color: #fff; } ._eventr{ background-color:#eee; } </style> <script type="text/javascript" src="<%=request.getContextPath()%>/common/js/jquery.min.js"></script> <script type="text/javascript"> $(function(){ $("tbody tr").hover(function(){ $(this).addClass('_mouseover'); },function(){ $(this).removeClass('_mouseover'); }); }); //添加用户 function addUser(){ var f = document.forms[0]; f.action = "addUser.action"; f.submit(); } function deleteUser(id,name){ var result = confirm("确认删除"+name+"?"); if(result){ window.location.href='deleteUser.action?user.id='+id; } } </script> </head> <body> <form action="" method="post"> <table cellpadding="0" cellspacing="0" border="1" width="60%" align="center" class="detail"> <thead> <tr> <th width="15%" align="center">id</th> <th width="15%" align="center">用户名</th> <th width="15%" align="center">密码</th> <th width="15%" align="center">操作</th> </tr> </thead> <tbody> <s:iterator value="users" status="user"> <tr <s:if test="#user.even">class='_eventr'</s:if>> <td width="15%" align="center"><s:property value="id"/></td> <td width="15%" align="center"><s:property value="name"/></td> <td width="15%" align="center"><s:property value="password"/></td> <td width="15%" align="center"> <a href="javascript:window.location.href='goEdit.action?user.id=<s:property value='id'/>'">编辑</a> <a href="javascript:deleteUser(<s:property value='id'/>,'<s:property value='name'/>')">删除</a> </td> </tr> </s:iterator> </tbody> </table> <table cellpadding="0" cellspacing="0" border="0" width="60%" align="center" id="_table2"> <tr> <td colspan="3">用户名:<input type="text" name="user.name">密码:<input type="text" name="user.password"></td> <td><input type="button" onclick="addUser()" value="添加用户"></td> </tr> </table> </form> </body> </html>
editUser.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <%@taglib uri="/struts-tags" prefix="s"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>My JSP 'User.jsp' starting page</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <style type="text/css"> *{ margin:0; padding:0; color:#666; line-height:30px; } #content{ width:500px; margin:30px auto; } input[type='checkbox']{ margin-top: 2px; margin-left: 10px; margin-right: 10px; } input[type='text'],input[type='password']{ height:30px; border:1px solid black; background-color: #fff; } form .priority{ float:left margin-left: 20px; } </style> </head> <body> <div id="content"> <form action="editUser.action" method="post" name="myform"> 用户名:<input type="text" value="<s:property value='user.name'/>" name="user.name"> 密码:<input type="text" value="<s:property value='user.password'/>" name="user.password"><br/> <span class="priority">权限:</span><br/> <input type="checkbox" name="priorityName" value="管理员" <s:if test="'管理员' in priorities.{name}">checked='checked'</s:if>>管理员<br/> <input type="checkbox" name="priorityName" value="程序员"<s:if test="'程序员' in priorities.{name}">checked='checked'</s:if>>程序员<br/> <input type="checkbox" name="priorityName" value="测试员"<s:if test="'测试员' in priorities.{name}">checked='checked'</s:if>>测试员<br/> <input type="checkbox" name="priorityName" value="运维人员"<s:if test="'运维人员' in priorities.{name}">checked='checked'</s:if>>运维人员<br/> <input type="hidden" name="user.id" value="${user.id}"> <input type="submit" value="确认修改"> </form> </div> </body> </html>
log4j.properties:
# # Log4J Settings for log4j 1.2.x (via jakarta-commons-logging) # # The five logging levels used by Log are (in order): # # 1. DEBUG (the least serious) # 2. INFO # 3. WARN # 4. ERROR # 5. FATAL (the most serious) # Set root logger level to WARN and append to stdout log4j.rootLogger=info, stdout log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.Target=System.out log4j.appender.stdout.layout=org.apache.log4j.PatternLayout # Pattern to output the caller's file name and line number. log4j.appender.stdout.layout.ConversionPattern=%d %5p (%c:%L) - %m%n # Print only messages of level ERROR or above in the package noModule. log4j.logger.noModule=FATAL log4j.logger.com.opensymphony.xwork2=info log4j.logger.org.apache.struts2=info
测试类:
package com.tch.test.ssh.test; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.tch.test.ssh.entity.Priority; import com.tch.test.ssh.entity.User; public class SpringTest { @Test public void testHibernate(){ ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); SessionFactory sessionFactory = (SessionFactory)context.getBean("sessionFactory"); Session session = sessionFactory.openSession(); session.beginTransaction(); User u = new User(); u.setId(1); u = (User)session.get(User.class, 1); System.out.println(u.getPriorities()); Priority p = (Priority) session.load(Priority.class, 3); u.getPriorities().add(p); // u.getPriorities().remove(p); // Priority p = new Priority(); // p.setId(3); // u.setPriorities(null); session.update(u); System.out.println(u.getPriorities()); session.getTransaction().commit(); session.close(); } }
完整代码:网盘下载
相关推荐
SSH框架整合教程是Java开发领域中的一个重要主题,它涉及到三个核心的开源框架:Struts、Spring和Hibernate。这些框架在企业级应用开发中扮演着关键角色,分别负责表现层、业务逻辑层和数据持久化层的管理。 Struts...
Java SSH 框架整合是Java开发中常见的一项技术,主要涉及Spring、Struts和Hibernate这三个开源框架。这些框架在企业级应用开发中扮演着重要角色,分别负责控制层、视图层和持久层的管理。下面将详细介绍SSH框架整合...
Spring在SSH整合中主要负责控制反转和事务管理: 1. **IoC容器**:通过XML或注解方式管理对象及其依赖关系,实现依赖注入。 2. **Service层**:定义业务接口和实现,Spring会管理这些对象的生命周期和事务。 3. **...
SSH框架整合是Java Web开发中常见的一种技术栈组合,它由Spring、Struts2和Hibernate三个框架构成。这个"SSH框架整合jar包"是开发者为了方便项目构建,避免手动逐个添加和配置这三个框架所需的库文件而制作的集合。...
SSH框架整合是Java Web开发中常见的一种技术栈组合,它由Spring、Struts2和Hibernate三个框架组成。这些框架分别负责应用的依赖注入(DI)、表现层管理和持久化层操作,为开发者提供了一套高效、灵活的解决方案。...
在SSH整合中,Spring主要负责管理对象的生命周期,处理事务,并集成其他两个框架。 2. **Struts框架**:Struts是一个基于MVC(Model-View-Controller)设计模式的Web应用框架,用于控制应用程序的流程。它将业务...
SSH框架整合图解(3个方案)SSH框架整合图解(3个方案)SSH框架整合图解(3个方案)SSH框架整合图解(3个方案)SSH框架整合图解(3个方案)SSH框架整合图解(3个方案)SSH框架整合图解(3个方案)SSH框架整合图解(3...
SSH框架,全称为Struts2、Spring和Hibernate的组合,是Java Web开发中常见的三大开源框架集成。这个项目源码提供了SSH整合的实践案例,特别适合初学者学习和理解Web应用的开发流程。 Struts2作为MVC(Model-View-...
在SSH整合中,Spring作为核心,协调其他两个框架,并可以处理数据访问、业务逻辑和服务层的集成。 其次,**Struts框架**是MVC(Model-View-Controller)设计模式的一种实现,主要关注于Web层的控制。它接收用户的...
SSH框架是Java开发中常用的...通过学习和实践使用这个SSH框架整合jar包,开发者可以深入理解如何在实际项目中运用这些框架,提高开发效率,同时也可以掌握如何管理和配置依赖库,这对于Java Web开发者的成长至关重要。
ssh框架整合配置文件 ssh框架整合配置文件 ssh框架整合配置文件 ssh框架整合配置文件 ssh框架整合配置文件 ssh框架整合配置文件 ssh框架整合配置文件 ssh框架整合配置文件 ssh框架整合配置文件 ssh框架整合配置文件 ...
SSH框架整合是一个常见的Java Web开发技术栈,由Struts、Spring和Hibernate三个开源框架组成,分别负责表现层、业务逻辑层和数据访问层。在这个实例中,我们将深入探讨这三个框架如何协同工作,实现一个完整的增删改...
SSH框架,全称为Spring、Struts2和Hibernate的集成,是Java Web开发中常见的三大开源框架的组合。这些框架各自负责应用的不同层面:Spring提供IoC(Inversion of Control)和AOP(Aspect-Oriented Programming)功能...
SSH框架整合是Java Web开发中常见的一种技术组合,它由Spring、Struts2和Hibernate三个开源框架构成。Spring提供依赖注入(DI)和面向切面编程(AOP),Struts2作为MVC框架负责控制层,而Hibernate则作为对象关系...
《J2EE SSH框架整合详解》 在Java企业级开发中,SSH(Struts、Spring、Hibernate)框架的整合是常见的技术实践,它能够提供强大的表现层、业务逻辑层和数据持久化层的支持。SSH框架整合的核心在于如何将这三个框架...
SSH框架,全称为Struts2、Spring和Hibernate的组合,是Java Web开发中常见的三大框架。这三大框架分别负责表现层、业务层和持久层的管理,为开发者提供了高效、灵活且可扩展的开发环境。在Java Web项目中,SSH框架的...
SSH框架整合是Java开发中的一个重要话题,主要涉及Spring、Struts和Hibernate这三个开源框架的集成应用。本教程《SSH框架整合实战教程》旨在帮助Java程序员深入理解和熟练掌握这些技术,以便在实际项目开发中实现...