寫在前面
在學習完了MyBatis、Spring、SpringMVC之後,現在進行SSM的整合,寫一個簡單的項目
整體項目結構,因為圖檔上傳好像出了點問題,目錄如下
-src
-main
-java
-com.michilay
-controller
BooksController(java)
-dao
BooksMapper(interface)
-pojo
Books(java)
-service
BooksService(interface)
BooksServiceImpl(java)
-resources
-com.mihcilay.dao
BooksMapper.xml
applicationContext.xml
jdbc.properties
rebel.xml
spring-dao.xml
spring-mvc.xml
spring-service.xml
-web
-WEB-INF
-jsp
test.jsp
web.xml
index.jsp
pom.xml
資料庫準備
CREATE TABLE books (
bookID int(10) not null auto_increment comment '書id',
bookName varchar(100) not null comment '書名',
bookCounts int(11) not null comment '數量',
detail varchar(200) not null comment '描述',
key bookID (bookID)
) engine=innodb default charset=utf8
INSERT INTO `books` VALUES (1, 'java', 1, '從入門到放棄');
INSERT INTO `books` VALUES (2, 'MySQL', 10, '從删庫到跑路');
INSERT INTO `books` VALUES (3, 'Linux', 4, '從進門到進牢');
建立項目
建立一個普通的Maven項目, 導入以下依賴
<dependencies>
<!-- 資料庫連接配接-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.26</version>
</dependency>
<!-- 單元測試-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<!-- servlet-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2</version>
<scope>provided</scope>
</dependency>
<!-- Mybatis-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.7</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.6</version>
</dependency>
<!-- spring-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.9</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.3.9</version>
</dependency>
<!-- 簡化代碼-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.20</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.6</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.3.5</version>
<scope>test</scope>
</dependency>
</dependencies>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.9.7</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.7</version>
</dependency>
idea連接配接資料庫(這一步可省略,隻是為了友善
MyBatis層
相關配置檔案
mybatis-config配置檔案如下
<?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>
<!-- 導入外部的資源檔案-->
<properties resource="jdbc.properties"/>
<typeAliases>
<package name="com.michilay.dao"/>
</typeAliases>
<!-- 配置資料庫的環境-->
<environments default="mysql">
<environment id="mysql">
<!-- 使用jdbc資料管理-->
<transactionManager type="JDBC"></transactionManager>
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>
<!-- 導入映射檔案-->
<mappers>
<package name="com.michilay.dao"/>
</mappers>
</configuration>
jdbc.properties配置自己的資料庫
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/ssm_db?serverTimezone=UTC&characterEncoding=utf-8
jdbc.username=root
jdbc.password=123456
實體類和接口方法方法
Books實體類
package com.michilay.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Books {
private int bookID;
private String bookName;
private int bookCounts;
private String detail;
}
BooksMapper持久層操作接口
package com.michilay.dao;
import com.michilay.pojo.Books;
import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface BooksMapper {
// 增加一本書
int addBook(Books books);
// 删除一本書
int deleteBookById(@Param("bookID") int id);
// 更新一本書
int updateBook(Books books);
// 查找
Books findBookById(@Param("bookID") int id);
List<Books> findAllBook();
}
BooksMapper實作方法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.michilay.dao.BooksMapper">
<insert id="addBook" parameterType="Books">
insert into books (bookName, bookCounts, detail)
value (#{bookName},#{bookCounts},#{detail})
</insert>
<delete id="deleteBookById" parameterType="int">
delete from books where bookID = #{bookID}
</delete>
<update id="updateBook" parameterType="Books">
update books
<set>
<if test="bookName != null">
bookName = #{bookName}
</if>
<if test="bookCounts != 0">
bookCounts = #{bookCounts}
</if>
<if test="detail != null">
detail = #{detail}
</if>
</set>
where bookID = #{bookID}
</update>
<select id="findBookById" resultType="Books">
select * from books where bookID = #{bookID}
</select>
<select id="findAllBook" resultType="Books">
select * from books
</select>
</mapper>
注意:這裡建立包的時候,和java不同,java中建立的包是com.michilay.dao,但是resources檔案夾下建立包應該寫成com/michilay/dao,包括後面建立web下的目錄也是要用/
測試類
import com.michilay.dao.BooksMapper;
import com.michilay.pojo.Books;
import lombok.SneakyThrows;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
public class MyBatisTest {
static SqlSession ss = null;
static BooksMapper getMapper(){
InputStream resourceAsStream = null;
try {
resourceAsStream = Resources.getResourceAsStream("mybatis-config.xml");
} catch (IOException e) {
e.printStackTrace();
}
SqlSessionFactory build = new SqlSessionFactoryBuilder().build(resourceAsStream);
ss = build.openSession();
BooksMapper mapper = ss.getMapper(BooksMapper.class);
return mapper;
}
@SneakyThrows
@Test
public void testFindAll(){
BooksMapper mapper = MyBatisTest.getMapper();
List<Books> allBook = mapper.findAllBook();
for (Books books : allBook) {
System.out.println(books);
}
}
@SneakyThrows
@Test
public void testFindById(){
BooksMapper mapper = MyBatisTest.getMapper();
Books bookById = mapper.findBookById(1);
System.out.println(bookById);
}
@Test
public void testAdd(){
BooksMapper mapper = MyBatisTest.getMapper();
Books books1 = new Books(4, "測試書本4",14,"測試細節4");
mapper.addBook(books1);
ss.commit();
ss.close();
testFindAll();
}
@Test
public void testDelete(){
BooksMapper mapper = MyBatisTest.getMapper();
mapper.deleteBookById(4);
ss.commit();
ss.close();
testFindAll();
}
@Test
public void testUpdate(){
BooksMapper mapper = MyBatisTest.getMapper();
Books books = new Books();
books.setBookID(6);
books.setDetail("更改後的詳情");
mapper.updateBook(books);
ss.commit();
ss.close();
testFindAll();
}
}
測試沒有問題後進入下一階段
Spring層
将mybatis配置引入到spring中,spring-dao.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:mvc="http://www.springframework.org/schema/mvc"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://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/mvc
https://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd">
<context:component-scan base-package="com.michilay.dao"/>
<!-- 關聯配置檔案-->
<context:property-placeholder location="classpath:jdbc.properties"/>
<!-- 連結池,dbcp(半自動化操作,手動連接配接),c3p0(自動化操作,自動化加載配置文集,自動設定到對象
druid,hikari-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="typeAliasesPackage" value="com.michilay.pojo"/>
<property name="mapperLocations" value="classpath:com/michilay/dao/*.xml"/>
</bean>
<!-- 配置dao接口掃描包,動态實作dao接口自動注入-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!-- 要掃描的dao包-->
<property name="basePackage" value="com.michilay.dao"/>
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
</bean>
</beans>
Spring和服務層的整合配置檔案spring-service.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:aop="http://www.springframework.org/schema/aop"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://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
https://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- 掃描包-->
<context:component-scan base-package="com.michilay.service"/>
<!-- 聲明式事務-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!-- 注入資料源-->
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- aop事務支援-->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="*" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut id="txPointCut" expression="execution(* com.michilay.dao.*.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut"/>
</aop:config>
</beans>
總配置檔案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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<import resource="classpath:spring-dao.xml"/>
<import resource="classpath:spring-service.xml"/>
</beans>
service層
package com.michilay.service;
import com.michilay.pojo.Books;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Service;
import java.util.List;
public interface BooksService {
// 增加一本書
int addBook(Books books);
// 删除一本書
int deleteBookById(int id);
// 更新一本書
int updateBook(Books books);
// 查找
Books findBookById(int id);
List<Books> findAllBook();
}
package com.michilay.service;
import com.michilay.dao.BooksMapper;
import com.michilay.pojo.Books;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@Service("booksService")
public class BooksServiceImpl implements BooksService{
private BooksMapper booksMapper;
@Autowired
public void setBooksMapper(BooksMapper booksMapper) {
this.booksMapper = booksMapper;
}
@Override
public int addBook(Books books) {
return booksMapper.addBook(books);
}
@Override
public int deleteBookById(int id) {
return booksMapper.deleteBookById(id);
}
@Override
public int updateBook(Books books) {
return booksMapper.updateBook(books);
}
@Override
public Books findBookById(int id) {
return booksMapper.findBookById(id);
}
@Override
public List<Books> findAllBook() {
return booksMapper.findAllBook();
}
}
加上注解
在BooksMapper前加上@Repository
測試類
import com.michilay.dao.BooksMapper;
import com.michilay.pojo.Books;
import com.michilay.service.BooksService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import java.util.List;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class SpringTest {
@Autowired
public BooksService booksService;
@Test
public void test1() throws Exception{
List<Books> allBook = booksService.findAllBook();
for (Books books : allBook) {
System.out.println(books);
}
}
@Test
public void test2(){
ApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
BooksMapper bean = classPathXmlApplicationContext.getBean("booksMapper", BooksMapper.class);
List<Books> allBook = bean.findAllBook();
for (Books books : allBook) {
System.out.println(books);
}
}
}
一個是對spring的測試,一個是對spring整合mybatis的測試,通過後進入下一步
SpringMVC層
給項目添加WEB架構支援
web.xml
<?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">
<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>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<filter>
<filter-name>encoding</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>encoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<session-config>
<session-timeout>15</session-timeout>
</session-config>
</web-app>
SpringMVC配置檔案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:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://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/mvc
https://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!-- 自動掃描包-->
<context:component-scan base-package="com.michilay.controller"/>
<!-- 讓spring mvc不處理靜态的資料-->
<mvc:default-servlet-handler/>
<!-- 代替了HandlerMapping和HandlerAdapter,自動開啟自動注入-->
<mvc:annotation-driven/>
<!--視圖解析器:DispatcherServlet給他的ModelAndView-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver">
<!-- 轉發的字首合字尾-->
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
</beans>
記得要在總配置檔案applicationContext中加上
配置環境
- 在項目結構中,建立lib,導入所有的jar包
- 在Tomcat中配置Tomcat 8.5,并且更改路徑
- 将項目的Jrebel打上勾(可省略,熱部署用的插件,提高效率)
編寫Conroller進行測試
package com.michilay.controller;
import com.michilay.pojo.Books;
import com.michilay.service.BooksService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import java.util.List;
@Controller
public class BooksController {
@Autowired
private BooksService booksService;
@RequestMapping("/t1")
public String test1(Model model){
model.addAttribute("msg","SpringMvc層測試通過");
return "test";
}
@RequestMapping("/t2")
public String list(Model model){
List<Books> allBook = booksService.findAllBook();
model.addAttribute("msg",allBook);
return "test";
}
}
測試完成就表示整合好了,前端可以從資料庫拿到資料顯示了,實作了ssm架構,下面就是進一步的優化了
寫在後面
整合過程中會遇到很多的問題,這不是壞事,對這些問題,一步一步的排查,總會找到問題所在的
在寫完這邊文章後,我又從頭按照自己的教程重來了一遍,耗時兩個小時,中間也出了不少錯誤,很多都是因為自己沒看仔細造成的,不過還是覺得,在學完了ssm三大原理之後再進行整合的學習,是有效學習,出錯也是一種學習,因為我知道他錯誤在哪個環節。