一、概述
本文以一个登录注册的小功能作为示例,对SSM框架做一个整合。
二、SSM整合
SSM框架是指Spring、SpringMVC和Mybatis,SpringMVC是包含在Spring中的,因此SSM框架整合核心是将Mybatis整合到Spring中。
2.1 DAO
1. 创建如下的数据库表格:
CREATE TABLE `user` (
`id` int NOT NULL AUTO_INCREMENT,
`user_name` varchar(255) NOT NULL,
`user_password` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`create_time` datetime NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8;
2. 创建对应表格的User类:
/**
* 对应数据库user表格的User对象
*/
@Data
@AllArgsConstructor //生成一个包含所有参数的构造器
@NoArgsConstructor //生成一个没有参数的构造器
public class User {
private int id;
private String userName;
private String userPassword;
private Date createTime;
}
3. 创建Mybatis配置文件mybatis-config.xml:
<?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>
<!--配置日志-->
<settings>
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
<typeAliases>
<package name="com.wyf.dao"/>
</typeAliases>
<mappers>
<package name="com.wyf.dao" />
</mappers>
</configuration>
mybatis-config.xml是Mybatis的主配置文件,一般若是单独使用Mybatis的话,应该在该配置文件中使用环境配置对数据库连接进行配置,但是,我们整合SSM框架,可以将数据库连接的相关配置交给Spring来做,甚至都可以不要mybatis-config.xml文件。
4. 编写UserMapper接口:
public interface UserMapper {
/**
* 新增用户
*
* @param sysUser
* @return 返回影响行数
*/
int insert(User sysUser);
/**
* 通过ID查询用户
* @param id
* @return
*/
User selectById(int id);
/**
* 查询符合登录条件的用户数
* @return
*/
long selectUser(User sysUser);
}
示例程序只有登录操作以及注册操作,因此此处为了简单,只提供了插入和查询功能。如果有其他需求,可以添加。
5. 编写UserMapper接口对应的UserMapper.xml文件:
<?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.wyf.dao.UserMapper">
<resultMap id="userMap" type="com.wyf.dao.User">
<id property="id" column="id"/>
<result property="userName" column="user_name"/>
<result property="userPassword" column="user_password"/>
<result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
</resultMap>
<!-- select查询 -->
<select id="selectById" resultMap="userMap">
select * from `user` where id = #{id}
</select>
<!-- insert数据插入 -->
<insert id="insert">
insert into `user`(
user_name, user_password, create_time)
values(#{userName}, #{userPassword}, #{createTime, jdbcType=TIMESTAMP})
</insert>
<select id="selectUser" resultType="long">
SELECT COUNT(*) from `user` WHERE user_name=#{userName} AND user_password=#{userPassword};
</select>
</mapper>
6. 编写spring-dao.xml文件,将Mybatis框架整合到Spring中:
<?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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<!-- spring整合Mybatis,使用c3p0数据库连接池 -->
<!-- 配置整合mybatis -->
<!-- 1. 关联数据库文件 -->
<context:property-placeholder location="classpath:database.properties"/>
<!-- C3P0数据库连接池 -->
<!-- 配置数据源(C3P0) -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<!-- 属性注入 -->
<property name="driverClass" value="${jdbc.driver}"></property>
<property name="jdbcUrl" value="${jdbc.url}"></property>
<property name="user" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
<!-- C3P0其他属性设置 -->
<!--连接池中保留的最小连接数。 -->
<property name="minPoolSize" value="10" />
<!--连接池中保留的最大连接数。Default: 15 -->
<property name="maxPoolSize" value="30" />
<!-- 关闭链接后不自动commit -->
<property name="autoCommitOnClose" value="false"/>
<!--最大空闲时间,1800秒内未使用则连接被丢弃。若为0则永不丢弃。Default: 0 -->
<property name="maxIdleTime" value="1800" />
<!--当连接池中的连接耗尽的时候c3p0一次同时获取的连接数。Default: 3 -->
<property name="acquireIncrement" value="3" />
<property name="maxStatements" value="1000" />
<property name="initialPoolSize" value="10" />
<!--每60秒检查所有连接池中的空闲连接。Default: 0 -->
<property name="idleConnectionTestPeriod" value="60" />
<!--定义在从数据库获取新连接失败后重复尝试的次数。Default: 30 -->
<property name="acquireRetryAttempts" value="30" />
<property name="breakAfterAcquireFailure" value="true" />
<property name="testConnectionOnCheckout" value="false" />
</bean>
<!-- 3. 配置sqlSessionFactory对象 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 注入数据库连接池 -->
<property name="dataSource" ref="dataSource"/>
<!-- 配置Mybatis的配置文件:mybatis-config.xml -->
<property name="configLocation" value="classpath:mybatis-config.xml"/>
</bean>
<!-- SqlSessionTemplate:就是我们使用的sqlSession -->
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
<!-- 只能使用构造器注入SqlSessionFactory,因为它没有set方法 -->
<constructor-arg index="0" ref="sqlSessionFactory"/>
</bean>
<!-- 注入UserMapperImpl数据操作类 -->
<bean id="userMapper" class="com.wyf.dao.UserMapperImpl">
<property name="sqlSession" ref="sqlSession"/>
</bean>
</beans>
我们在使用Mybatis框架的时候,必然要使用SqlSessionFactory以及SqlSession。Mybatis框架整合到Spring中,该对象由MyBatis-Spring使用 SqlSessionFactoryBean 来创建,该对象需要注入一个数据源datasource,本文使用的是c3p0数据源,如上所示。
在Mybatis中,SqlSession相当于一个数据库连接,用以实现对数据库的各种操作,而Mybatis整合到Spring中,由MyBatis-Spring提供了SqlSessionTemplate代替SqlSession,如上文xml文件中的配置所示。上文中配置了一个新的UserMapper接口实现类UserMapperImpl,如下所示:
public class UserMapperImpl implements UserMapper{
private SqlSessionTemplate sqlSession;
public void setSqlSession(SqlSessionTemplate sqlSession) {
this.sqlSession = sqlSession;
}
@Override
public int insert(User sysUser) {
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
return mapper.insert(sysUser);
}
@Override
public User selectById(int id) {
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
return mapper.selectById(id);
}
@Override
public long selectUser(User sysUser) {
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
return mapper.selectUser(sysUser);
}
}
首先,该实现类注入了SqlSessionTemplate,用以执行接口定义的各项数据库操作,此实现类在单独使用Mybatis框架的时候是不需要的。此处在将Mybatis整合到Spring的过程中,就必须多创建一个UserMapperImpl类,用以执行具体的数据库操作,相比于原本的Mybatis框架,多创建的该类还是略显繁琐一些,还好,Spring提供了DAO包扫描,可以实现动态将DAO接口注入到Spring容器中,如下所示,但本文还是采用了上述的实现类的方式。
<!-- 配置扫描dao包,动态实现Dao接口注入到spring容器中-->
<!--解释 :https://www.cnblogs.com/jpfss/p/7799806.html-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!-- 注入sqlSessionFactory -->
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
<!-- 给出需要扫描的Dao接口的包 -->
<property name="basePackage" value="com.wyf.dao"/>
</bean>
2.2 Service
1. 编写接口
public interface UserService {
/**
* 新增用户
*
* @param sysUser
* @return 返回影响行数
*/
int insert(User sysUser);
/**
* 通过ID查询用户
* @param id
* @return
*/
User selectById(int id);
/**
* 查询符合登录条件的用户数
* @return
*/
long selectUser(User sysUser);
}
因为业务很简单,只是一个登录和注册,因此此处的Service功能也很简单,就是数据查询和数据插入。
2. 编写业务实现类
public class UserServiceImpl implements UserService{
private UserMapperImpl usermapper;
public void setUsermapper(UserMapperImpl usermapper) {
this.usermapper = usermapper;
}
@Override
public int insert(User sysUser) {
return usermapper.insert(sysUser);
}
@Override
public User selectById(int id) {
return usermapper.selectById(id);
}
@Override
public long selectUser(User sysUser) {
return usermapper.selectUser(sysUser);
}
}
可以看到,在此业务实现类中,注入了UserMapperImpl类,UserMapperImpl类属于DAO层,Service调用该对象实现对数据库的操作。
3. 编写spring-service.xml文件,用以配置service层编写的类。
<?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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<!--Spring整合service层 -->
<!-- 扫描service相关的bean -->
<context:component-scan base-package="com.wyf.service"/>
<!-- 将UserServiceImpl注入到IOC容器 -->
<bean id="UserServiceImpl" class="com.wyf.service.UserServiceImpl">
<property name="usermapper" ref="userMapper"/>
</bean>
<!-- 配置事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!-- 注入数据库连接池 -->
<property name="dataSource" ref="dataSource" />
</bean>
</beans>
2.3 SpringMVC
1. 前端控制器
springmvc的核心是DispatcherServlet前端控制器,所有的请求都要经过DispatcherServlet然后通过适配器分发给合适的Controller去调用Service业务来进行处理,因此DispatcherServlet在Springmvc中有着举足轻重的低位,本质上,DispatcherServlet其实是一个Servlet,下面是在web.xml中配置DispatcherServlet:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<!--DispatcherServlet-->
<servlet>
<servlet-name>DispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationConfig.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>DispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!--encodingFilter-->
<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>
<!--Session过期时间-->
<session-config>
<session-timeout>15</session-timeout>
</session-config>
</web-app>
可以看到,上述的web.xml文件就配置了一个DispatcherServlet,这也就是springmvc的优势所在,所有的请求都给了这个servlet,由该servlet通过适配器找到合适的controller来调用相应的业务层代码去进行处理。这样代码清晰明了,配置也更加简洁方便。
2. 编写Controller
@Controller
public class UserController {
@Autowired
@Qualifier("UserServiceImpl")
private UserService userService;
@GetMapping("/login")
public String getLogin(Model model) {
return "Login";
}
@PostMapping("/register")
public String getRegister(Model model){
return "Register";
}
@PostMapping("/registerUser")
public String registerGetLogin(@RequestParam("name") String name,@RequestParam("pwd") String password, Model model){
User user = new User();
user.setUserName(name);
user.setUserPassword(password);
user.setCreateTime(new Date());
int res = userService.insert(user);
return "Login";
}
@PostMapping("/login")
public String loginGetMain(@RequestParam("name") String name,@RequestParam("pwd") String password, Model model){
User user = new User();
user.setUserName(name);
user.setUserPassword(password);
long res = userService.selectUser(user);
if(res>0){
//登录成功
model.addAttribute("message","登录成功!");
return "Login";
}else{
model.addAttribute("message","用户名或密码错误,请重试!");
return "Login";
}
}
}
如上所示,所有的请求经过DispatcherServlet之后,在通过适配器找到合适的Controller去进行处理。上述请求使用了RestFul风格。
3. spring-mvc.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:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
https://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<!-- 配置SpringMVC -->
<!-- 1.开启SpringMVC注解驱动 -->
<mvc:annotation-driven />
<!-- 2.静态资源默认servlet配置-->
<mvc:default-servlet-handler/>
<!-- 3.配置jsp 显示ViewResolver视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
<!-- 4.扫描web相关的bean -->
<context:component-scan base-package="com.wyf.controller" />
</beans>
至此,相关的代码以及配置文件编写完毕,回顾一下会发现,springmvc帮我们做了太多的事情,我们真正要写的就是Controller调用Service层的业务代码以及Service调用DAO层进行数据库操作的相关代码。可以直观的感受到springmvc是如何让我们更关注于业务逻辑本身。为了将上述几个Spring配置文件融合在一起,编写applicationConfig.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<import resource="spring-dao.xml"/>
<import resource="spring-service.xml"/>
<import resource="spring-mvc.xml"/>
</beans>
2.4 View
表现层很简单,就两个页面,一个登录页面,一个注册页面。如下所示:
登录页面:
<%@ page isELIgnored="false"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<style>
.h_title{position: relative;display: inline-block;}
.box_div{
width: 100%;
}
.box_main{
position: absolute;
top:50%;
left: 50%;
transform: translate(-50%,-50%);
width: 60%;
min-width: 700px;
box-shadow: 0 0 30px #322f2f;
}
.box_main_right{
width: 50%;
height:450px;
float: left;
position: relative;
}
.box_form{
position: absolute;
top:50%;
left: 50%;
transform: translate(-50%,-50%);
}
</style>
<title>Title</title>
</head>
<body style="text-align: center">
<div class="box_div">
<div class="box_main">
<div style="width:50%;height:450px;float: left;background: blueviolet">
<br>
<h2 class="h_title">智 能 仪 表 设 备 管 理</h2>
</div>
<div class="box_main_right">
<div class="box_form">
<div style="width: 300px">
<h3 style="float: left">登 录</h3>
<c:if test="${not empty message}">
<div style="width: 100%;height: 40px;clear: left;margin-bottom: 15px;background: rgba(252,158,158,0.3);border-radius: 5px">
<P style="font-size: 17px;color: #8a1717;line-height: 40px;">${message}</P>
</div>
</c:if>
</div>
<form action="login.do" method="post" style="width: 300px;">
<input type="text" name="name" value="" placeholder="用户名" style="width: 100%;height: 40px;border-radius: 5px"><br><br>
<input type="password" name="pwd" value="" placeholder="密码" style="width: 100%;height: 40px;border-radius: 5px"><br><br>
<input type="submit"value="登 录" name="login" style="width: 100%;height: 35px;background: orange;color: white;font-size: 17px;border-radius: 5px">
</form>
<form action="register" method="post" style="width: 300px">
<input type="submit" value="新用户注册" style="width: 100%;height: 35px;background: deepskyblue;color:white;font-size: 17px;border-radius: 5px">
</form>
</div>
</div>
</div>
</div>
</body>
</html>
注册页面:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<style>
.h_title{position: relative;display: inline-block;}
.box_div{
width: 100%;
}
.box_main{
position: absolute;
top:50%;
left: 50%;
transform: translate(-50%,-50%);
width: 60%;
min-width: 700px;
box-shadow: 0 0 30px #322f2f;
}
.box_main_right{
width: 50%;
height:450px;
float: left;
position: relative;
}
.box_form{
position: absolute;
top:50%;
left: 50%;
transform: translate(-50%,-50%);
}
</style>
<title>Title</title>
</head>
<body style="text-align: center">
<div class="box_div">
<div class="box_main">
<div style="width:50%;height:450px;float: left;background: blueviolet">
<br>
<h2 class="h_title">智 能 仪 表 设 备 管 理</h2>
</div>
<div class="box_main_right">
<div class="box_form">
<div style="width: 300px">
<h3 style="float: left">注 册</h3>
</div>
<form action="registerUser" method="post" style="width: 300px;">
<input type="text" name="name" value="" placeholder="用户名" style="width: 100%;height: 40px;border-radius: 5px"><br><br>
<input type="password" name="pwd" value="" placeholder="密码" style="width: 100%;height: 40px;border-radius: 5px"><br><br>
<input type="submit"value="立即注册" name="login" style="width: 100%;height: 35px;background: orange;color: white;font-size: 17px;border-radius: 5px">
</form>
<form action="login" style="width: 300px">
<input type="submit" value="返回登录" style="width: 100%;height: 35px;background: deepskyblue;color:white;font-size: 17px;border-radius: 5px">
</form>
</div>
</div>
</div>
</div>
</body>
</html>
三、结束
本文主要以一个登录注册的小案例介绍了SSM框架的整合,登录注册也可以看作是一般项目开发的起点,可以在其基础上进行其他内容的开发。
SSM框架整合源代码:https://download.csdn.net/download/sssxlxwbwz/85090259