Top
JAVA SPRINGMYBATIS02 UNIT06
- Spring声明式事务-注解应用
- Spring声明式事务-XML配置
- Spring声明式事务-回滚机制
- RESTful应用案例
1 Spring声明式事务-注解应用
1.1 问题
使用Spring注解实现声明式事务,管理Controller中各业务方法的事务。
1.2 方案
Spring事务注解使用步骤:
1.3 步骤
实现此案例需要按照如下步骤进行。
步骤一:测试未管理事务的情况
复制项目SpringUnit05,创建新项目SpringUnit06。
在EmpController中,增加批量添加员工的方法,并模拟实现,代码如下:
- package com.tarena.controller;
-
- import javax.annotation.Resource;
- import org.springframework.stereotype.Controller;
- import org.springframework.transaction.annotation.Transactional;
- import org.springframework.web.bind.annotation.RequestMapping;
- import com.tarena.dao.EmpDao;
- import com.tarena.entity.Emp;
-
- @Controller
- @RequestMapping("/emp")
- public class EmpController {
-
- @Resource
- private EmpDao empDao;
-
-
-
-
- @RequestMapping("/addEmps.do")
- public String addBatch() {
-
- Emp e1 = new Emp();
- e1.setEname("刘备");
- e1.setJob("皇叔");
- e1.setSal(1000.0);
- e1.setEmpno(10);
- empDao.save(e1);
-
-
- Integer.valueOf("abc");
-
-
- Emp e2 = new Emp();
- e2.setEname("关羽");
- e2.setJob("候");
- e2.setSal(1000.0);
- e2.setEmpno(10);
- empDao.save(e2);
-
- return "redirect:findEmp.do";
- }
-
- }
package com.tarena.controller;
import javax.annotation.Resource;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestMapping;
import com.tarena.dao.EmpDao;
import com.tarena.entity.Emp;
@Controller
@RequestMapping("/emp")
public class EmpController {
#cold_bold @Resource
#cold_bold private EmpDao empDao;
//其他方法略
#cold_bold /**
#cold_bold * 模拟批量添加员工
#cold_bold */
#cold_bold @RequestMapping("/addEmps.do")
#cold_bold public String addBatch() {
#cold_bold // 插入第一个员工
#cold_bold Emp e1 = new Emp();
#cold_bold e1.setEname("刘备");
#cold_bold e1.setJob("皇叔");
#cold_bold e1.setSal(1000.0);
#cold_bold e1.setEmpno(10);
#cold_bold empDao.save(e1);
#cold_bold
#cold_bold // 模拟异常
#cold_bold Integer.valueOf("abc"); //ClassCastException
#cold_bold
#cold_bold // 插入第二个员工
#cold_bold Emp e2 = new Emp();
#cold_bold e2.setEname("关羽");
#cold_bold e2.setJob("候");
#cold_bold e2.setSal(1000.0);
#cold_bold e2.setEmpno(10);
#cold_bold empDao.save(e2);
#cold_bold
#cold_bold return "redirect:findEmp.do";
#cold_bold }
}
在TestEmpController中,增加测试方法,测试批量添加员工,代码如下:
- package com.tarena.test;
-
- import org.junit.Test;
- import org.springframework.context.ApplicationContext;
- import org.springframework.context.support.ClassPathXmlApplicationContext;
- import com.tarena.controller.EmpController;
-
- public class TestEmpController {
-
-
-
- @Test
- public void test2() throws ClassNotFoundException {
- ApplicationContext ctx = new ClassPathXmlApplicationContext(
- "applicationContext.xml");
- EmpController ctl = ctx.getBean(EmpController.class);
- ctl.addBatch();
- }
-
- }
package com.tarena.test;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.tarena.controller.EmpController;
public class TestEmpController {
//其他方法略
#cold_bold /**
#cold_bold * 测试批量添加员工
#cold_bold */
#cold_bold @Test
#cold_bold public void test2() throws ClassNotFoundException {
#cold_bold ApplicationContext ctx = new ClassPathXmlApplicationContext(
#cold_bold "applicationContext.xml");
#cold_bold EmpController ctl = ctx.getBean(EmpController.class);
#cold_bold ctl.addBatch();
#cold_bold }
}
没有执行该测试方法前,员工表中的数据如下图:
图-1
执行该测试方法后,员工表中的数据如下图:
图-2
可见,员工刘备添加成功。但EmpController.addBatch()方法是业务方法,体现了完整的业务逻辑,发生异常时应该整个业务失败,而不是一部分成功一部分失败,因此添加刘备成功是不符合要求的,应该引入事务管理机制来解决此问题。
步骤二:声明事务组件
在applicationContext.xml中声明事务组件,关键代码如下:
- <!-- 声明事务管理组件 -->
- <bean id="txManager"
- class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
- <property name="dataSource" ref="ds"/>
- </bean>
#cold_bold <!-- 声明事务管理组件 -->
#cold_bold <bean id="txManager"
#cold_bold class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
#cold_bold <property name="dataSource" ref="ds"/>
#cold_bold </bean>
步骤三:开启事务注解扫描
在applicationContext.xml中,开启事务注解扫描,关键代码如下:
- <!-- 声明事务管理组件 -->
- <bean id="txManager"
- class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
- <property name="dataSource" ref="ds"/>
- </bean>
-
- <!-- 开启事务注解扫描 -->
- <tx:annotation-driven
- transaction-manager="txManager" proxy-target-class="true"/>
<!-- 声明事务管理组件 -->
<bean id="txManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="ds"/>
</bean>
#cold_bold <!-- 开启事务注解扫描 -->
#cold_bold <tx:annotation-driven
#cold_bold transaction-manager="txManager" proxy-target-class="true"/>
步骤四:使用注解标识类/方法
在EmpController中,使用注解对该方法启用事务管理,代码如下:
- package com.tarena.controller;
-
- import javax.annotation.Resource;
- import org.springframework.stereotype.Controller;
- import org.springframework.transaction.annotation.Transactional;
- import org.springframework.web.bind.annotation.RequestMapping;
- import com.tarena.dao.EmpDao;
- import com.tarena.entity.Emp;
-
- @Controller
- @RequestMapping("/emp")
- @Transactional
- public class EmpController {
-
- @Resource
- private EmpDao empDao;
-
-
-
- @RequestMapping("/addEmps.do")
- public String addBatch() {
-
- Emp e1 = new Emp();
- e1.setEname("刘备");
- e1.setJob("皇叔");
- e1.setSal(1000.0);
- e1.setEmpno(10);
- empDao.save(e1);
-
-
- Integer.valueOf("abc");
-
-
- Emp e2 = new Emp();
- e2.setEname("关羽");
- e2.setJob("候");
- e2.setSal(1000.0);
- e2.setEmpno(10);
- empDao.save(e2);
-
- return "redirect:findEmp.do";
- }
-
- }
package com.tarena.controller;
import javax.annotation.Resource;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestMapping;
import com.tarena.dao.EmpDao;
import com.tarena.entity.Emp;
@Controller
@RequestMapping("/emp")
#cold_bold@Transactional
public class EmpController {
@Resource
private EmpDao empDao;
//其他方法略
/**
* 模拟批量添加员工
*/
@RequestMapping("/addEmps.do")
public String addBatch() {
// 插入第一个员工
Emp e1 = new Emp();
e1.setEname("刘备");
e1.setJob("皇叔");
e1.setSal(1000.0);
e1.setEmpno(10);
empDao.save(e1);
// 模拟异常
Integer.valueOf("abc"); //ClassCastException
// 插入第二个员工
Emp e2 = new Emp();
e2.setEname("关羽");
e2.setJob("候");
e2.setSal(1000.0);
e2.setEmpno(10);
empDao.save(e2);
return "redirect:findEmp.do";
}
}
步骤五:测试
手动删除员工表中的刘备,执行测试方法TestEmpController.test2(),然后查询员工表数据如下图:
图-3
可见,在引入了事务管理机制后,业务方法发生异常时,由于事务回滚,所以没有成功插入员工刘备,从而保证了业务的完整性。
1.4 完整代码
本案例的完整代码如下所示:
EmpController完整代码如下:
- package com.tarena.controller;
-
- import javax.annotation.Resource;
- import org.springframework.stereotype.Controller;
- import org.springframework.transaction.annotation.Transactional;
- import org.springframework.web.bind.annotation.RequestMapping;
- import com.tarena.dao.EmpDao;
- import com.tarena.entity.Emp;
-
- @Controller
- @RequestMapping("/emp")
- @Transactional
- public class EmpController {
-
- @Resource
- private EmpDao empDao;
-
-
- @RequestMapping("/findEmp.do")
- @Transactional(readOnly=true)
- public String find() {
-
- System.out.println("查询员工数据,发送至列表页面.");
-
- Integer.valueOf("abc");
- return "emp/emp_list.jsp";
- }
-
-
- @RequestMapping("/addEmps.do")
- public String addBatch() {
-
- Emp e1 = new Emp();
- e1.setEname("刘备");
- e1.setJob("皇叔");
- e1.setSal(1000.0);
- e1.setEmpno(10);
- empDao.save(e1);
-
-
- Integer.valueOf("abc");
-
-
- Emp e2 = new Emp();
- e2.setEname("关羽");
- e2.setJob("候");
- e2.setSal(1000.0);
- e2.setEmpno(10);
- empDao.save(e2);
-
- return "redirect:findEmp.do";
- }
-
- }
package com.tarena.controller;
import javax.annotation.Resource;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestMapping;
import com.tarena.dao.EmpDao;
import com.tarena.entity.Emp;
@Controller
@RequestMapping("/emp")
@Transactional
public class EmpController {
@Resource
private EmpDao empDao;
/**
* 查询员工
*/
@RequestMapping("/findEmp.do")
@Transactional(readOnly=true)
public String find() {
// 模拟查询员工数据
System.out.println("查询员工数据,发送至列表页面.");
// 制造一个异常,便于测试异常通知
Integer.valueOf("abc");
return "emp/emp_list.jsp";
}
/**
* 模拟批量添加员工
*/
@RequestMapping("/addEmps.do")
public String addBatch() {
// 插入第一个员工
Emp e1 = new Emp();
e1.setEname("刘备");
e1.setJob("皇叔");
e1.setSal(1000.0);
e1.setEmpno(10);
empDao.save(e1);
// 模拟异常
Integer.valueOf("abc"); //ClassCastException
// 插入第二个员工
Emp e2 = new Emp();
e2.setEname("关羽");
e2.setJob("候");
e2.setSal(1000.0);
e2.setEmpno(10);
empDao.save(e2);
return "redirect:findEmp.do";
}
}
TestEmpController完整代码如下:
- package com.tarena.test;
-
- import org.junit.Test;
- import org.springframework.context.ApplicationContext;
- import org.springframework.context.support.ClassPathXmlApplicationContext;
- import com.tarena.controller.EmpController;
-
- public class TestEmpController {
-
-
- @Test
- public void test1() {
- ApplicationContext ctx = new ClassPathXmlApplicationContext(
- "applicationContext.xml");
- EmpController ctl = ctx.getBean(EmpController.class);
- ctl.find();
- }
-
-
- @Test
- public void test2() throws ClassNotFoundException {
- ApplicationContext ctx = new ClassPathXmlApplicationContext(
- "applicationContext.xml");
- EmpController ctl = ctx.getBean(EmpController.class);
- ctl.addBatch();
- }
-
- }
package com.tarena.test;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.tarena.controller.EmpController;
public class TestEmpController {
/**
* 测试查询员工
*/
@Test
public void test1() {
ApplicationContext ctx = new ClassPathXmlApplicationContext(
"applicationContext.xml");
EmpController ctl = ctx.getBean(EmpController.class);
ctl.find();
}
/**
* 测试批量添加员工
*/
@Test
public void test2() throws ClassNotFoundException {
ApplicationContext ctx = new ClassPathXmlApplicationContext(
"applicationContext.xml");
EmpController ctl = ctx.getBean(EmpController.class);
ctl.addBatch();
}
}
applicationContext.xml完整代码如下:
- <?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:jdbc="http://www.springframework.org/schema/jdbc"
- xmlns:jee="http://www.springframework.org/schema/jee"
- xmlns:tx="http://www.springframework.org/schema/tx"
- xmlns:aop="http://www.springframework.org/schema/aop"
- xmlns:mvc="http://www.springframework.org/schema/mvc"
- xmlns:jpa="http://www.springframework.org/schema/data/jpa"
- xsi:schemaLocation="
- http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
- http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
- http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd
- http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd
- http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.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/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
- http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd">
-
- <!-- 配置数据源 -->
- <bean id="ds"
- class="org.apache.commons.dbcp.BasicDataSource"
- destroy-method="close">
- <property name="url"
- value="jdbc:oracle:thin:@localhost:1521:xe"/>
- <property name="driverClassName"
- value="oracle.jdbc.OracleDriver"/>
- <property name="username" value="lhh"/>
- <property name="password" value="123456"/>
- </bean>
-
- <!-- 配置SqlSessionFactory -->
- <bean id="sqlSessionFactory"
- class="org.mybatis.spring.SqlSessionFactoryBean">
- <property name="dataSource" ref="ds" />
- <property name="mapperLocations"
- value="classpath:com/tarena/entity/*.xml"/>
- </bean>
-
- <!-- 配置MyBatis注解 -->
- <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
- <property name="basePackage" value="com.tarena.dao" />
- <property name="annotationClass"
- value="com.tarena.annotation.MyBatisRepository"/>
- </bean>
-
- <!-- 开启注解扫描 -->
- <context:component-scan base-package="com.tarena" />
-
- <!-- 支持@RequestMapping请求和Controller映射 -->
- <mvc:annotation-driven />
-
- <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
- <property name="prefix" value="/WEB-INF/"/>
- <property name="suffix" value=".jsp"/>
- </bean>
-
- <!-- 声明方面组件 -->
- <!-- <bean id="operateLogger" class="com.tarena.aspect.OperateLogger"/> -->
-
- <!-- 配置AOP -->
- <!-- <aop:config>
- <aop:aspect ref="operateLogger">
- <aop:before method="log1"
- pointcut="within(com.tarena.controller..*)"/>
- </aop:aspect>
- <aop:aspect ref="operateLogger">
- <aop:around method="log2"
- pointcut="within(com.tarena.controller..*)"/>
- </aop:aspect>
- <aop:aspect ref="operateLogger">
- <aop:after-throwing method="log3" throwing="e"
- pointcut="within(com.tarena.controller..*)"/>
- </aop:aspect>
- </aop:config> -->
-
- <!-- 开启AOP注解扫描 -->
- <aop:aspectj-autoproxy proxy-target-class="true"/>
-
- <!-- 声明事务管理组件 -->
- <bean id="txManager"
- class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
- <property name="dataSource" ref="ds"/>
- </bean>
-
- <!-- 开启事务注解扫描 -->
- <tx:annotation-driven
- transaction-manager="txManager" proxy-target-class="true"/>
-
- </beans>
<?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:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.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/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd">
<!-- 配置数据源 -->
<bean id="ds"
class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="url"
value="jdbc:oracle:thin:@localhost:1521:xe"/>
<property name="driverClassName"
value="oracle.jdbc.OracleDriver"/>
<property name="username" value="lhh"/>
<property name="password" value="123456"/>
</bean>
<!-- 配置SqlSessionFactory -->
<bean id="sqlSessionFactory"
class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="ds" />
<property name="mapperLocations"
value="classpath:com/tarena/entity/*.xml"/>
</bean>
<!-- 配置MyBatis注解 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.tarena.dao" />
<property name="annotationClass"
value="com.tarena.annotation.MyBatisRepository"/>
</bean>
<!-- 开启注解扫描 -->
<context:component-scan base-package="com.tarena" />
<!-- 支持@RequestMapping请求和Controller映射 -->
<mvc:annotation-driven />
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/"/>
<property name="suffix" value=".jsp"/>
</bean>
<!-- 声明方面组件 -->
<!-- <bean id="operateLogger" class="com.tarena.aspect.OperateLogger"/> -->
<!-- 配置AOP -->
<!-- <aop:config>
<aop:aspect ref="operateLogger">
<aop:before method="log1"
pointcut="within(com.tarena.controller..*)"/>
</aop:aspect>
<aop:aspect ref="operateLogger">
<aop:around method="log2"
pointcut="within(com.tarena.controller..*)"/>
</aop:aspect>
<aop:aspect ref="operateLogger">
<aop:after-throwing method="log3" throwing="e"
pointcut="within(com.tarena.controller..*)"/>
</aop:aspect>
</aop:config> -->
<!-- 开启AOP注解扫描 -->
<aop:aspectj-autoproxy proxy-target-class="true"/>
<!-- 声明事务管理组件 -->
<bean id="txManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="ds"/>
</bean>
<!-- 开启事务注解扫描 -->
<tx:annotation-driven
transaction-manager="txManager" proxy-target-class="true"/>
</beans>
2 Spring声明式事务-XML配置
2.1 问题
使用XML配置代替注解,实现Spring声明式事务。
2.2 方案
XML配置声明式事务,关键代码如下:
- <!-- XML配置声明事务范围及类型 -->
- <tx:advice id="txAdvice" transaction-manager="txManager">
- <tx:attributes>
- <tx:method name="find*" read-only="true" />
- <tx:method name="add*" propagation="REQUIRED"
- rollback-for="java.lang.Exception"/>
- <tx:method name="update*" propagation="REQUIRED"
- rollback-for="java.lang.Exception"/>
- <tx:method name="delete*" propagation="REQUIRED"
- rollback-for="java.lang.Exception"/>
- </tx:attributes>
- </tx:advice>
- <aop:config proxy-target-class="true">
- <aop:advisor advice-ref="txAdvice"
- pointcut="within(com.tarena.controller..*)" />
- </aop:config>
<!-- XML配置声明事务范围及类型 -->
<tx:advice id="txAdvice" transaction-manager="txManager">
<tx:attributes>
<tx:method name="find*" read-only="true" />
<tx:method name="add*" propagation="REQUIRED"
rollback-for="java.lang.Exception"/>
<tx:method name="update*" propagation="REQUIRED"
rollback-for="java.lang.Exception"/>
<tx:method name="delete*" propagation="REQUIRED"
rollback-for="java.lang.Exception"/>
</tx:attributes>
</tx:advice>
<aop:config proxy-target-class="true">
<aop:advisor advice-ref="txAdvice"
pointcut="within(com.tarena.controller..*)" />
</aop:config>
2.3 步骤
实现此案例需要按照如下步骤进行。
步骤一:取消事务注解
在applicationContext.xml中,去掉开启事务注解扫描的代码,使事务注解失效,关键代码如下:
- <!-- 开启事务注解扫描 -->
- <!-- <tx:annotation-driven
- transaction-manager="txManager" proxy-target-class="true"/> -->
#cold_bold <!-- 开启事务注解扫描 -->
#cold_bold <!-- <tx:annotation-driven
#cold_bold transaction-manager="txManager" proxy-target-class="true"/> -->
步骤二:使用XML配置声明式事务
在applicationContext.xml中,使用XML配置声明式事务,关键代码如下:
- <!-- XML配置声明事务范围及类型 -->
- <tx:advice id="txAdvice" transaction-manager="txManager">
- <tx:attributes>
- <tx:method name="find*" read-only="true" />
- <tx:method name="add*" propagation="REQUIRED" />
- <tx:method name="update*" propagation="REQUIRED" />
- <tx:method name="delete*" propagation="REQUIRED" />
- </tx:attributes>
- </tx:advice>
- <aop:config proxy-target-class="true">
- <aop:advisor advice-ref="txAdvice"
- pointcut="within(com.tarena.controller..*)" />
- </aop:config>
#cold_bold <!-- XML配置声明事务范围及类型 -->
#cold_bold <tx:advice id="txAdvice" transaction-manager="txManager">
#cold_bold <tx:attributes>
#cold_bold <tx:method name="find*" read-only="true" />
#cold_bold <tx:method name="add*" propagation="REQUIRED" />
#cold_bold <tx:method name="update*" propagation="REQUIRED" />
#cold_bold <tx:method name="delete*" propagation="REQUIRED" />
#cold_bold </tx:attributes>
#cold_bold </tx:advice>
#cold_bold <aop:config proxy-target-class="true">
#cold_bold <aop:advisor advice-ref="txAdvice"
#cold_bold pointcut="within(com.tarena.controller..*)" />
#cold_bold </aop:config>
步骤三:测试
执行测试方法TestEmpController.test2(),然后查询员工表数据如下图:
图-4
可见,XML配置的声明式事务与注解方式效果一样。
2.4 完整代码
本案例的完整代码如下所示:
applicationContext.xml完整代码如下:
3 Spring声明式事务-回滚机制
3.1 问题
默认情况下,声明式事务只能捕获RuntimeException,并使事务回滚,请处理非RuntimeException情况下的事务回滚。
3.2 方案
使用注解实现声明式事务时,按如下方式指定异常:
@Transactional(rollbackFor=ClassNotFoundException.class)
使用XML配置实现声明式事务时,按如下方式指定异常:
<tx:method name="update*" propagation="REQUIRED"
rollback-for="java.lang.ClassNotFoundException"/>
本案例中演示第二种方式。
3.3 步骤
实现此案例需要按照如下步骤进行。
步骤一:测试非RuntimeException异常的情况
修改EmpController.addBatch()方法,将模拟的异常换成非RuntimeException,代码如下:
- package com.tarena.controller;
-
- import javax.annotation.Resource;
- import org.springframework.stereotype.Controller;
- import org.springframework.transaction.annotation.Transactional;
- import org.springframework.web.bind.annotation.RequestMapping;
- import com.tarena.dao.EmpDao;
- import com.tarena.entity.Emp;
-
- @Controller
- @RequestMapping("/emp")
- @Transactional
- public class EmpController {
-
- @Resource
- private EmpDao empDao;
-
-
-
- @RequestMapping("/addEmps.do")
- public String addBatch() throws ClassNotFoundException {
-
- Emp e1 = new Emp();
- e1.setEname("刘备");
- e1.setJob("皇叔");
- e1.setSal(1000.0);
- e1.setEmpno(10);
- empDao.save(e1);
-
-
- Class.forName("BadClass");
-
-
- Emp e2 = new Emp();
- e2.setEname("关羽");
- e2.setJob("候");
- e2.setSal(1000.0);
- e2.setEmpno(10);
- empDao.save(e2);
-
- return "redirect:findEmp.do";
- }
-
- }
package com.tarena.controller;
import javax.annotation.Resource;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestMapping;
import com.tarena.dao.EmpDao;
import com.tarena.entity.Emp;
@Controller
@RequestMapping("/emp")
@Transactional
public class EmpController {
@Resource
private EmpDao empDao;
//其他方法略
/**
* 模拟批量添加员工
*/
@RequestMapping("/addEmps.do")
public String addBatch() throws ClassNotFoundException {
// 插入第一个员工
Emp e1 = new Emp();
e1.setEname("刘备");
e1.setJob("皇叔");
e1.setSal(1000.0);
e1.setEmpno(10);
empDao.save(e1);
// 模拟异常
#cold_bold// Integer.valueOf("abc"); //ClassCastException
#cold_bold Class.forName("BadClass"); //ClassNotFoundException
// 插入第二个员工
Emp e2 = new Emp();
e2.setEname("关羽");
e2.setJob("候");
e2.setSal(1000.0);
e2.setEmpno(10);
empDao.save(e2);
return "redirect:findEmp.do";
}
}
执行测试方法TestEmpController.test2(),然后查询员工表数据如下图:
图-5
可见,对于非RuntimeException异常,默认的声明式事务是处理不了的。
步骤二:注解上指定处理的异常类型
修改applicationContext.xml,在通知配置上指定异常类型,关键代码如下:
- <!-- XML配置声明事务范围及类型 -->
- <tx:advice id="txAdvice" transaction-manager="txManager">
- <tx:attributes>
- <tx:method name="find*" read-only="true" />
- <tx:method name="add*" propagation="REQUIRED"
- rollback-for="java.lang. ClassNotFoundException"/>
- <tx:method name="update*" propagation="REQUIRED" />
- <tx:method name="delete*" propagation="REQUIRED" />
- </tx:attributes>
- </tx:advice>
- <aop:config proxy-target-class="true">
- <aop:advisor advice-ref="txAdvice"
- pointcut="within(com.tarena.controller..*)" />
- </aop:config>
<!-- XML配置声明事务范围及类型 -->
<tx:advice id="txAdvice" transaction-manager="txManager">
<tx:attributes>
<tx:method name="find*" read-only="true" />
#cold_bold <tx:method name="add*" propagation="REQUIRED"
#cold_bold rollback-for="java.lang. ClassNotFoundException"/>
<tx:method name="update*" propagation="REQUIRED" />
<tx:method name="delete*" propagation="REQUIRED" />
</tx:attributes>
</tx:advice>
<aop:config proxy-target-class="true">
<aop:advisor advice-ref="txAdvice"
pointcut="within(com.tarena.controller..*)" />
</aop:config>
步骤三:测试
手动删除员工表中的刘备,执行测试方法TestEmpController.test2(),然后查询员工表数据如下图:
图-6
可见,在注解上指定了要处理的异常类型后,它就可以处理非RuntimeException了。
3.4 完整代码
本案例的完整代码如下所示:
applicationContext.xml完整代码如下:
4 RESTful应用案例
4.1 问题
使用RESTful实现员工模块的增删改查功能。
4.2 方案
在Spring+MyBatis框架基础上实现员工模块的增删改查功能,然后再使用RESTful来重构请求URL。
4.3 步骤
实现此案例需要按照如下步骤进行。
步骤一:实现员工模块增删改查功能
复制项目SpringUnit01,创建新项目SpringRestful,在新项目中完成员工的增删改查功能。
EmpDao代码如下:
- package com.tarena.dao;
-
- import java.util.List;
- import com.tarena.annotation.MyBatisRepository;
- import com.tarena.entity.Emp;
-
- @MyBatisRepository
- public interface EmpDao {
-
- List<Emp> findAll();
-
- void save(Emp emp);
-
- Emp findById(int id);
-
- void update(Emp emp);
-
- void delete(int id);
-
- }
package com.tarena.dao;
import java.util.List;
import com.tarena.annotation.MyBatisRepository;
import com.tarena.entity.Emp;
/**
* 员工表的DAO组件
*/
@MyBatisRepository
public interface EmpDao {
List<Emp> findAll();
void save(Emp emp);
Emp findById(int id);
void update(Emp emp);
void delete(int id);
}
EmpMapper.xml代码如下:
- <?xml version="1.0" encoding="UTF-8" ?>
- <!DOCTYPE mapper PUBLIC "-//ibatis.apache.org//DTD Mapper 3.0//EN"
- "http://ibatis.apache.org/dtd/ibatis-3-mapper.dtd">
-
- <mapper namespace="com.tarena.dao.EmpDao">
-
- <!-- 查询全部的员工 -->
- <select id="findAll"
- resultType="com.tarena.entity.Emp">
- select * from t_emp
- </select>
-
- <!-- 保存一条员工数据 -->
- <insert id="save"
- parameterType="com.tarena.entity.Emp">
- insert into t_emp values(
- emp_seq.nextval,
- #{ename,jdbcType=VARCHAR},
- #{job,jdbcType=VARCHAR},
- #{mgr,jdbcType=NUMERIC},
- #{hiredate,jdbcType=DATE},
- #{sal,jdbcType=NUMERIC},
- #{comm,jdbcType=NUMERIC},
- #{deptno,jdbcType=NUMERIC}
- )
- </insert>
-
- <!-- 根据ID查询员工 -->
- <select id="findById"
- parameterType="java.lang.Integer"
- resultType="com.tarena.entity.Emp">
- select * from t_emp where empno=#{id}
- </select>
-
- <!-- 修改员工 -->
- <update id="update" parameterType="com.tarena.entity.Emp">
- update t_emp set
- ename=#{ename,jdbcType=VARCHAR},
- job=#{job,jdbcType=VARCHAR},
- sal=#{sal,jdbcType=NUMERIC}
- where empno=#{empno,jdbcType=NUMERIC}
- </update>
-
- <!-- 删除员工 -->
- <delete id="delete" parameterType="java.lang.Integer">
- delete from t_emp where empno=#{id}
- </delete>
-
- </mapper>
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//ibatis.apache.org//DTD Mapper 3.0//EN"
"http://ibatis.apache.org/dtd/ibatis-3-mapper.dtd">
<mapper namespace="com.tarena.dao.EmpDao">
<!-- 查询全部的员工 -->
<select id="findAll"
resultType="com.tarena.entity.Emp">
select * from t_emp
</select>
<!-- 保存一条员工数据 -->
<insert id="save"
parameterType="com.tarena.entity.Emp">
insert into t_emp values(
emp_seq.nextval,
#{ename,jdbcType=VARCHAR},
#{job,jdbcType=VARCHAR},
#{mgr,jdbcType=NUMERIC},
#{hiredate,jdbcType=DATE},
#{sal,jdbcType=NUMERIC},
#{comm,jdbcType=NUMERIC},
#{deptno,jdbcType=NUMERIC}
)
</insert>
<!-- 根据ID查询员工 -->
<select id="findById"
parameterType="java.lang.Integer"
resultType="com.tarena.entity.Emp">
select * from t_emp where empno=#{id}
</select>
<!-- 修改员工 -->
<update id="update" parameterType="com.tarena.entity.Emp">
update t_emp set
ename=#{ename,jdbcType=VARCHAR},
job=#{job,jdbcType=VARCHAR},
sal=#{sal,jdbcType=NUMERIC}
where empno=#{empno,jdbcType=NUMERIC}
</update>
<!-- 删除员工 -->
<delete id="delete" parameterType="java.lang.Integer">
delete from t_emp where empno=#{id}
</delete>
</mapper>
EmpController代码如下:
- package com.tarena.controller;
-
- import java.util.List;
- import javax.annotation.Resource;
- import org.springframework.stereotype.Controller;
- import org.springframework.ui.Model;
- import org.springframework.web.bind.annotation.RequestMapping;
- import org.springframework.web.bind.annotation.RequestParam;
- import com.tarena.dao.EmpDao;
- import com.tarena.entity.Emp;
-
- @Controller
- @RequestMapping("/emp")
- public class EmpController {
-
- @Resource
- private EmpDao empDao;
-
- @RequestMapping("/findEmp.do")
- public String find(Model model) {
- List<Emp> list = empDao.findAll();
- model.addAttribute("emps", list);
- return "emp/emp_list";
- }
-
-
- @RequestMapping("/toAddEmp.do")
- public String toAdd() {
- return "emp/add_emp";
- }
-
-
- @RequestMapping("/addEmp.do")
- public String add(Emp emp) {
- empDao.save(emp);
- return "redirect:findEmp.do";
- }
-
-
- @RequestMapping("/toUpdateEmp.do")
- public String toUpdate(
- @RequestParam("id") int id,
- Model model) {
- Emp e = empDao.findById(id);
- model.addAttribute("emp", e);
- return "emp/update_emp";
- }
-
-
- @RequestMapping("/updateEmp.do")
- public String update(Emp emp) {
- empDao.update(emp);
- return "redirect:findEmp.do";
- }
-
-
- @RequestMapping("/deleteEmp.do")
- public String delete(@RequestParam("id") int id) {
- empDao.delete(id);
- return "redirect:findEmp.do";
- }
-
- }
package com.tarena.controller;
import java.util.List;
import javax.annotation.Resource;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import com.tarena.dao.EmpDao;
import com.tarena.entity.Emp;
@Controller
@RequestMapping("/emp")
public class EmpController {
@Resource
private EmpDao empDao;
@RequestMapping("/findEmp.do")
public String find(Model model) {
List<Emp> list = empDao.findAll();
model.addAttribute("emps", list);
return "emp/emp_list";
}
/**
* 打开新增页面
*/
@RequestMapping("/toAddEmp.do")
public String toAdd() {
return "emp/add_emp";
}
/**
* 新增保存
*/
@RequestMapping("/addEmp.do")
public String add(Emp emp) {
empDao.save(emp);
return "redirect:findEmp.do";
}
/**
* 打开修改页面
*/
@RequestMapping("/toUpdateEmp.do")
public String toUpdate(
@RequestParam("id") int id,
Model model) {
Emp e = empDao.findById(id);
model.addAttribute("emp", e);
return "emp/update_emp";
}
/**
* 修改保存
*/
@RequestMapping("/updateEmp.do")
public String update(Emp emp) {
empDao.update(emp);
return "redirect:findEmp.do";
}
/**
* 删除
*/
@RequestMapping("/deleteEmp.do")
public String delete(@RequestParam("id") int id) {
empDao.delete(id);
return "redirect:findEmp.do";
}
}
员工列表页面emp_list.jsp代码如下:
- <%@page pageEncoding="utf-8"%>
- <%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
- <html>
- <head>
- <script type="text/javascript" src="../js/jquery-1.11.1.js"></script>
- <script type="text/javascript">
- function delete_emp(id) {
- var r = window.confirm("确定要删除此数据吗?");
- if(r) {
- location.href = "deleteEmp.do?id="+id;
- }
- }
- </script>
- </head>
- <body>
- <div align="center">
- <input type="button" value="新增" onclick="location.href='toAddEmp.do'"/>
- </div>
- <table width="60%" border="1" cellpadding="2" cellspacing="0" align="center">
- <tr>
- <th>EMPNO</th>
- <th>ENAME</th>
- <th>JOB</th>
- <th>MGR</th>
- <th>HIREDATE</th>
- <th>SAL</th>
- <th>COMM</th>
- <th>DEPTNO</th>
- <th></th>
- </tr>
- <c:forEach items="${emps }" var="emp">
- <tr>
- <td>${emp.empno }</td>
- <td>${emp.ename }</td>
- <td>${emp.job }</td>
- <td>${emp.mgr }</td>
- <td>${emp.hiredate }</td>
- <td>${emp.sal }</td>
- <td>${emp.comm }</td>
- <td>${emp.deptno }</td>
- <td>
- <input type="button" value="修改" onclick="location.href='toUpdateEmp.do?id=${emp.empno }'"/>
- <input type="button" value="删除" onclick="delete_emp(${emp.empno });"/>
- </td>
- </tr>
- </c:forEach>
- </table>
- </body>
- </html>
<%@page pageEncoding="utf-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<html>
<head>
<script type="text/javascript" src="../js/jquery-1.11.1.js"></script>
<script type="text/javascript">
function delete_emp(id) {
var r = window.confirm("确定要删除此数据吗?");
if(r) {
location.href = "deleteEmp.do?id="+id;
}
}
</script>
</head>
<body>
<div align="center">
<input type="button" value="新增" onclick="location.href='toAddEmp.do'"/>
</div>
<table width="60%" border="1" cellpadding="2" cellspacing="0" align="center">
<tr>
<th>EMPNO</th>
<th>ENAME</th>
<th>JOB</th>
<th>MGR</th>
<th>HIREDATE</th>
<th>SAL</th>
<th>COMM</th>
<th>DEPTNO</th>
<th></th>
</tr>
<c:forEach items="${emps }" var="emp">
<tr>
<td>${emp.empno }</td>
<td>${emp.ename }</td>
<td>${emp.job }</td>
<td>${emp.mgr }</td>
<td>${emp.hiredate }</td>
<td>${emp.sal }</td>
<td>${emp.comm }</td>
<td>${emp.deptno }</td>
<td>
<input type="button" value="修改" onclick="location.href='toUpdateEmp.do?id=${emp.empno }'"/>
<input type="button" value="删除" onclick="delete_emp(${emp.empno });"/>
</td>
</tr>
</c:forEach>
</table>
</body>
</html>
员工新增页面add_emp.jsp代码如下:
- <%@page pageEncoding="utf-8"%>
- <%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
- <html>
- <head>
- </head>
- <body>
- <form action="addEmp.do" method="post">
- <table width="40%" border="1" cellpadding="2" cellspacing="0" align="center">
- <tr>
- <td>姓名:</td>
- <td><input type="text" name="ename"/></td>
- </tr>
- <tr>
- <td>岗位:</td>
- <td><input type="text" name="job"/></td>
- </tr>
- <tr>
- <td>工资:</td>
- <td><input type="text" name="sal"/></td>
- </tr>
- <tr>
- <td colspan="2"><input type="submit" value="保存"/></td>
- </tr>
- </table>
- </form>
- </body>
- </html>
<%@page pageEncoding="utf-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<html>
<head>
</head>
<body>
<form action="addEmp.do" method="post">
<table width="40%" border="1" cellpadding="2" cellspacing="0" align="center">
<tr>
<td>姓名:</td>
<td><input type="text" name="ename"/></td>
</tr>
<tr>
<td>岗位:</td>
<td><input type="text" name="job"/></td>
</tr>
<tr>
<td>工资:</td>
<td><input type="text" name="sal"/></td>
</tr>
<tr>
<td colspan="2"><input type="submit" value="保存"/></td>
</tr>
</table>
</form>
</body>
</html>
员工修改页面update_emp.jsp代码如下:
- <%@page pageEncoding="utf-8"%>
- <%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
- <html>
- <head>
- </head>
- <body>
- <form action="updateEmp.do" method="post">
- <table width="40%" border="1" cellpadding="2" cellspacing="0" align="center">
- <tr>
- <td>EMPNO:</td>
- <td><input type="text" name="empno" value="${emp.empno }"/></td>
- </tr>
- <tr>
- <td>姓名:</td>
- <td><input type="text" name="ename" value="${emp.ename }"/></td>
- </tr>
- <tr>
- <td>岗位:</td>
- <td><input type="text" name="job" value="${emp.job }"/></td>
- </tr>
- <tr>
- <td>工资:</td>
- <td><input type="text" name="sal" value="${emp.sal }"/></td>
- </tr>
- <tr>
- <td colspan="2"><input type="submit" value="保存"/></td>
- </tr>
- </table>
- </form>
- </body>
- </html>
<%@page pageEncoding="utf-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<html>
<head>
</head>
<body>
<form action="updateEmp.do" method="post">
<table width="40%" border="1" cellpadding="2" cellspacing="0" align="center">
<tr>
<td>EMPNO:</td>
<td><input type="text" name="empno" value="${emp.empno }"/></td>
</tr>
<tr>
<td>姓名:</td>
<td><input type="text" name="ename" value="${emp.ename }"/></td>
</tr>
<tr>
<td>岗位:</td>
<td><input type="text" name="job" value="${emp.job }"/></td>
</tr>
<tr>
<td>工资:</td>
<td><input type="text" name="sal" value="${emp.sal }"/></td>
</tr>
<tr>
<td colspan="2"><input type="submit" value="保存"/></td>
</tr>
</table>
</form>
</body>
</html>
部署项目并启动tomcat,测试通过员工的增删改查功能。
步骤二:启用RESTful
修改web.xml,将*.do改为/,代码如下:
- <?xml version="1.0" encoding="UTF-8"?>
- <web-app version="2.5"
- xmlns="http://java.sun.com/xml/ns/javaee"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
- http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
- <display-name></display-name>
- <welcome-file-list>
- <welcome-file>index.jsp</welcome-file>
- </welcome-file-list>
-
- <!-- Spring前端控制器 -->
- <servlet>
- <servlet-name>SpringMVC</servlet-name>
- <servlet-class>
- org.springframework.web.servlet.DispatcherServlet
- </servlet-class>
- <init-param>
- <param-name>
- contextConfigLocation
- </param-name>
- <param-value>
- classpath:applicationContext.xml
- </param-value>
- </init-param>
- </servlet>
- <servlet-mapping>
- <servlet-name>SpringMVC</servlet-name>
- <url-pattern>/</url-pattern>
- </servlet-mapping>
- <!-- 使用Filter解决中文乱码问题 -->
- <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>
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<display-name></display-name>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<!-- Spring前端控制器 -->
<servlet>
<servlet-name>SpringMVC</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<init-param>
<param-name>
contextConfigLocation
</param-name>
<param-value>
classpath:applicationContext.xml
</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>SpringMVC</servlet-name>
#cold_bold <url-pattern>/</url-pattern>
</servlet-mapping>
<!-- 使用Filter解决中文乱码问题 -->
<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>
#cold_bold <url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
修改applicationContext.xml,增加支持RESTful访问静态资源的配置,关键代码如下:
- <!-- 支持RESTful访问静态资源 -->
- <mvc:default-servlet-handler />
#cold_bold <!-- 支持RESTful访问静态资源 -->
#cold_bold <mvc:default-servlet-handler />
导入Spring中使用Ajax所需的3个开发包,如下图:
图-7
步骤三:使用RESTful重构Controller
修改EmpController,使用RESTful设计访问URI,代码如下:
- package com.tarena.controller;
-
- import java.util.List;
- import javax.annotation.Resource;
- import org.springframework.stereotype.Controller;
- import org.springframework.ui.Model;
- import org.springframework.web.bind.annotation.PathVariable;
- import org.springframework.web.bind.annotation.RequestBody;
- import org.springframework.web.bind.annotation.RequestMapping;
- import org.springframework.web.bind.annotation.RequestMethod;
- import org.springframework.web.bind.annotation.ResponseBody;
- import com.tarena.dao.EmpDao;
- import com.tarena.entity.Emp;
-
- @Controller
- @RequestMapping("/emp")
- public class EmpController {
-
- @Resource
- private EmpDao empDao;
-
- @RequestMapping(value="/find",method=RequestMethod.GET)
- public String find(Model model) {
- List<Emp> list = empDao.findAll();
- model.addAttribute("emps", list);
- return "emp/emp_list";
- }
-
-
- @RequestMapping(value="/toAdd",method=RequestMethod.GET)
- public String toAdd() {
- return "emp/add_emp";
- }
-
-
- @RequestMapping(value="/add",method=RequestMethod.POST)
- public String add(Emp emp) {
- empDao.save(emp);
- return "redirect:find";
- }
-
-
- @RequestMapping(value="/toUpdate/{id}",method=RequestMethod.GET)
- public String toUpdate(
- @PathVariable("id") int id,
- Model model) {
- Emp e = empDao.findById(id);
- model.addAttribute("emp", e);
- return "emp/update_emp";
- }
-
-
- @RequestMapping(value="/update",method=RequestMethod.PUT)
- @ResponseBody
- public boolean update(@RequestBody Emp emp) {
- empDao.update(emp);
- return true;
- }
-
-
- @RequestMapping(value="/{id}",method=RequestMethod.DELETE)
- @ResponseBody
- public boolean delete(@PathVariable("id") int id) {
- empDao.delete(id);
- return true;
- }
-
- }
package com.tarena.controller;
import java.util.List;
import javax.annotation.Resource;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import com.tarena.dao.EmpDao;
import com.tarena.entity.Emp;
@Controller
@RequestMapping("/emp")
public class EmpController {
@Resource
private EmpDao empDao;
#cold_bold @RequestMapping(value="/find",method=RequestMethod.GET)
public String find(Model model) {
List<Emp> list = empDao.findAll();
model.addAttribute("emps", list);
return "emp/emp_list";
}
/**
* 打开新增页面
*/
#cold_bold @RequestMapping(value="/toAdd",method=RequestMethod.GET)
public String toAdd() {
return "emp/add_emp";
}
/**
* 新增保存
*/
#cold_bold @RequestMapping(value="/add",method=RequestMethod.POST)
public String add(Emp emp) {
empDao.save(emp);
#cold_bold return "redirect:find";
}
/**
* 打开修改页面
*/
#cold_bold @RequestMapping(value="/toUpdate/{id}",method=RequestMethod.GET)
public String toUpdate(
#cold_bold @PathVariable("id") int id,
Model model) {
Emp e = empDao.findById(id);
model.addAttribute("emp", e);
return "emp/update_emp";
}
/**
* 修改保存
*/
#cold_bold @RequestMapping(value="/update",method=RequestMethod.PUT)
#cold_bold @ResponseBody
#cold_bold public boolean update(@RequestBody Emp emp) {
#cold_bold empDao.update(emp);
#cold_bold return true;
#cold_bold }
/**
* 删除
*/
#cold_bold @RequestMapping(value="/{id}",method=RequestMethod.DELETE)
#cold_bold @ResponseBody
#cold_bold public boolean delete(@PathVariable("id") int id) {
#cold_bold empDao.delete(id);
#cold_bold return true;
#cold_bold }
}
步骤四:修改页面发请求的方式
在WebRoot/js文件夹下创建json.js,用于将表单数据转换成json对象,代码如下:
- $.fn.serializeObject = function() {
- var o = {};
- var a = this.serializeArray();
- $.each(a, function() {
- if (o[this.name]) {
- if (!o[this.name].push) {
- o[this.name] = [o[this.name]];
- }
- o[this.name].push(this.value || '');
- } else {
- o[this.name] = this.value || '';
- }
- });
- return o;
- };
// 将表单数据转换成json对象
$.fn.serializeObject = function() {
var o = {};
var a = this.serializeArray();
$.each(a, function() {
if (o[this.name]) {
if (!o[this.name].push) {
o[this.name] = [o[this.name]];
}
o[this.name].push(this.value || '');
} else {
o[this.name] = this.value || '';
}
});
return o;
};
在emp_list.jsp中,对新增、修改按钮的URL进行修改,并将删除按钮改为RESTful的删除提交方式,代码如下:
- <%@page pageEncoding="utf-8"%>
- <%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
- <html>
- <head>
- <script type="text/javascript" src="../js/jquery-1.11.1.js"></script>
- <script type="text/javascript">
- function delete_emp(id) {
- var r = window.confirm("确定要删除此数据吗?");
- if(r) {
-
- $.ajax({
- type:"DELETE",
- url:"/SpringRestful/emp/"+id,
- dataType:"json",
- success:function(data){
- location.href = "/SpringRestful/emp/find";
- }
- });
- }
- }
- </script>
- </head>
- <body>
- <div align="center">
- <input type="button" value="新增" onclick="location.href='toAdd'"/>
- </div>
- <table width="60%" border="1" cellpadding="2" cellspacing="0" align="center">
- <tr>
- <th>EMPNO</th>
- <th>ENAME</th>
- <th>JOB</th>
- <th>MGR</th>
- <th>HIREDATE</th>
- <th>SAL</th>
- <th>COMM</th>
- <th>DEPTNO</th>
- <th></th>
- </tr>
- <c:forEach items="${emps }" var="emp">
- <tr>
- <td>${emp.empno }</td>
- <td>${emp.ename }</td>
- <td>${emp.job }</td>
- <td>${emp.mgr }</td>
- <td>${emp.hiredate }</td>
- <td>${emp.sal }</td>
- <td>${emp.comm }</td>
- <td>${emp.deptno }</td>
- <td>
- <input type="button" value="修改" onclick="location.href='toUpdate/${emp.empno }'"/>
- <input type="button" value="删除" onclick="delete_emp(${emp.empno });"/>
- </td>
- </tr>
- </c:forEach>
- </table>
- </body>
- </html>
<%@page pageEncoding="utf-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<html>
<head>
<script type="text/javascript" src="../js/jquery-1.11.1.js"></script>
<script type="text/javascript">
function delete_emp(id) {
var r = window.confirm("确定要删除此数据吗?");
if(r) {
#cold_bold //location.href = "deleteEmp.do?id="+id;
#cold_bold $.ajax({
#cold_bold type:"DELETE",
#cold_bold url:"/SpringRestful/emp/"+id,
#cold_bold dataType:"json",
#cold_bold success:function(data){
#cold_bold location.href = "/SpringRestful/emp/find";
#cold_bold }
#cold_bold });
}
}
</script>
</head>
<body>
<div align="center">
#cold_bold <input type="button" value="新增" onclick="location.href='toAdd'"/>
</div>
<table width="60%" border="1" cellpadding="2" cellspacing="0" align="center">
<tr>
<th>EMPNO</th>
<th>ENAME</th>
<th>JOB</th>
<th>MGR</th>
<th>HIREDATE</th>
<th>SAL</th>
<th>COMM</th>
<th>DEPTNO</th>
<th></th>
</tr>
<c:forEach items="${emps }" var="emp">
<tr>
<td>${emp.empno }</td>
<td>${emp.ename }</td>
<td>${emp.job }</td>
<td>${emp.mgr }</td>
<td>${emp.hiredate }</td>
<td>${emp.sal }</td>
<td>${emp.comm }</td>
<td>${emp.deptno }</td>
<td>
#cold_bold <input type="button" value="修改" onclick="location.href='toUpdate/${emp.empno }'"/>
#cold_bold <input type="button" value="删除" onclick="delete_emp(${emp.empno });"/>
</td>
</tr>
</c:forEach>
</table>
</body>
</html>
修改add_emp.jsp表单的提交路径,代码如下:
- <%@page pageEncoding="utf-8"%>
- <%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
- <html>
- <head>
- </head>
- <body>
- <form action="add" method="post">
- <table width="40%" border="1" cellpadding="2" cellspacing="0" align="center">
- <tr>
- <td>姓名:</td>
- <td><input type="text" name="ename"/></td>
- </tr>
- <tr>
- <td>岗位:</td>
- <td><input type="text" name="job"/></td>
- </tr>
- <tr>
- <td>工资:</td>
- <td><input type="text" name="sal"/></td>
- </tr>
- <tr>
- <td colspan="2"><input type="submit" value="保存" /></td>
- </tr>
- </table>
- </form>
- </body>
- </html>
<%@page pageEncoding="utf-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<html>
<head>
</head>
<body>
#cold_bold <form action="add" method="post">
<table width="40%" border="1" cellpadding="2" cellspacing="0" align="center">
<tr>
<td>姓名:</td>
<td><input type="text" name="ename"/></td>
</tr>
<tr>
<td>岗位:</td>
<td><input type="text" name="job"/></td>
</tr>
<tr>
<td>工资:</td>
<td><input type="text" name="sal"/></td>
</tr>
<tr>
<td colspan="2"><input type="submit" value="保存" /></td>
</tr>
</table>
</form>
</body>
</html>
修改update_emp.jsp中表单提交的方式和路径,代码如下:
- <%@page pageEncoding="utf-8"%>
- <%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
- <html>
- <head>
- <script type="text/javascript" src="../../js/jquery-1.11.1.js"></script>
- <script type="text/javascript" src="../../js/json.js"></script>
- <script type="text/javascript">
- function save() {
- $.ajax({
- type:"PUT",
- url:"/SpringRestful/emp/update",
- data:JSON.stringify($("#myform").serializeObject()),
- dataType:"json",
- contentType:"application/json",
- success:function(data){
- location.href = "/SpringRestful/emp/find";
- }
- });
- }
- </script>
- </head>
- <body>
- <form action="updateEmp.do" method="post" id="myform">
- <table width="40%" border="1" cellpadding="2" cellspacing="0" align="center">
- <tr>
- <td>EMPNO:</td>
- <td><input type="text" name="empno" value="${emp.empno }"/></td>
- </tr>
- <tr>
- <td>姓名:</td>
- <td><input type="text" name="ename" value="${emp.ename }"/></td>
- </tr>
- <tr>
- <td>岗位:</td>
- <td><input type="text" name="job" value="${emp.job }"/></td>
- </tr>
- <tr>
- <td>工资:</td>
- <td><input type="text" name="sal" value="${emp.sal }"/></td>
- </tr>
- <tr>
- <td colspan="2"><input type="button" value="保存" onclick="save();"/></td>
- </tr>
- </table>
- </form>
- </body>
- </html>
<%@page pageEncoding="utf-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<html>
<head>
#cold_bold <script type="text/javascript" src="../../js/jquery-1.11.1.js"></script>
#cold_bold <script type="text/javascript" src="../../js/json.js"></script>
#cold_bold <script type="text/javascript">
#cold_bold function save() {
#cold_bold $.ajax({
#cold_bold type:"PUT",
#cold_bold url:"/SpringRestful/emp/update",
#cold_bold data:JSON.stringify($("#myform").serializeObject()),
#cold_bold dataType:"json",
#cold_bold contentType:"application/json",
#cold_bold success:function(data){
#cold_bold location.href = "/SpringRestful/emp/find";
#cold_bold }
#cold_bold });
#cold_bold }
#cold_bold </script>
</head>
<body>
<form action="updateEmp.do" method="post" id="myform">
<table width="40%" border="1" cellpadding="2" cellspacing="0" align="center">
<tr>
<td>EMPNO:</td>
<td><input type="text" name="empno" value="${emp.empno }"/></td>
</tr>
<tr>
<td>姓名:</td>
<td><input type="text" name="ename" value="${emp.ename }"/></td>
</tr>
<tr>
<td>岗位:</td>
<td><input type="text" name="job" value="${emp.job }"/></td>
</tr>
<tr>
<td>工资:</td>
<td><input type="text" name="sal" value="${emp.sal }"/></td>
</tr>
<tr>
#cold_bold <td colspan="2"><input type="button" value="保存" onclick="save();"/></td>
</tr>
</table>
</form>
</body>
</html>
步骤五:测试
重新部署并启动tomcat,测试通过员工的增删改查功能。
4.4 完整代码
本案例的完整代码如下所示:
EmpDao完整代码如下:
- package com.tarena.dao;
-
- import java.util.List;
- import com.tarena.annotation.MyBatisRepository;
- import com.tarena.entity.Emp;
-
- @MyBatisRepository
- public interface EmpDao {
-
- List<Emp> findAll();
-
- void save(Emp emp);
-
- Emp findById(int id);
-
- void update(Emp emp);
-
- void delete(int id);
-
- }
package com.tarena.dao;
import java.util.List;
import com.tarena.annotation.MyBatisRepository;
import com.tarena.entity.Emp;
/**
* 员工表的DAO组件
*/
@MyBatisRepository
public interface EmpDao {
List<Emp> findAll();
void save(Emp emp);
Emp findById(int id);
void update(Emp emp);
void delete(int id);
}
EmpMapper.xml完整代码如下:
- <?xml version="1.0" encoding="UTF-8" ?>
- <!DOCTYPE mapper PUBLIC "-//ibatis.apache.org//DTD Mapper 3.0//EN"
- "http://ibatis.apache.org/dtd/ibatis-3-mapper.dtd">
-
- <mapper namespace="com.tarena.dao.EmpDao">
-
- <!-- 查询全部的员工 -->
- <select id="findAll"
- resultType="com.tarena.entity.Emp">
- select * from t_emp
- </select>
-
- <!-- 保存一条员工数据 -->
- <insert id="save"
- parameterType="com.tarena.entity.Emp">
- insert into t_emp values(
- emp_seq.nextval,
- #{ename,jdbcType=VARCHAR},
- #{job,jdbcType=VARCHAR},
- #{mgr,jdbcType=NUMERIC},
- #{hiredate,jdbcType=DATE},
- #{sal,jdbcType=NUMERIC},
- #{comm,jdbcType=NUMERIC},
- #{deptno,jdbcType=NUMERIC}
- )
- </insert>
-
- <!-- 根据ID查询员工 -->
- <select id="findById"
- parameterType="java.lang.Integer"
- resultType="com.tarena.entity.Emp">
- select * from t_emp where empno=#{id}
- </select>
-
- <!-- 修改员工 -->
- <update id="update" parameterType="com.tarena.entity.Emp">
- update t_emp set
- ename=#{ename,jdbcType=VARCHAR},
- job=#{job,jdbcType=VARCHAR},
- sal=#{sal,jdbcType=NUMERIC}
- where empno=#{empno,jdbcType=NUMERIC}
- </update>
-
- <!-- 删除员工 -->
- <delete id="delete" parameterType="java.lang.Integer">
- delete from t_emp where empno=#{id}
- </delete>
-
- </mapper>
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//ibatis.apache.org//DTD Mapper 3.0//EN"
"http://ibatis.apache.org/dtd/ibatis-3-mapper.dtd">
<mapper namespace="com.tarena.dao.EmpDao">
<!-- 查询全部的员工 -->
<select id="findAll"
resultType="com.tarena.entity.Emp">
select * from t_emp
</select>
<!-- 保存一条员工数据 -->
<insert id="save"
parameterType="com.tarena.entity.Emp">
insert into t_emp values(
emp_seq.nextval,
#{ename,jdbcType=VARCHAR},
#{job,jdbcType=VARCHAR},
#{mgr,jdbcType=NUMERIC},
#{hiredate,jdbcType=DATE},
#{sal,jdbcType=NUMERIC},
#{comm,jdbcType=NUMERIC},
#{deptno,jdbcType=NUMERIC}
)
</insert>
<!-- 根据ID查询员工 -->
<select id="findById"
parameterType="java.lang.Integer"
resultType="com.tarena.entity.Emp">
select * from t_emp where empno=#{id}
</select>
<!-- 修改员工 -->
<update id="update" parameterType="com.tarena.entity.Emp">
update t_emp set
ename=#{ename,jdbcType=VARCHAR},
job=#{job,jdbcType=VARCHAR},
sal=#{sal,jdbcType=NUMERIC}
where empno=#{empno,jdbcType=NUMERIC}
</update>
<!-- 删除员工 -->
<delete id="delete" parameterType="java.lang.Integer">
delete from t_emp where empno=#{id}
</delete>
</mapper>
web.xml完整代码如下:
- <?xml version="1.0" encoding="UTF-8"?>
- <web-app version="2.5"
- xmlns="http://java.sun.com/xml/ns/javaee"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
- http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
- <display-name></display-name>
- <welcome-file-list>
- <welcome-file>index.jsp</welcome-file>
- </welcome-file-list>
-
- <!-- Spring前端控制器 -->
- <servlet>
- <servlet-name>SpringMVC</servlet-name>
- <servlet-class>
- org.springframework.web.servlet.DispatcherServlet
- </servlet-class>
- <init-param>
- <param-name>
- contextConfigLocation
- </param-name>
- <param-value>
- classpath:applicationContext.xml
- </param-value>
- </init-param>
- </servlet>
- <servlet-mapping>
- <servlet-name>SpringMVC</servlet-name>
- <url-pattern>/</url-pattern>
- </servlet-mapping>
- <!-- 使用Filter解决中文乱码问题 -->
- <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>
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<display-name></display-name>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<!-- Spring前端控制器 -->
<servlet>
<servlet-name>SpringMVC</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<init-param>
<param-name>
contextConfigLocation
</param-name>
<param-value>
classpath:applicationContext.xml
</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>SpringMVC</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!-- 使用Filter解决中文乱码问题 -->
<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>
</web-app>
applicationContext.xml完整代码如下:
- <?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:jdbc="http://www.springframework.org/schema/jdbc"
- xmlns:jee="http://www.springframework.org/schema/jee"
- xmlns:tx="http://www.springframework.org/schema/tx"
- xmlns:aop="http://www.springframework.org/schema/aop"
- xmlns:mvc="http://www.springframework.org/schema/mvc"
- xmlns:jpa="http://www.springframework.org/schema/data/jpa"
- xsi:schemaLocation="
- http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
- http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
- http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd
- http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd
- http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.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/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
- http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd">
-
- <!-- 配置数据源 -->
- <bean id="ds" class="org.apache.commons.dbcp.BasicDataSource">
- <property name="url" value="jdbc:oracle:thin:@localhost:1521:xe" />
- <property name="driverClassName" value="oracle.jdbc.OracleDriver" />
- <property name="username" value="lhh" />
- <property name="password" value="123456" />
- </bean>
-
- <!-- 配置SqlSessionFactory -->
- <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
- <property name="dataSource" ref="ds" />
- <property name="mapperLocations" value="classpath:com/tarena/entity/*.xml" />
- </bean>
-
- <!-- 配置MyBatis注解 -->
- <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
- <property name="basePackage" value="com.tarena.dao" />
- <property name="annotationClass" value="com.tarena.annotation.MyBatisRepository" />
- </bean>
-
- <!-- 开启注解扫描 -->
- <context:component-scan base-package="com.tarena" />
-
- <!-- 开启RequestMapping注解 -->
- <mvc:annotation-driven />
-
- <!-- 处理请求转发 -->
- <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
- <property name="prefix" value="/WEB-INF/"/>
- <property name="suffix" value=".jsp"/>
- </bean>
-
- <!-- 支持RESTful访问静态资源 -->
- <mvc:default-servlet-handler />
-
- </beans>
<?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:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.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/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd">
<!-- 配置数据源 -->
<bean id="ds" class="org.apache.commons.dbcp.BasicDataSource">
<property name="url" value="jdbc:oracle:thin:@localhost:1521:xe" />
<property name="driverClassName" value="oracle.jdbc.OracleDriver" />
<property name="username" value="lhh" />
<property name="password" value="123456" />
</bean>
<!-- 配置SqlSessionFactory -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="ds" />
<property name="mapperLocations" value="classpath:com/tarena/entity/*.xml" />
</bean>
<!-- 配置MyBatis注解 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.tarena.dao" />
<property name="annotationClass" value="com.tarena.annotation.MyBatisRepository" />
</bean>
<!-- 开启注解扫描 -->
<context:component-scan base-package="com.tarena" />
<!-- 开启RequestMapping注解 -->
<mvc:annotation-driven />
<!-- 处理请求转发 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/"/>
<property name="suffix" value=".jsp"/>
</bean>
<!-- 支持RESTful访问静态资源 -->
<mvc:default-servlet-handler />
</beans>
EmpController完整代码如下:
- package com.tarena.controller;
-
- import java.util.List;
- import javax.annotation.Resource;
- import org.springframework.stereotype.Controller;
- import org.springframework.ui.Model;
- import org.springframework.web.bind.annotation.PathVariable;
- import org.springframework.web.bind.annotation.RequestBody;
- import org.springframework.web.bind.annotation.RequestMapping;
- import org.springframework.web.bind.annotation.RequestMethod;
- import org.springframework.web.bind.annotation.ResponseBody;
- import com.tarena.dao.EmpDao;
- import com.tarena.entity.Emp;
-
- @Controller
- @RequestMapping("/emp")
- public class EmpController {
-
- @Resource
- private EmpDao empDao;
-
- @RequestMapping(value="/find",method=RequestMethod.GET)
- public String find(Model model) {
- List<Emp> list = empDao.findAll();
- model.addAttribute("emps", list);
- return "emp/emp_list";
- }
-
-
- @RequestMapping(value="/toAdd",method=RequestMethod.GET)
- public String toAdd() {
- return "emp/add_emp";
- }
-
-
- @RequestMapping(value="/add",method=RequestMethod.POST)
- public String add(Emp emp) {
- empDao.save(emp);
- return "redirect:find";
- }
-
-
- @RequestMapping(value="/toUpdate/{id}",method=RequestMethod.GET)
- public String toUpdate(
- @PathVariable("id") int id,
- Model model) {
- Emp e = empDao.findById(id);
- model.addAttribute("emp", e);
- return "emp/update_emp";
- }
-
-
- @RequestMapping(value="/update",method=RequestMethod.PUT)
- @ResponseBody
- public boolean update(@RequestBody Emp emp) {
- empDao.update(emp);
- return true;
- }
-
-
- @RequestMapping(value="/{id}",method=RequestMethod.DELETE)
- @ResponseBody
- public boolean delete(@PathVariable("id") int id) {
- empDao.delete(id);
- return true;
- }
-
- }
package com.tarena.controller;
import java.util.List;
import javax.annotation.Resource;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import com.tarena.dao.EmpDao;
import com.tarena.entity.Emp;
@Controller
@RequestMapping("/emp")
public class EmpController {
@Resource
private EmpDao empDao;
@RequestMapping(value="/find",method=RequestMethod.GET)
public String find(Model model) {
List<Emp> list = empDao.findAll();
model.addAttribute("emps", list);
return "emp/emp_list";
}
/**
* 打开新增页面
*/
@RequestMapping(value="/toAdd",method=RequestMethod.GET)
public String toAdd() {
return "emp/add_emp";
}
/**
* 新增保存
*/
@RequestMapping(value="/add",method=RequestMethod.POST)
public String add(Emp emp) {
empDao.save(emp);
return "redirect:find";
}
/**
* 打开修改页面
*/
@RequestMapping(value="/toUpdate/{id}",method=RequestMethod.GET)
public String toUpdate(
@PathVariable("id") int id,
Model model) {
Emp e = empDao.findById(id);
model.addAttribute("emp", e);
return "emp/update_emp";
}
/**
* 修改保存
*/
@RequestMapping(value="/update",method=RequestMethod.PUT)
@ResponseBody
public boolean update(@RequestBody Emp emp) {
empDao.update(emp);
return true;
}
/**
* 删除
*/
@RequestMapping(value="/{id}",method=RequestMethod.DELETE)
@ResponseBody
public boolean delete(@PathVariable("id") int id) {
empDao.delete(id);
return true;
}
}
json.js完整代码如下:
- $.fn.serializeObject = function() {
- var o = {};
- var a = this.serializeArray();
- $.each(a, function() {
- if (o[this.name]) {
- if (!o[this.name].push) {
- o[this.name] = [o[this.name]];
- }
- o[this.name].push(this.value || '');
- } else {
- o[this.name] = this.value || '';
- }
- });
- return o;
- };
// 将表单数据转换成json对象
$.fn.serializeObject = function() {
var o = {};
var a = this.serializeArray();
$.each(a, function() {
if (o[this.name]) {
if (!o[this.name].push) {
o[this.name] = [o[this.name]];
}
o[this.name].push(this.value || '');
} else {
o[this.name] = this.value || '';
}
});
return o;
};
emp_list.jsp完整代码如下:
- <%@page pageEncoding="utf-8"%>
- <%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
- <html>
- <head>
- <script type="text/javascript" src="../js/jquery-1.11.1.js"></script>
- <script type="text/javascript">
- function delete_emp(id) {
- var r = window.confirm("确定要删除此数据吗?");
- if(r) {
-
- $.ajax({
- type:"DELETE",
- url:"/SpringRestful/emp/"+id,
- dataType:"json",
- success:function(data){
- location.href = "/SpringRestful/emp/find";
- }
- });
- }
- }
- </script>
- </head>
- <body>
- <div align="center">
- <input type="button" value="新增" onclick="location.href='toAdd'"/>
- </div>
- <table width="60%" border="1" cellpadding="2" cellspacing="0" align="center">
- <tr>
- <th>EMPNO</th>
- <th>ENAME</th>
- <th>JOB</th>
- <th>MGR</th>
- <th>HIREDATE</th>
- <th>SAL</th>
- <th>COMM</th>
- <th>DEPTNO</th>
- <th></th>
- </tr>
- <c:forEach items="${emps }" var="emp">
- <tr>
- <td>${emp.empno }</td>
- <td>${emp.ename }</td>
- <td>${emp.job }</td>
- <td>${emp.mgr }</td>
- <td>${emp.hiredate }</td>
- <td>${emp.sal }</td>
- <td>${emp.comm }</td>
- <td>${emp.deptno }</td>
- <td>
- <input type="button" value="修改" onclick="location.href='toUpdate/${emp.empno }'"/>
- <input type="button" value="删除" onclick="delete_emp(${emp.empno });"/>
- </td>
- </tr>
- </c:forEach>
- </table>
- </body>
- </html>
<%@page pageEncoding="utf-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<html>
<head>
<script type="text/javascript" src="../js/jquery-1.11.1.js"></script>
<script type="text/javascript">
function delete_emp(id) {
var r = window.confirm("确定要删除此数据吗?");
if(r) {
//location.href = "deleteEmp.do?id="+id;
$.ajax({
type:"DELETE",
url:"/SpringRestful/emp/"+id,
dataType:"json",
success:function(data){
location.href = "/SpringRestful/emp/find";
}
});
}
}
</script>
</head>
<body>
<div align="center">
<input type="button" value="新增" onclick="location.href='toAdd'"/>
</div>
<table width="60%" border="1" cellpadding="2" cellspacing="0" align="center">
<tr>
<th>EMPNO</th>
<th>ENAME</th>
<th>JOB</th>
<th>MGR</th>
<th>HIREDATE</th>
<th>SAL</th>
<th>COMM</th>
<th>DEPTNO</th>
<th></th>
</tr>
<c:forEach items="${emps }" var="emp">
<tr>
<td>${emp.empno }</td>
<td>${emp.ename }</td>
<td>${emp.job }</td>
<td>${emp.mgr }</td>
<td>${emp.hiredate }</td>
<td>${emp.sal }</td>
<td>${emp.comm }</td>
<td>${emp.deptno }</td>
<td>
<input type="button" value="修改" onclick="location.href='toUpdate/${emp.empno }'"/>
<input type="button" value="删除" onclick="delete_emp(${emp.empno });"/>
</td>
</tr>
</c:forEach>
</table>
</body>
</html>
add_emp.jsp完整代码如下:
- <%@page pageEncoding="utf-8"%>
- <%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
- <html>
- <head>
- </head>
- <body>
- <form action="add" method="post">
- <table width="40%" border="1" cellpadding="2" cellspacing="0" align="center">
- <tr>
- <td>姓名:</td>
- <td><input type="text" name="ename"/></td>
- </tr>
- <tr>
- <td>岗位:</td>
- <td><input type="text" name="job"/></td>
- </tr>
- <tr>
- <td>工资:</td>
- <td><input type="text" name="sal"/></td>
- </tr>
- <tr>
- <td colspan="2"><input type="submit" value="保存" /></td>
- </tr>
- </table>
- </form>
- </body>
- </html>
<%@page pageEncoding="utf-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<html>
<head>
</head>
<body>
<form action="add" method="post">
<table width="40%" border="1" cellpadding="2" cellspacing="0" align="center">
<tr>
<td>姓名:</td>
<td><input type="text" name="ename"/></td>
</tr>
<tr>
<td>岗位:</td>
<td><input type="text" name="job"/></td>
</tr>
<tr>
<td>工资:</td>
<td><input type="text" name="sal"/></td>
</tr>
<tr>
<td colspan="2"><input type="submit" value="保存" /></td>
</tr>
</table>
</form>
</body>
</html>
update_emp.jsp完整代码如下:
- <%@page pageEncoding="utf-8"%>
- <%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
- <html>
- <head>
- <script type="text/javascript" src="../../js/jquery-1.11.1.js"></script>
- <script type="text/javascript" src="../../js/json.js"></script>
- <script type="text/javascript">
- function save() {
- $.ajax({
- type:"PUT",
- url:"/SpringRestful/emp/update",
- data:JSON.stringify($("#myform").serializeObject()),
- dataType:"json",
- contentType:"application/json",
- success:function(data){
- location.href = "/SpringRestful/emp/find";
- }
- });
- }
- </script>
- </head>
- <body>
- <form action="updateEmp.do" method="post" id="myform">
- <table width="40%" border="1" cellpadding="2" cellspacing="0" align="center">
- <tr>
- <td>EMPNO:</td>
- <td><input type="text" name="empno" value="${emp.empno }"/></td>
- </tr>
- <tr>
- <td>姓名:</td>
- <td><input type="text" name="ename" value="${emp.ename }"/></td>
- </tr>
- <tr>
- <td>岗位:</td>
- <td><input type="text" name="job" value="${emp.job }"/></td>
- </tr>
- <tr>
- <td>工资:</td>
- <td><input type="text" name="sal" value="${emp.sal }"/></td>
- </tr>
- <tr>
- <td colspan="2"><input type="button" value="保存" onclick="save();"/></td>
- </tr>
- </table>
- </form>
- </body>
- </html>
<%@page pageEncoding="utf-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<html>
<head>
<script type="text/javascript" src="../../js/jquery-1.11.1.js"></script>
<script type="text/javascript" src="../../js/json.js"></script>
<script type="text/javascript">
function save() {
$.ajax({
type:"PUT",
url:"/SpringRestful/emp/update",
data:JSON.stringify($("#myform").serializeObject()),
dataType:"json",
contentType:"application/json",
success:function(data){
location.href = "/SpringRestful/emp/find";
}
});
}
</script>
</head>
<body>
<form action="updateEmp.do" method="post" id="myform">
<table width="40%" border="1" cellpadding="2" cellspacing="0" align="center">
<tr>
<td>EMPNO:</td>
<td><input type="text" name="empno" value="${emp.empno }"/></td>
</tr>
<tr>
<td>姓名:</td>
<td><input type="text" name="ename" value="${emp.ename }"/></td>
</tr>
<tr>
<td>岗位:</td>
<td><input type="text" name="job" value="${emp.job }"/></td>
</tr>
<tr>
<td>工资:</td>
<td><input type="text" name="sal" value="${emp.sal }"/></td>
</tr>
<tr>
<td colspan="2"><input type="button" value="保存" onclick="save();"/></td>
</tr>
</table>
</form>
</body>
</html>