我們都知道SSM框架是Java中使用非常多的框架,雖然現在流行SpringBoot框架。但是SSM框架依舊有公司在用,這篇博客也是爲了剛剛學習SSM框架的Java開發者後期整合做準備,也是我回顧SSM框架整合流程的一個總結。
SSM整合就是將Spring與Mybatis整合,SM需要中間件充當整合的橋樑。Spring與SpringMVC整合,SS整合不需要中間件。
在Java中,中間件就是一堆具有某個功能的jar包,因爲Java都是類class,而jar包又是類的集合。
這裏使用Maven來創建Web工程,這樣方便我們管理項目中所需要的依賴。那麼接下來我們就開始整合SSM框架。
SSM整合所需要的依賴
我們先引入日誌依賴,因爲每個項目都需要日誌來記錄項目中的任何事情。不管是開發中在控制檯打印日誌,還是上線後將日誌輸出到文件中
這裏日誌類庫我們採用sl4j + log4j2
,所需的依賴如下:
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>2.7</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-web</artifactId>
<version>2.7</version>
</dependency>
接下來我們引入數據庫相關的依賴:mysql驅動包,Druid數據庫連接池,mybatis框架包,spring整合mybatis的橋樑jar包
<!-- mysql jdbc驅動包 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
<scope>runtime</scope>
</dependency>
<!--Druid數據庫連接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.20</version>
</dependency>
<!-- mybatis框架包 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.2</version>
</dependency>
<!-- mybatis和spring整合依賴包 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.2</version>
</dependency>
然後我們引入spring框架的依賴
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.1.10.RELEASE</version>
</dependency>
哎,spring框架不是有很多jar包嗎,這裏爲啥只引入一個,我們通過下面一張圖來解釋…
我們知道Maven的一個作用就是依賴管理,引入一個依賴就會把它所依賴的jar包也引進來,所以我們無需把spring的每個依賴都引一遍。
上面我們看到AOP的依賴也引入進來,但是要使用AOP技術,還是要其他jar包的支持
<!--spring AOP和aspectj框架整合的模塊-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>5.1.10.RELEASE</version>
</dependency>
接下來引入spring jdbc和事務相關的依賴
<!--spring 支持jdbc 編程模塊-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.1.10.RELEASE</version>
</dependency>
然後我們再引入javaweb相關依賴
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
最後我們把springmvc默認解析json的jar包和文件上傳的jar包引進來
<!-- spring-json依賴 -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.8</version>
</dependency>
<!--文件上傳-->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.3</version>
</dependency>
這樣我們就把ssm整合基本需要的jar包都引進來了,整合時只需要把上面的jar包歸總即可。
我也看過其他ssm整合的博客,都是把spring全部的依賴都加進來,雖然不影響功能的實現。畢竟我們使用了Maven管理項目,所以儘可能的理清每個依賴所關聯的依賴,而不是把全部的spring依賴都加進來。
依賴搞定了,接下來我們就開始配置文件的編寫,不得不說ssm最大弊病就是配置文件太多,寫錯一點配置就可能查找半天原因。這也是爲什麼springboot這麼火的原因–零XML配置
等其他特性。
log4j2.xml
上面引入的日誌類庫需要配置文件的支持才能生效
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!--先定義所有的appender-->
<appenders>
<!--輸出控制檯的配置-->
<console name="Console" target="SYSTEM_OUT">
<!--輸出日誌的格式-->
<!--<patternlayout pattern="%d{yyyy-MM-dd HH:mm:ss} [%p] %c %m
%n"/>-->
<patternlayout pattern="[%p] %m %n"/>
</console>
</appenders>
<!-- 然後定義logger,只有定義了logger並引入的appender,appender纔會生效-->
<!-- 日誌級別以及優先級排序: OFF > FATAL > ERROR > WARN > INFO > DEBUG > TRACE > ALL -->
<loggers>
<root level="DEBUG">
<!--輸出到控制檯-->
<appender-ref ref="Console"/>
</root>
<!--org.springframework
<logger name="org.springframework" level="INFO"/>-->
</loggers>
</configuration>
db.properties
我們把數據源的相關配置單獨放在一個文件中
jdbc.username=root
jdbc.password=root用戶的密碼
jdbc.url=jdbc:mysql://127.0.0.1:3306/ssm?useSSL=false&serverTimezone=Asia/Shanghai
jdbc.driverClassName=com.mysql.jdbc.Driver
#初始化連接數大小
jdbc.initialSize=5
applicationContext.xml
這是spring的核心配置文件,把數據源,sqlSessionFactory交給了spring IOC容器管理,以及開啓了註解式事務。
<?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:tx="http://www.springframework.org/schema/tx"
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
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<!--掃描service層組件-->
<context:component-scan base-package="cn.zwq.ssm.service"/>
<!--讀取外部配置文件-->
<context:property-placeholder location="classpath:application.properties"/>
<!--將Druid數據源交給Spring IOC容器來管理-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
<property name="url" value="${jdbc.url}"/>
<property name="driverClassName" value="${jdbc.driverClassName}"/>
<property name="initialSize" value="${jdbc.initialSize}"/>
</bean>
<!--SqlSessionFactory 會話工廠交給spring容器管理-->
<bean name="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!--注入數據源-->
<property name="dataSource" ref="dataSource"/>
<!--配置Mapper映射文件的位置-->
<property name="mapperLocations" value="classpath:mapper/*/*Mapper.xml"/>
</bean>
<!--配置Mapper接口的掃描器-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!--配置mapper接口所在的包-->
<property name="basePackage" value="cn.zwq.ssm.mapper"/>
<!--注入會話工廠-->
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
</bean>
<!--配置jdbc的事務管理器-->
<bean name="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!--注入數據源-->
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- 啓用註解事務 -->
<tx:annotation-driven transaction-manager="txManager"/>
</beans>
springmvc.xml
這是springmvc的配置文件,配置了視圖解析器,文件上傳,以及開放所有的靜態資源
<?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:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!--開啓Controller層註解掃描-->
<context:component-scan base-package="cn.zwq.ssm.controller"/>
<!--springmvc註解支持-->
<mvc:annotation-driven/>
<!--不攔截靜態資源-->
<mvc:default-servlet-handler/>
<!--視圖解析器-->
<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>
<!--文件上傳解析器-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 限制文件上傳總大小,不設置默認沒有限制,單位爲字節 200*1024*1024即200M -->
<property name="maxUploadSize" value="209715200" />
<!-- 設置每個上傳文件的大小上限 1024*1024*2 2M -->
<property name="maxUploadSizePerFile" value="2019152"/>
<!-- 處理文件名中文亂碼 -->
<property name="defaultEncoding" value="UTF-8" />
<!-- resolveLazily屬性啓用是爲了推遲文件解析,以便捕獲文件大小異常 -->
<property name="resolveLazily" value="true" />
</bean>
</beans>
web.xml
在web.xml中配置了初始化spring容器的監聽器,以及前端控制器和編碼過濾器
<?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">
<!-- spring 核心配置文件位置 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<!-- 服務啓動監聽,web應用啓動的時候初始化Spring核心IOC容器 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- 配置前端控制器 -->
<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:springmvc.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!-- 配置字符集編碼過濾器 -->
<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>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>characterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
這樣ssm整合的基本配置已經完成了,接下來我們對用戶表進行增刪改查,來驗證我們ssm整合是否正確可行。
我們上面在配置數據源的時候,指定連接到ssm數據庫,所有我們先創建ssm數據庫,再在其中創建用戶表。
用戶表語句
我們通過下面sql語句創建用戶表並插入6條記錄
create database if no exist `ssm`;
use `ssm`;
CREATE TABLE `users` (
`uid` int(10) NOT NULL AUTO_INCREMENT COMMENT '用戶id',
`uname` varchar(255) DEFAULT NULL COMMENT '用戶姓名',
`pwd` varchar(255) DEFAULT NULL COMMENT '用戶密碼',
`sex` int(1) DEFAULT NULL COMMENT '用戶性別,1:男,0:女',
`age` int(3) DEFAULT NULL COMMENT '用戶年齡',
PRIMARY KEY (`uid`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
INSERT INTO users VALUES(1,"張三","zs",1,21);
INSERT INTO users VALUES(2,"李四","ls",0,18);
INSERT INTO users VALUES(3,"王五","ww",0,20);
INSERT INTO users VALUES(4,"趙六","zl",1,26);
INSERT INTO users VALUES(5,"十七","sq",0,22);
INSERT INTO users VALUES(6,"阿什","as",1,25);
用戶實體類
在類上面我們使用Lombok的@Data註解幫我們簡化代碼,該註解會自動生成getter、setter、toString等方法
@Data
public class User {
private Integer uid;
private String uname;
private String pwd;
private Integer sex;
private Integer age;
}
UserMapper
這是操作用戶表數據的持久化接口,使用註解的方式實現,
public interface UserMapper {
//查詢全部用戶
@Select("select * from users")
List<User> selectAll();
//根據id查詢用戶
@Select("select * from users where uid = #{uid}")
User selectByPrimaryKey(Integer uid);
//根據id修改用戶
void updateByPrimaryKeySelective(User user);
//保存用戶
void insertSelective(User user);
//根據id刪除用戶
@Delete("delete from users where uid = #{uid}")
void deleteByPrimaryKey(Integer uid);
}
UserService與UserServiceImpl
UserService
public interface UserService {
/*查詢所有用戶*/
List<User> queryAllUser();
/*根據用戶id查詢用戶*/
User queryUserByUid(Integer uid);
/*根據用戶id修改用戶信息*/
void updateUserByUid(User user);
/*添加用戶*/
void addUser(User user);
/*根據用戶id刪除用戶*/
void deleteUserByUids(Integer[] uids);
}
UserServiceImpl
我們在類上加入@Transactional表明啓動註解式事務
@Service
@Transactional
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;
@Override
public List<User> queryAllUser() {
return userMapper.selectAll();
}
@Override
public User queryUserByUid(Integer uid) {
return userMapper.selectByPrimaryKey(uid);
}
@Override
public void updateUserByUid(User user) {
userMapper.updateByPrimaryKeySelective(user);
}
@Override
public void addUser(User user) {
userMapper.insertSelective(user);
}
/*根據用戶id刪除用戶*/
@Override
public void deleteUserByUids(Integer[] uids) {
/*Stream流+方法引用+lambda表達式簡化刪除代碼*/
Stream.of(uids).forEach(userMapper::deleteByPrimaryKey);
}
}
UserController
我們知道在類上加入@Controller註解表示該類是控制器,用來接收並響應客戶端的請求。
而@RestController是由@Controller和@ResponseBody組成,表示該類中的所有方法都是返回Json數據。
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
/*查詢所有用戶*/
@RequestMapping("/queryAllUser")
public List<User> queryAllUser() {
return userService.queryAllUser();
}
/*根據用戶id查詢用戶*/
@RequestMapping("/queryUserByUid/{uid}")
public User queryUserByUid(@PathVariable("uid") Integer uid) {
return userService.queryUserByUid(uid);
}
/*根據用戶id修改用戶信息*/
@RequestMapping("/updateUserByUid")
public boolean updateUserByUid(User user) {
try {
userService.updateUserByUid(user);
return true;
}catch (Exception e){
return false;
}
}
/*添加用戶*/
@RequestMapping("/addUser")
public Boolean addUser(User user) {
try {
userService.addUser(user);
return true;
}catch (Exception e){
return false;
}
}
/*根據用戶id刪除用戶*/
@RequestMapping("/deleteUserByUids")
public Boolean deleteUserByUids(Integer[] uids) {
try {
userService.deleteUserByUids(uids);
return true;
}catch (Exception e){
return false;
}
}
}
我們使用postman工具
來測試我們上面方法的效果。Postman工具是專門用來向服務器發起請求,然後得到最原始的響應數據。
我們先測試查詢全部用戶的接口:http://localhost:8080/ssm/user/queryAllUser
剩下的幾個方法也測試過,是🆗的。這樣我們就把ssm整合完畢,並且通過對用戶模塊的操作驗證了是可行的,以後需要使用ssm框架的時候,也可以拿這個來當ssm框架的基本骨架。
這次整合ssm框架的源碼