摘要 对于现在主流的j2ee企业级开发而言,ssh(struts+hibernate+spring)依然是一个事实的标准。由struts充当的mvc调度控制;hibernate的orm持久化映射;spring的ioc和aop的容器环境近乎于完美的框架组合。但是,在实际的开发工作中,由于程序猿对于技术、以及更加快速的解决方案的追求,我们会越来越发现ssh框架所存在的诸多问题和困扰。
基于REST风格的Spring3 MVC资源映射编程模型,编写的Code真的很优雅。那是相当的惊喜,编程之美。
MyEclipse项目清单
清单1. web.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
|
<? 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 >mySpring3 and myBatis3 Project</ display-name > <!-- 配置文件位置,默认为/WEB-INF/applicationContext.xml --> < context-param > < param-name >contextConfigLocation</ param-name > < param-value >classpath:applicationContext.xml</ param-value > </ context-param > <!-- 字符集过滤器 --> < filter > < filter-name >characterEncodingFilter</ 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 >characterEncodingFilter</ filter-name > < url-pattern >/*</ url-pattern > </ filter-mapping > <!-- 上下文Spring监听器 --> < listener > < listener-class >org.springframework.web.context.ContextLoaderListener</ listener-class > </ listener > <!-- servlet控制跳转 --> < servlet > < servlet-name >spring3</ servlet-name > < servlet-class >org.springframework.web.servlet.DispatcherServlet</ servlet-class > <!-- 配置文件 --> < init-param > < param-name >contextConfigLocation</ param-name > < param-value >classpath:context-dispatcher.xml</ param-value > </ init-param > </ servlet > < servlet-mapping > < servlet-name >spring3</ servlet-name > < url-pattern >/</ url-pattern > </ servlet-mapping > <!-- 激活静态资源的默认配置,解决Rest风格兼容 --> < servlet-mapping > < servlet-name >default</ servlet-name > < url-pattern >*.css</ url-pattern > </ servlet-mapping > < servlet-mapping > < servlet-name >default</ servlet-name > < url-pattern >*.js</ url-pattern > </ servlet-mapping > < servlet-mapping > < servlet-name >default</ servlet-name > < url-pattern >*.gif</ url-pattern > </ servlet-mapping > < servlet-mapping > < servlet-name >default</ servlet-name > < url-pattern >*.jpg</ url-pattern > </ servlet-mapping > < welcome-file-list > < welcome-file >index.jsp</ welcome-file > </ welcome-file-list > </ web-app > |
清单2. applicationContext.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
|
<? 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:p = "http://www.springframework.org/schema/p" xmlns:tx = "http://www.springframework.org/schema/tx" xmlns:aop = "http://www.springframework.org/schema/aop" xmlns:context = "http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd" default-init-method = "init" > <!-- 引入jdbc配置文件 --> < context:property-placeholder location = "classpath:jdbc.properties" /> <!--创建jdbc数据源 --> < bean id = "dataSource" class = "org.apache.commons.dbcp.BasicDataSource" destroy-method = "close" > < property name = "driverClassName" value = "${driver}" /> < property name = "url" value = "${url}" /> < property name = "username" value = "${username}" /> < property name = "password" value = "${password}" /> </ bean > <!-- (事务管理)transaction manager, use JtaTransactionManager for global tx --> < bean id = "transactionManager" class = "org.springframework.jdbc.datasource.DataSourceTransactionManager" > < property name = "dataSource" ref = "dataSource" /> </ bean > <!-- 创建SqlSessionFactory,同时指定数据源 --> < bean id = "sqlSessionFactory" class = "org.mybatis.spring.SqlSessionFactoryBean" > < property name = "configLocation" value = "classpath:mybatis.cfg.xml" ></ property > < property name = "dataSource" ref = "dataSource" /> </ bean > <!-- 可通过注解控制事务 --> < tx:annotation-driven transaction-manager = "transactionManager" /> <!-- 配置事务的传播特性 --> <!-- <tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <tx:method name="create*" propagation="REQUIRED" /> <tx:method name="modify*" propagation="REQUIRED" /> <tx:method name="delete*" propagation="REQUIRED" /> <tx:method name="*" read-only="true" /> </tx:attributes> </tx:advice> --> <!-- 配置事务的切入点 --> <!-- <aop:config> <aop:pointcut id="targetMethod" expression="execution(* com.matol.service.*.*(..))" /> <aop:advisor advice-ref="txAdvice" pointcut-ref="targetMethod" /> </aop:config> --> <!-- Mapper接口所在包名,Spring会自动查找其下的Mapper --> < bean class = "org.mybatis.spring.mapper.MapperScannerConfigurer" > < property name = "basePackage" value = "com.matol.mapper" /> </ bean > <!-- 负责注册JSR-250 的注释生效 @Resource MapperScannerConfigurer配置会自动启用mapper注解,可省略当前配置 <bean class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor"/> --> </ beans > |
清单3. context-dispatcher.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
|
<? xml version = "1.0" encoding = "UTF-8" ?> < beans default-lazy-init = "true" xmlns = "http://www.springframework.org/schema/beans" xmlns:p = "http://www.springframework.org/schema/p" xmlns:tx = "http://www.springframework.org/schema/tx" xmlns:aop = "http://www.springframework.org/schema/aop" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xmlns:context = "http://www.springframework.org/schema/context" xmlns:mvc = "http://www.springframework.org/schema/mvc" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <!-- 通过注解,把URL映射到Controller上,该标签默认注册DefaultAnnotationHandlerMapping和AnnotationMethodHandlerAdapter --> < mvc:annotation-driven /> <!-- annotation默认的方法映射适配器 mvc:annotation-driven注册后可以省略当前配置 <bean id="handlerMapping" class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" /> <bean id="handlerAdapter" class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" /> --> <!-- 探测注解的包,包括子集, 在JUnit测试的时候需要 --> <!-- 自动扫描bean,把作了注解的类转换为bean --> < context:component-scan base-package = "com.matol" /> <!-- 加载组装所以配置文件 context:component-scan注册后可以省略当前配置 <context:annotation-config/> --> <!-- 视图解析器 --> < bean id = "viewResolver" class = "org.springframework.web.servlet.view.InternalResourceViewResolver" > <!-- 使用JSP页面进行输出 --> < property name = "viewClass" value = "org.springframework.web.servlet.view.JstlView" /> <!-- 指定了表示层的前缀 --> <!-- 这个配置是配置JSP页面的位置,按照你自己的配置来配 --> < property name = "prefix" value = "/" /> <!-- 指定了表示层的后缀 --> < property name = "suffix" value = ".jsp" ></ property > </ bean > <!-- 处理文件上传处理 --> < bean id = "multipartResolver" class = "org.springframework.web.multipart.commons.CommonsMultipartResolver" p:defaultEncoding = "UTF-8" /> </ beans > |
清单4. jdbc.properties
1
2
3
4
|
driver=com.mysql.jdbc.Driver url=jdbc:mysql://localhost:3306/matolDB username=root password=root |
清单5. mybatis.cfg.xml
1
2
3
4
5
6
7
8
9
10
11
12
|
<? xml version = "1.0" encoding = "UTF-8" ?> <! DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> < configuration > < typeAliases > < typeAlias alias = "Student" type = "com.matol.entity.User" /> </ typeAliases > < mappers > < mapper resource = "com/matol/mapper/UserMapper.xml" /> </ mappers > </ configuration > |
清单6. matolDB.sql
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
/* Navicat MySQL Data Transfer Source Server : localhost Source Server Version : 50141 Source Host : localhost:3306 Source Database : matoldb Target Server Type : MYSQL Target Server Version : 50141 File Encoding : 65001 Date: 2013-01-23 16:47:52 */ SET FOREIGN_KEY_CHECKS=0; -- ---------------------------- -- Table structure for `sys_user` -- ---------------------------- DROP TABLE IF EXISTS `sys_user`; CREATE TABLE `sys_user` ( `id` int (11) unsigned zerofill NOT NULL AUTO_INCREMENT, ` name ` varchar (100) COLLATE utf8_unicode_ci DEFAULT NULL , `pass` varchar (100) COLLATE utf8_unicode_ci DEFAULT NULL , `age` int (11) DEFAULT NULL , PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8 COLLATE =utf8_unicode_ci; |
清单7. User.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
|
package com.matol.entity; import java.io.Serializable; import org.springframework.stereotype.Repository; /** * * @author matol * @date 2013-01-23 16:38 */ @Repository (value = "user" ) public class User implements Serializable { private Integer id; private String name; private String pass; private Integer age; public User(){} 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 String getPass() { return pass; } public void setPass(String pass) { this .pass = pass; } public Integer getAge() { return age; } public void setAge(Integer age) { this .age = age; } } |
清单7. UserMapper.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
package com.matol.mapper; import java.util.List; import org.springframework.stereotype.Repository; import org.springframework.transaction.annotation.Transactional; import com.matol.entity.User; /** * * @author matol * @date 2013-01-23 16:38 */ @Repository (value = "userMapper" ) @Transactional public interface UserMapper { Integer create(User user); Integer delete(Integer id); Integer modify(User user); User findById(Integer id); User findByUser(User user); List<User> findAll(); List<User> findAll(User user); Integer count(); } |
清单8. UserMapper .xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
|
<? xml version = "1.0" encoding = "UTF-8" ?> <! DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> < mapper namespace = "com.matol.mapper.UserMapper" > <!-- 定义数据库字段与实体对象的映射关系 --> < resultMap type = "com.matol.entity.User" id = "resultUser" > < id property = "id" column = "id" /> < result property = "name" column = "name" /> < result property = "pass" column = "pass" /> < result property = "age" column = "age" /> </ resultMap > <!-- 定义参数模型 --> < parameterMap type = "com.matol.entity.User" id = "paramUser" > < parameter property = "id" /> < parameter property = "name" /> < parameter property = "pass" /> < parameter property = "age" /> </ parameterMap > <!-- 定义要操纵的SQL语句 --> < insert id = "create" parameterType = "com.matol.entity.User" > INSERT INTO sys_user(name,pass,age) VALUES(#{name},#{pass},#{age}) </ insert > < delete id = "delete" parameterType = "Integer" > DELETE FROM sys_user WHERE id=#{value} </ delete > < update id = "modify" parameterType = "com.matol.entity.User" > UPDATE sys_user < set > < if test = "name != null" >name=#{name},</ if > < if test = "pass != null" >pass=#{pass},</ if > < if test = "age != null" >age=#{age},</ if > </ set > WHERE id=#{id} </ update > < select id = "findById" parameterType = "Integer" resultMap = "resultUser" > SELECT * FROM sys_user WHERE id=#{value} </ select > < select id = "findAll" resultType = "list" resultMap = "resultUser" > SELECT * FROM sys_user </ select > < select id = "count" resultType = "Integer" > SELECT count(*) FROM sys_user </ select > </ mapper > |
清单9. UserService.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
package com.matol.service; import java.util.List; import org.springframework.stereotype.Repository; import com.matol.entity.User; /** * * @author matol * @date 2013-01-23 16:38 */ @Repository (value = "userService" ) public interface UserService { Integer create(User user); Integer delete(Integer id); Integer modify(User user); User findById(Integer id); User findByUser(User user); List<User> findAll(); List<User> findAll(User user); Integer count(); } |
清单10. UserServiceImpl.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
|
package com.matol.service.impl; import java.util.List; import javax.annotation.Resource; import org.springframework.stereotype.Repository; import com.matol.entity.User; import com.matol.mapper.UserMapper; import com.matol.service.UserService; /** * * @author matol * @date 2013-01-23 16:38 */ @Repository (value = "userServiceImpl" ) public class UserServiceImpl implements UserService{ @Resource (name = "userMapper" ) private UserMapper userMapper; public Integer count() { return userMapper.count(); } public Integer create(User user) { return userMapper.create(user); } public Integer delete(Integer id) { return userMapper.delete(id); } public List<User> findAll() { return userMapper.findAll(); } public List<User> findAll(User user) { return userMapper.findAll(user); } public User findById(Integer id) { return userMapper.findById(id); } public User findByUser(User user) { return userMapper.findByUser(user); } public Integer modify(User user) { return userMapper.modify(user); } } |
清单11. UserController.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
|
package com.matol.controller; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.ModelAndView; import com.matol.entity.User; import com.matol.service.UserService; /** * * @author matol * @date 2013-01-23 16:38 */ @Controller @RequestMapping (value = "/user" ) public class UserController { @Resource (name = "userServiceImpl" ) private UserService userService; /** * @author matol * @date 2013-01-23 16:38 * @return */ @RequestMapping (value = "**/list" ) public ModelAndView getAllUser(HttpServletRequest request,HttpServletResponse response) throws Exception { Map<String, Object> map = new HashMap<String, Object>(); List<User> result = new ArrayList<User>(); result = userService.findAll(); map.put( "result" , result); return new ModelAndView( "/user/list" , map); } /** * @author matol * @date 2013-01-23 16:38 * @return */ @RequestMapping (value = "**/list/{id}" ) public ModelAndView getTheUser( @PathVariable ( "id" ) int id){ Map<String, Object> map = new HashMap<String, Object>(); List<User> result = new ArrayList<User>(); result.add(userService.findById(id)); map.put( "result" , result); return new ModelAndView( "/user/list" , map); } /** * @author matol * @date 2013-01-23 16:38 * @return */ @RequestMapping (value = "**/toAdd" ) public ModelAndView toAddUser(){ return new ModelAndView( "/user/adds" ); } /** * @author matol * @date 2013-01-23 16:38 * @return */ @RequestMapping (value = "**/doAdd" ) public String addUser(User user){ userService.create(user); Map<String, Object> map = new HashMap<String, Object>(); List<User> result = new ArrayList<User>(); result = userService.findAll(); map.put( "result" , result); return "redirect:list" ; } /** * @author matol * @date 2013-01-23 16:38 * @return */ @RequestMapping (value = "**/delete/{id}" ) public String deleteTheUser( @PathVariable ( "id" ) int id){ Map<String, Object> map = new HashMap<String, Object>(); userService.delete(id); List<User> result = new ArrayList<User>(); result = userService.findAll(); map.put( "result" , result); return "redirect:/user/list" ; } } |
清单12. index.jsp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> <% 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 > < title >My JSP 'index.jsp' starting page</ title > </ head > < body > < h3 >Spring3.1、MyBatis3.1、MySQL 整合.</ h3 > < a href = "user/list" >查询所有</ a >< br /> < a href = "user/toAdd" >添加记录</ a >< br /> </ body > </ html > |
清单13. list.jsp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <! DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> < html > < head > < meta http-equiv = "Content-Type" content = "text/html; charset=UTF-8" /> < title >Insert title here</ title > </ head > < body > < c:forEach items = "${result}" var = "item" > < a href = "list/${item.id }" >${item.name }</ a > pass: ${item.pass } --- age: ${item.age } < a href = "delete/${item.id }" >delete</ a >< hr /> </ c:forEach > < a href = "toAdd" >添加记录</ a >< br /> </ body > </ html > |
清单14. adds.jsp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <! DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> < html > < head > < meta http-equiv = "Content-Type" content = "text/html; charset=UTF-8" /> < title >Insert title here</ title > </ head > < body > < br /> < form action = "doAdd" method = "post" > name:< input type = "text" name = "name" > pass:< input type = "text" name = "pass" > age:< input type = "text" name = "age" > < input type = "submit" value = "submit" > </ form > < br /> < a href = "list" >查询所有</ a >< br /> </ body > </ html > |
lib的jar清单
由于只是一个相对简单的使用范例,所以没有非常标准的注入DAO,以及DAO接口,只是通过Mapper代替过程。不过,道理都是一样,无非就是新添加一层注入而已。