Spring + Spring MVC + Mybatis 整合
实现SSM的登录、注册功能。
首先对SSM框架有一个整体意识
建立目录结构:
controller service mapper 三者关系:
调用:controller --> service --> mapper
返回:mapper --> service --> controller
controller:作为请求转发,调用service接口处理逻辑,页面所有路径的访问方法:控制层的命名空间+@RequestMapping的value service:接口,处理业务逻辑(impl里面实现,调用mapper操作数据库) mapper:操作数据库的接口
第一,导入spring、spring mvc与mybatis所需要的包
第二,配置applicationContext.xml
1 <!-- 配置包扫描 -->
2 <context:component-scan base-package="com.krry"></context:component-scan>
3
4 <!-- 导入外部资源文件 -->
5 <!-- <context:property-placeholder location="classpath:jdbc.properties" /> -->
6 <bean class="com.krry.core.des.EncryptPropertyPlaceholderConfigurer"
7 p:location="classpath:db/jdbc.properties" p:fileEncoding="utf-8" />
8
9 <!-- proxool连接池 -->
10 <bean id="dataSource" class="org.logicalcobwebs.proxool.ProxoolDataSource">
11 <!-- 驱动的名字,mysql -->
12 <property name="driver" value="${db.driver}"></property>
13 <!--proxool 的 url连接串,这个必须确定用户名和密码 -->
14 <property name="driverUrl" value="${db.url}"></property>
15 <!-- 用户名(proxool没有使用,但是不能没有) -->
16 <property name="user" value="${db.username}"></property>
17 <!-- 密码(proxool没有使用,但是不能没有) -->
18 <property name="password" value="${db.password}"></property>
19 <!-- proxool自动侦察各个连接状态的时间间隔(毫秒),侦察到空闲的连接就马上回收,超时的销毁 现在设置为4秒) -->
20 <property name="houseKeepingSleepTime" value="3000"></property><!-- 自动检查连接是否断掉开关 -->
21 <property name="testBeforeUse" value="true"></property>
22 <!-- 如果发现了空闲的数据库连接.house keeper 将会用这个语句来测试.这个语句最好非常快的被执行.如果没有定义,测试过程将会被忽略 -->
23 <property name="houseKeepingTestSql" value="SELECT count(1) from dual"></property>
24 <!-- 如果housekeeper 检测到某个线程的活动时间大于这个数值.它将会杀掉这个线程.所以确认一下你的服务器的带宽.然后定一个合适的值.默认是5分钟. 现在设置 10 秒-->
25 <property name="maximumActiveTime" value="10000"></property>
26 <!-- 最少保持的空闲连接数 (现在设置20个) -->
27 <property name="prototypeCount" value="20"></property>
28 <!-- 最大连接数 (现在设置100个) -->
29 <property name="maximumConnectionCount" value="200"></property>
30 <!-- 最小连接数 (现在设置50个) -->
31 <property name="minimumConnectionCount" value="50"></property>
32 <!-- 如果为true,那么每个被执行的SQL语句将会在执行期被log记录(DEBUG LEVEL).你也可以注册一个ConnectionListener (参看ProxoolFacade)得到这些信息. -->
33 <property name="trace" value="false"></property>
34 <property name="verbose" value="true"></property>
35 </bean>
36
37 <!-- 注册事务管理器 -->
38 <bean id="txMgr"
39 class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
40 <property name="dataSource" ref="dataSource"></property>
41 </bean>
42
43 <!-- 开启事务注解驱动 -->
44 <tx:annotation-driven transaction-manager="txMgr" />
45
46 <!-- 配置mybatis的sqlSessionFactory -->
47 <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
48 <property name="dataSource" ref="dataSource"></property>
49 <property name="configLocation" value="classpath:mybatis-config.xml"></property>
50 </bean>
51
52 <!-- 配置可以整体扫描Mapper的一个扫描器 -->
53 <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
54 <!--如果有多个报路径,用逗号分开即可 -->
55 <property name="basePackage" value="com.krry.mapper"></property>
56 <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>
57 </bean>
第三,配置springmvc.xml
1 <?xml version="1.0" encoding="UTF-8" ?>
2 <beans xmlns="http://www.springframework.org/schema/beans"
3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4 xmlns:p="http://www.springframework.org/schema/p"
5 xmlns:context="http://www.springframework.org/schema/context"
6 xmlns:util="http://www.springframework.org/schema/util"
7 xmlns:mvc="http://www.springframework.org/schema/mvc"
8 xsi:schemaLocation="http://www.springframework.org/schema/beans
9 http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
10 http://www.springframework.org/schema/context
11 http://www.springframework.org/schema/context/spring-context-3.0.xsd
12 http://www.springframework.org/schema/util
13 http://www.springframework.org/schema/util/spring-util-3.0.xsd
14 http://www.springframework.org/schema/mvc
15 http://www.springframework.org/schema/mvc/spring-mvc.xsd
16 ">
17
18 <!-- 开启注解模式驱动 -->
19 <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" />
20 <!-- 开启mvc的注解模式 user 还会注册一个ConversionService 子类FormattingConversionServiceFactoryBean-->
21 <mvc:annotation-driven>
22 <mvc:message-converters register-defaults="true">
23 <bean class="com.krry.core.UTF8StringHttpMessageConverter">
24 <property name="supportedMediaTypes">
25 <list>
26 <value>text/plain;charset=UTF-8</value>
27 <value>text/html;charset=UTF-8</value>
28 </list>
29 </property>
30 </bean>
31 <bean class="org.springframework.http.converter.BufferedImageHttpMessageConverter"/>
32 <bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter"/>
33 <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
34 <property name="prefixJson" value="false" />
35 <property name="objectMapper">
36 <bean class="com.fasterxml.jackson.databind.ObjectMapper">
37 <!-- 处理responseBody 里面日期类型 -->
38 <property name="dateFormat">
39 <bean class="java.text.SimpleDateFormat">
40 <constructor-arg type="java.lang.String" value="yyyy-MM-dd HH:mm:ss" />
41 </bean>
42 </property>
43 <!-- 为null字段时不显示 -->
44 <property name="serializationInclusion">
45 <value type="com.fasterxml.jackson.annotation.JsonInclude.Include">NON_NULL</value>
46 </property>
47 </bean>
48 </property>
49 <property name="supportedMediaTypes">
50 <list>
51 <value>application/json;charset=UTF-8</value>
52 <value>application/x-www-form-urlencoded;charset=UTF-8</value>
53 </list>
54 </property>
55 </bean>
56 </mvc:message-converters>
57 </mvc:annotation-driven>
58
59 <!-- 扫包 -->
60 <context:component-scan base-package="com.krry.controller"></context:component-scan>
61
62 <!--对静态资源文件的访问 必须要设置,因为在springmvc的配置中配置了/匹配所有请求,
63 此工程所有的请求(.do ,addUser,js/image/css)都会被springmvc解析,
64 必须对所有的静态资源文件进行过滤放行 -->
65 <!-- 静态资源过滤 下面二选一-->
66 <!--<mvc:default-servlet-handler/> -->
67 <mvc:resources mapping="/resourse/**" location="/resourse/" />
68
69 <!-- 拦截器定义 -->
70 <mvc:interceptors>
71 <mvc:interceptor>
72 <!-- 个人中心也需要登陆 以admin开头的配置都会进行拦截-->
73 <mvc:mapping path="/admin/**"></mvc:mapping>
74 <!-- 这个是设置不会进入拦截器的路径 -->
75 <mvc:exclude-mapping path="/resourse/**"/>
76 <!-- 拦截器进入的类,返回false表示不会进入输入的路径 -->
77 <bean class="com.krry.core.filter.LoginInterceptor" />
78 </mvc:interceptor>
79 </mvc:interceptors>
80
81 <!-- 配置文件解析器 -->
82 <bean id="multipartResolver"
83 class="org.springframework.web.multipart.commons.CommonsMultipartResolver"
84 p:defaultEncoding="utf-8">
85 <property name="uploadTempDir" value="/temp"></property>
86 <property name="maxUploadSize">
87 <value>209715200</value><!-- 200MB -->
88 </property>
89 <property name="maxInMemorySize">
90 <value>4096</value><!-- 4KB大小读写 -->
91 </property>
92 </bean>
93
94
95 <!-- 视图渲染 jsp/freemaker/velocity-->
96 <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
97 <!-- 制定页面存放的路径 -->
98 <property name="prefix" value="/WEB-INF/pages/"></property>
99 <!-- 文件的后缀 -->
100 <property name="suffix" value=".jsp"></property>
101 </bean>
102
103 </beans>
第四,配置mybatis-config.xml
1 <configuration>
2 <settings>
3 <!-- 全局映射器启用缓存 -->
4 <setting name="cacheEnabled" value="true" />
5 <!-- 查询时,关闭关联对象即时加载以提高性能 -->
6 <setting name="lazyLoadingEnabled" value="true" />
7 <!-- 设置关联对象加载的形态,此处为按需加载字段(加载字段由SQL指定),不会加载关联表的所有字段,以提高性能 -->
8 <setting name="aggressiveLazyLoading" value="false" />
9 <!-- 对于未知的SQL查询,允许返回不同的结果集以达到通用的效果 -->
10 <setting name="multipleResultSetsEnabled" value="true" />
11 <!-- 允许使用列标签代替列名 -->
12 <setting name="useColumnLabel" value="true" />
13 <!-- 允许使用自定义的主键值(比如由程序生成的UUID 32位编码作为键值),数据表的PK生成策略将被覆盖 -->
14 <setting name="useGeneratedKeys" value="true" />
15 <!-- 给予被嵌套的resultMap以字段-属性的映射支持 -->
16 <setting name="autoMappingBehavior" value="FULL" />
17 <!-- 对于批量更新操作缓存SQL以提高性能 -->
18 <setting name="defaultExecutorType" value="BATCH" />
19 <!-- 数据库超过25000秒仍未响应则超时 -->
20 <setting name="defaultStatementTimeout" value="25" />
21 <setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString"/>
22 </settings>
23
24 <typeAliases>
25 <!--自定义user对象的别名 -->
26 <!-- <typeAlias type="com.krry.mybatis.sysmanage.entity.User" alias="user"/> -->
27 <!-- 批量定义别名 -->
28 <package name="com.krry.entity" />
29 </typeAliases>
30
31 <!-- 配置pageHelper分页插件 -->
32 <plugins>
33 <plugin interceptor="com.github.pagehelper.PageHelper">
34 <!-- 设置数据库类型 Oracle,Mysql,MariaDB,SQLite,Hsqldb,PostgreSQL六种数据库 -->
35 <property name="dialect" value="mysql" />
36 <!--当设置为true的时候,如果pagesize设置为0 就不执行分页,返回全部结果 -->
37 <property name="pageSizeZero" value="true" />
38 <!--合理化查询 比如如果pageNum<1会查询第一页;如果pageNum>pages会查询最后一页(设置为false返回空) -->
39 <property name="reasonable" value="false" />
40 <!-- 支持通过Mapper接口参数来传递分页参数 -->
41 <property name="supportMethodsArguments" value="false" />
42 <!-- 总是返回PageInfo类型,check检查返回类型是否为PageInfo,none返回Page -->
43 <property name="returnPageInfo" value="none" />
44 </plugin>
45 </plugins>
46
47
48 </configuration>
在mybatis相应的xml文件配置mybatis的sql文件和mapper转换器(也就是说的mapper下面的接口) 注入到sqlSessionFactory (放入到内存中)
1. mapper的xml中,这里的命名空间可以随便定义(必须唯一),但是为了方便,定义成mapper包下的类的目录,调用mapper下面类的接口方法的时候,调用的路径是:mapper包下的类的目录+方法名,即是与这个命名空间+id一样,自动用了这个sql语句(id对应这个类的接口里面的方法)这里面必定有executeQuery方法,会执行这条sql语句。
2. 如果自己自定义名命名空间,调用下面的sql语句的方法为:在mapper里的方法执行以下语句: SqlSession session = sessionFactory.openSession(); List<User> users = session.selectList("命名空间+id"); //根据实际结果集类型和sql语句类型,写这条代码就可以获取结果集
推荐使用第一种命名方式。
mybatis执行流程:
第五,配置web.xml
1 <?xml version="1.0" encoding="UTF-8"?>
2 <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
3
4 <display-name>krry_SSM</display-name>
5
6 <welcome-file-list>
7 <welcome-file>index</welcome-file>
8 </welcome-file-list>
9
10 <!-- 加载Spring IOC容器 -->
11 <context-param>
12 <param-name>contextConfigLocation</param-name>
13 <param-value>classpath:spring/applicationContext*.xml</param-value>
14 </context-param>
15
16 <!-- spring上下文监听器 -->
17 <listener>
18 <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
19 </listener>
20
21 <!-- Introspector缓存清除监听器 -->
22 <listener>
23 <listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>
24 </listener>
25
26 <filter>
27 <filter-name>encoding</filter-name>
28 <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
29 <init-param>
30 <param-name>encoding</param-name>
31 <param-value>UTF-8</param-value>
32 </init-param>
33 </filter>
34
35 <filter-mapping>
36 <filter-name>encoding</filter-name>
37 <url-pattern>/*</url-pattern>
38 </filter-mapping>
39
40 <!-- 配置DispatcherServlet -->
41 <servlet>
42 <servlet-name>krry_SSM</servlet-name>
43 <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
44 <!-- 配置springMVC的配置文件 -->
45 <!-- 如果不配置下面选项,系统默认加载classpath下面名为[servlet-name]-servlet.xml的文件 springmvc01-servlet.xml -->
46 <init-param>
47 <param-name>contextConfigLocation</param-name>
48 <param-value>classpath:spring/springmvc.xml</param-value>
49 </init-param>
50 </servlet>
51
52 <servlet-mapping>
53 <servlet-name>krry_SSM</servlet-name>
54 <url-pattern>/index</url-pattern>
55 </servlet-mapping>
56
57 <!-- 可以配*.do, *.action(了解) / (重点): 所有的请求都会被spring mvc解析,但必须对静态资源文件进行过滤放行,建议大家使用这种方式
58 /* : 不建议大家使用 -->
59 <servlet-mapping>
60 <servlet-name>krry_SSM</servlet-name>
61 <url-pattern>/</url-pattern>
62 </servlet-mapping>
63
64 </web-app>
这里注意一点欢迎页面,welcome-file-list一般情况下只能使用静态网页,如果非要把他配置成SpringMVC的控制器(通过controller进入欢迎页)URL就会报错404,
解决方法:
在web.xml上首先设置
1 <welcome-file-list>
2 <welcome-file>index</welcome-file>
3 </welcome-file-list>
再增加一个/index 的映射
1 <servlet-mapping>
2 <servlet-name>krry_SSM</servlet-name>
3 <url-pattern>/index</url-pattern>
4 </servlet-mapping>
最后在controller层添加一个首页控制器得到index的请求
1 @RequestMapping("/index")
controller层:
1 package com.krry.controller.login;
2
3 import java.sql.Date;
4 import java.sql.Timestamp;
5 import java.text.SimpleDateFormat;
6 import java.util.UUID;
7
8 import javax.servlet.http.HttpServletRequest;
9
10 import org.springframework.beans.factory.annotation.Autowired;
11 import org.springframework.stereotype.Controller;
12 import org.springframework.web.bind.annotation.RequestMapping;
13 import org.springframework.web.bind.annotation.RequestMethod;
14
15 import com.krry.entity.User;
16 import com.krry.service.IUserService;
17 import com.krry.util.TmStringUtils;
18
19 /**
20 * Controller层,作为请求转发
21 * 页面所有路径的访问方法:控制层的命名空间+@RequestMapping的value
22 * 如这里的/login/index.krry(后缀在xml文件配置)
23 * */
24 @Controller //表示是多例模式,每个用户返回的web层是不一样的
25 @RequestMapping("/login")
26 public class LoginController {
27
28 @Autowired
29 private IUserService userService;
30
31 /**
32 * 若在下面的@RequestMapping前面加上@ResponseBody,
33 * 若方法是String类型则直接返回的是字符串,不会跳转到该字符串的路径jsp文件
34 *
35 * 所以要想跳转到某一jsp页面,不能加上@ResponseBody
36 * 这个@ResponseBody适合ajax返回的数据
37 *
38 */
39
40 /**
41 * 在控制层不加@ResponseBody的情况下,return值默认是转发到某路径,不会显示转发路径,显示的是未转发前的路径
42 * 若要重定向,加上redirect:这里默认是当前命名空间的转发,要跳转到另一个control层,需要返回上一级../
43 *
44 这里使用重定向,返回命名空间的上一级,重定向到命名空间为Krry下的index
45 return "redirect:../index";
46
47 注意:
48 转发不会显示转发路径,显示的是未转发前的路径
49 * 重定向显示的是跳转之后的路径
50 */
51
52 /**
53 * 进入登录界面
54 * @return
55 */
56 @RequestMapping("/index")
57 public String index(){
58 // ModelAndView modelAndView = new ModelAndView();
59 // modelAndView.setViewName("index/login"); //跳到此页面
60 // return modelAndView;
61 return "index/login"; //默认是转发,不会显示转发路径
62 }
63
64 /**
65 * 点击登录
66 * com.krry.controller.login
67 * 方法名:login
68 * @author krry
69 * @param request
70 * @return String
71 * @exception
72 * @since 1.0.0
73 */
74 @RequestMapping(method=RequestMethod.POST,value="/logined")
75 public String login(HttpServletRequest request){
76 //获取用户和密码
77 String username = request.getParameter("username");
78 String password = request.getParameter("password");
79
80 //如果邮箱和密码为null,那么就返回已null标识
81 if(TmStringUtils.isEmpty(username) )return "index/allError";
82 if(TmStringUtils.isEmpty(password))return "index/allError";
83
84 //密码进行加密处理
85 password = TmStringUtils.md5Base64(password);
86
87 //根据邮箱或昵称查询,用户是否存在
88 User user = userService.getLogin(username);
89
90 //如果存在
91 if(user!=null){
92
93 User userpas = userService.getpass(username, password);
94 if(userpas!=null){
95 //如果密码正确
96 //将用户信息放入到会话中...
97 request.getSession().setAttribute("user", user);
98
99 //这里使用重定向,返回命名空间的上一级,重定向到命名空间为Krry下的index.krry
100 return "redirect:../index";
101 }else{
102 //如果密码错误
103 System.out.println("密码错误");
104 return "index/error";
105 }
106 }else{
107 //如果不存在,代码邮箱和密码输入有误
108 System.out.println("用户不存在");
109 return "index/error";
110 }
111 }
112
113 /**
114 * 退出登录控制层
115 * com.krry.controller.login
116 * 方法名:logout
117 * @author krry
118 * @param request
119 * @return String
120 * @exception
121 * @since 1.0.0
122 */
123 @RequestMapping(method=RequestMethod.GET,value="/logout")
124 public String logout(HttpServletRequest request){
125 request.getSession().invalidate(); //清空session值
126 return "index/index";
127 }
128
129 /**
130 * 打开注册界面层
131 * @return
132 */
133 @RequestMapping("/rege")
134 public String rege(){
135 // ModelAndView modelAndView = new ModelAndView();
136 // modelAndView.setViewName("index/login"); //跳到此页面
137 // return modelAndView;
138 return "index/resgi";
139 }
140
141 /**
142 * 注册控制层
143 * com.krry.controller.login
144 * 方法名:resig
145 * @author krry
146 * @param request
147 * @return String
148 * @exception
149 * @since 1.0.0
150 */
151 @RequestMapping(method=RequestMethod.POST,value="/resig")
152 public String resig(HttpServletRequest request){
153 //获取用户和密码
154 String name = request.getParameter("username");
155 String email = request.getParameter("email");
156 String password = request.getParameter("password");
157
158 //如果邮箱和密码为null,那么就返回已null标识
159 if(TmStringUtils.isEmpty(name) )return "index/allError";
160 if(TmStringUtils.isEmpty(email))return "index/allError";
161 if(TmStringUtils.isEmail(password))return "index/allError";
162
163 //密码进行加密处理
164 password = TmStringUtils.md5Base64(password);
165 //根据昵称查询,用户是否存在
166 User user1 = userService.getothernameres(name);
167 //根据账号查询,用户是否存在
168 User user2 = userService.getemailres(email);
169
170 //若存在
171 if(user1 != null){ //昵称重复
172 return "index/allError";
173 }
174 if(user2 != null){ //email重复
175 return "index/allError";
176 }
177
178 Date time = new Date(System.currentTimeMillis());
179
180 String id = UUID.randomUUID().toString();
181 //执行到这里,说明可以注册
182 User newUser = new User(id, name, password, email,time);
183 //调用注册方法
184 userService.saveUser(newUser);
185
186 //将信息设置session作用域
187 request.getSession().setAttribute("user", newUser);
188
189 /**
190 * 这里使用重定向,返回命名空间的上一级,重定向到index
191 */
192 return "redirect:../index";
193 }
194
195 }
重要的点,以上的说到了,还有一些前端页面、数据库操作就不在这展示了
以上ssm整合的链接展示:https://www.ainyi.com/krry_SSM
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有