ssm框架整合,个人学习记录
Posted bky-min
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ssm框架整合,个人学习记录相关的知识,希望对你有一定的参考价值。
SSM框架整合
- 依赖导入
- 测试 junit
- 数据库驱动 连接池 (c3p0 dbcp druid hikari)
- servlet三连servlet jsp jstl
- mybatis mybatis-spring
- spring
- lombok
<!--junit测试-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13</version>
</dependency>
<!--数据库驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.20</version>
</dependency>
<!--c3p0 数据库连接池-->
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.5.5</version>
</dependency>
<!--servlet-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
</dependency>
<!--jsp-->
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2</version>
</dependency>
<!--jstl-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<!--mybatis-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.4</version>
</dependency>
<!--mybatis-spring整合-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.4</version>
</dependency>
<!--spring-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.6.RELEASE</version>
</dependency>
<!--spring-jdbc-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.6.RELEASE</version>
</dependency>
<!--lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
</dependency>
- 静态资源导出问题
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
</build>
model层
-
pojo
- Books
@Data @NoArgsConstructor @AllArgsConstructor public class Books { private int bookID; private String bookName; private int bookCounts; private String detail; }
-
dao
- mybatis-config.xml
<?xml version="1.0" encoding="GBK" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <!--设置 日志--> <settings> <setting name="lohImpl" value="STDOUT_LOGGING"/> </settings> <!--别名--> <typeAliases> <package name="com.min.pojo"/> </typeAliases> <!--配置数据源,整合后交给spring--> <mappers> <mapper class="com.min.dao.BookMapper"/> </mappers> </configuration>
- db.properties
jdbc.driver=com.mysql.jdbc.Driver #如果使用MySQL8.0+,需要增加一个时区配置; &serverTimezone=Asia/Shanghai jdbc.url=jdbc://mysql://localhost:3306/ssmbuild?useSSL=false&useUnicode=true&characterEncode=utf8&serverTimezone=Asia/Shanghai jdbc.username=root jdbc.password=123456
- BookMapper接口
public interface BookMapper { //增加一本书 public int addBook(Books book); //删除一本书 public int deleteBookById(@Param("bookId") int id); //更新一本书 public int updateBook(Books book); //查询一本书 public Books queryBookById(@Param("bookId") int id); //查询所有的书 public List<Books> queryAllBooks(); }
- BookMapper.xml
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.min.dao.BookMapper"> <insert id="addBook" parameterType="Books"> insert into ssmbuild.books (bookName, bookCounts,detail) values (#{bookName},#{bookCounts},#{detail}) </insert> <delete id="deleteBookById" parameterType="_int"> delete from ssmbuild.books where bookID = #{bookId} </delete> <update id="updateBook" parameterType="Books"> update ssmbuild.books set bookName = #{bookName}, set bookCounts = #{bookCounts}, set detail = #{detail} where bookID = #{bookId} </update> <select id="queryBookById" resultType="Books"> select * from ssmbuild.books where bookID = #{bookId} </select> <select id="queryAllBooks" resultType="Books"> select * from ssmbuild.books </select> </mapper>
- 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" 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"> <!--1、关联数据库配置文件--> <context:property-placeholder location="classpath:db.properties"/> <!--2、连接池 dbcp: 半自动化,不能自己连接 c3p0:自动化(自动化加载配置文件,并且自动设置到对象中) druid : hikari: --> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="driverClass" value="${jdbc.driver}}"/> <property name="jdbcUrl" value="${jdbc.url}}"/> <property name="user" value="${jdbc.username}}"/> <property name="password" value="${jdbc.password}"/> <!--c3p0连接池私有属性--> <property name="maxPoolSize" value="30"/> <property name="minPoolSize" value="10"/> <!--关闭连接后不自动commit--> <property name="autoCommitOnClose" value="false"/> <!--获取连接超时时间--> <property name="checkoutTimeout" value="10000"/> <!--当获取连接失败重试次数--> <property name="acquireRetryAttempts" value="2"/> </bean> <!--3、sqlSessionFactory--> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> <!--绑定mybatis配置文件--> <property name="configLocation" value="classpath:mybatis-config.xml"/> </bean> <!--4、配置dao接口扫描包,动态实现Dao接口可以注入到容器中--> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <!--注入sqlSessionFactory--> <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/> <!--要扫描的dao包--> <property name="basePackage" value="com.min.dao"/> </bean> </beans>
mapper实现另外两种方式
- 实现类继承SqlSessionDaoSupport
public class BookMapperImpl extends SqlSessionDaoSupport implements BookMapper { public int addBook(Books book) { return getSqlSession().getMapper(BookMapperImpl.class).addBook(book); } }
spring-dao.xml中配置4 要做如下调整
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate"> <!--只能使用构造器注入,源码分析没有set方法--> <constructor-arg index="0" ref="sqlSessionFactory"/> </bean> <bean id="userMapper" class="com.min.mapper.UserMapperImpl"> <!--需要提供SqlSessionDaoSupport的父类需要的sqlSessionFactory对象--> <property name="sqlSessionFactory" ref="sqlSessionFactory"/> </bean>
- 实现类使用SqlSessionTemplate对象
public class BookMapperImpl implements BookMapper { private SqlSessionTemplate sessionTemplate; public void setSessionTemplate(SqlSessionTemplate sessionTemplate) { this.sessionTemplate = sessionTemplate; } public int addBook(Books book) { return sessionTemplate.getMapper(BookMapperImpl.class).addBook(book); } }
spring-dao.xml中配置4 要做如下调整
<bean id="sessionTemplate" class="org.mybatis.spring.SqlSessionTemplate"> <!--只能使用构造器注入,源码分析没有set方法--> <constructor-arg index="0" ref="sqlSessionFactory"/> </bean> <bean id="userMapper" class="com.min.mapper.UserMapperImpl"> <property name="sqlSession" ref="sqlSession"/> </bean>
-
service
- BookService接口
@Service public interface BookService { //增加一本书 public int addBook(Books book); //删除一本书 public int deleteBookById(@Param("bookId") int id); //更新一本书 public int updateBook(Books book); //查询一本书 public Books queryBookById(@Param("bookId") int id); //查询所有的书 public List<Books> queryAllBooks(); }
- BookServiceImpl实现类
public class BookServiceImpl implements BookService { //service 调用 dao private BookMapper bookMapper; public void setBookMapper(BookMapper bookMapper) { this.bookMapper = bookMapper; } public int addBook(Books book) { return bookMapper.addBook(book); } public int deleteBookById(int id) { return bookMapper.deleteBookById(id); } public int updateBook(Books book) { return bookMapper.updateBook(book); } public Books queryBookById(int id) { return bookMapper.queryBookById(id); } public List<Books> queryAllBooks() { return bookMapper.queryAllBooks(); } }
- 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" 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"> <!--1、扫描service下的包--> <context:component-scan base-package="com.min.service"/> <!--2、将我们所有的业务类,注入到Spring,可以通过配置或注解实现--> <bean id="BookServiceImpl" class="com.min.service.BookServiceImpl"> <property name="bookMapper" ref="bookMapper"/> </bean> <!--3、声明式事务--> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <!--注入数据源--> <property name="dataSource" ref="dataSource"/> </bean> <!--4、aop事务支持--> <!--结合AOP实现事务的织入--> <!--配置事务通知--> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <!--给哪些方法配置事务--> <!--配置事务的传播特性: new propagation--> <tx:attributes> <tx:method name="*" propagation="REQUIRED"/> </tx:attributes> </tx:advice> <!--配置事务切入--> <aop:config> <aop:pointcut id="txPointCut" expression="execution(* com.min.dao.*.*(..))"/> <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut"/> </aop:config> </beans>
view层
-
web
- index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>首页</title> <style> a{ text-decoration: none; color: black; font-size: 18px; } h3{ width: 180px; height: 38px; margin: 100px auto; text-align: center; line-height: 38px; background-color: deepskyblue; border-radius: 5px; } </style> </head> <body> <h3> <a href="${pageContext.request.contextPath}/book/allBooks">进入数据展示页面</a> </h3> </body> </html>
- addBook.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>addBook</title> <%--BootStrap美化界面--%> <link href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"> </head> <body> <div class="container"> <div class="row clearfix"><%--清除浮动--%> <div class="col-md-12 column"><%--栅格 共12栏--%> <h1> <small>新增书籍</small> </h1> </div> </div> <form action="${pageContext.request.contextPath}/book/addBook" method="post"> <div class="form-group"> <label >书籍名称:</label> <input type="text" name="bookName" class="form-control" required> </div> <div class="form-group"> <label >书籍数量:</label> <input type="text" name="bookCounts" class="form-control" required> </div> <div class="form-group"> <label >书籍描述:</label> <input type="text" name="detail" class="form-control" required> </div> <div class="form-group"> <input type="submit" class="form-control" value="添加"> </div> </form> </div> </body> </html>
- allBook.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>allBooks.jsp</title> <%--BootStrap美化界面--%> <link href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"> </head> <body> <div class="container"> <div class="row clearfix"><%--清除浮动--%> <div class="col-md-12 column"><%--栅格 共12栏--%> <h1> <small>数据列表------展示所有书籍</small> </h1> </div> <div class="col-md-4 column"> <%--toAddBook--%> <a class="btn btn-primary" href="${pageContext.request.contextPath}/book/toAddBook">新增书籍</a> </div> <div class="col-md-8 column"> <%--查询书籍--%> <form class="form-inline" action="${pageContext.request.contextPath}/book/queryByName" method="post" style="float: right"> <span style="color: red;font-weight: bold">${msg}</span> <input type="text" name="bookName" class="form-control" placeholder="请输入要查询的书籍名称"> <input type="submit" value="查询" class="btn btn-primary"> </form> </div> </div> <div class="row clearfix"><%--清除浮动--%> <div class="col-md-12 column"><%--栅格 共12栏--%> <table class="table table-hover table-striped"><%--table-hover隔行变色--%> <thead> <tr> <th>书籍编号</th> <th>书籍名称</th> <th>书籍数量</th> <th>书籍详情</th> <th>操作</th> </tr> </thead> <%--书籍从数据库中查询出来,从这个list中遍历出来:foreach--%> <tbody> <tr> <c:forEach var="book" items="${list}"> <tr> <td>${book.bookID}</td> <td>${book.bookName}</td> <td>${book.bookCounts}</td> <td>${book.detail}</td> <td> <a href="${pageContext.request.contextPath}/book/toUpdateBook/${book.bookID}">修改</a> | <a href="${pageContext.request.contextPath}/book/deleteBook/${book.bookID}">删除</a> </td> </tr> </c:forEach> </tr> </tbody> </table> </div> </div> </div> </body> </html>
- updateBook.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>updateBook</title> <%--BootStrap美化界面--%> <link href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"> </head> <body> <div class="container"> <div class="row clearfix"><%--清除浮动--%> <div class="col-md-12 column"><%--栅格 共12栏--%> <h1> <small>更新书籍</small> </h1> </div> </div> <form action="${pageContext.request.contextPath}/book/updateBook" method="post"> <div class="form-group" hidden="hidden"> <label >书籍编号:</label> <input type="text" name="bookID" class="form-control" value="${qBook.bookID}" /> </div> <div class="form-group"> <label >书籍名称:</label> <input type="text" name="bookName" class="form-control" value="${qBook.bookName}" required/> </div> <div class="form-group"> <label >书籍数量:</label> <input type="text" name="bookCounts" class="form-control" value="${qBook.bookCounts}" required/> </div> <div class="form-group"> <label >书籍描述:</label> <input type="text" name="detail" class="form-control" value="${qBook.detail}" required/> </div> <div class="form-group"> <input type="submit" class="form-control" value="更新"> </div> </form> </div> </body> </html>
- 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"> <!--1、DispatcherServlet--> <servlet> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!--初始化web配置--> <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> <!--2、乱码过滤--> <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> <!--3、Session超时--> <session-config> <session-timeout>15</session-timeout> </session-config> </web-app>
Controller层
-
controller
- BookController
@Controller @RequestMapping("/book") public class BookController { // controller 调用 Service @Autowired @Qualifier("BookServiceImpl") private BookService bookService; public void setBookService(BookService bookService) { this.bookService = bookService; } //查询全部书籍,返回到书籍展示页面 @RequestMapping("/allBooks") public String list(Model model){ List<Books> books = bookService.queryAllBooks(); model.addAttribute("list",books); return "allBooks"; } //去新增书籍 @RequestMapping("/toAddBook") public String addBook(Model model){ return "addBook"; } //新增书籍 @RequestMapping("/addBook") public String addBook(Books books){ System.out.println("addBook => " + books); bookService.addBook(books); return "redirect:/book/allBooks"; // 重定向到@RequestMapping("/allBooks")请求 } //去更新书籍 @RequestMapping("/toUpdateBook/{bookID}") public String updateBook(@PathVariable int bookID, Model model){ Books books = bookService.queryBookById(bookID); model.addAttribute("qBook", books); return "updateBook"; } //新增书籍 @RequestMapping("/updateBook") public String updateBook(Books books){ System.out.println("updateBook => " + books); bookService.updateBook(books); return "redirect:/book/allBooks"; // 重定向到@RequestMapping("/allBooks")请求 } //删除书籍 @RequestMapping("/deleteBook/{bookID}") public String deleteBook(@PathVariable int bookID){ System.out.println("deleteID => " + bookID); bookService.deleteBookById(bookID); return "redirect:/book/allBooks"; } //根据名称查询书籍 @RequestMapping("/queryByName") public String queryBooksByName(String bookName, Model model){ System.out.println("bookName => " + bookName); model.addAttribute("msg", ""); if(bookName == null || bookName.equals("")){ model.addAttribute("msg", "请输入要查询书籍名称"); List<Books> books = bookService.queryAllBooks(); model.addAttribute("list", books); }else{ List<Books> books = bookService.queryBooksByName(bookName); model.addAttribute("list", books); } return "allBooks"; } }
- 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 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/cache http://www.springframework.org/schema/cache/spring-cache.xsd"> <!--1、注解驱动--> <mvc:annotation-driven/> <!--2、静态资源过滤--> <mvc:default-servlet-handler/> <!--3、扫描包:controller--> <context:component-scan base-package="com.min.controller"/> <!--4、视图解析器--> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <!--前缀--> <property name="prefix" value="/WEB-INF/jsp/"/> <!--后缀--> <property name="suffix" value=".jsp"/> </bean> </beans>
spring主配置
- 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"
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">
<import resource="classpath:spring-dao.xml"/>
<import resource="classpath:spring-service.xml"/>
<import resource="classpath:spring-mvc.xml"/>
</beans>
整合中的错误及解决方案 笔记
问题:service层bean不存在
步骤:
1、看这个bean注入是否成功
2、junit单元测试,看代码是否可以查询到结果
3、问题出在Spring
4、springMVC整合时没有调用到service的bean
1、applicationContext.xml 没有注入bean
2、web.xml中,我们也绑定过配置文件,发现配置的是mvc.xml
解决方式:web.xml中引用spring核心配置文件!
问题:更新操作提交更新的SQL,但是修改失败
1、初次考虑是事务问题,显式声明事务后依旧失败
2、查看sql语句打印结果,没有传送id
解决方式:前端隐藏域传递id
问题:29-May-2020 14:13:14.568 严重 [http-nio-8080-exec-4]
org.springframework.web.servlet.FrameworkServlet.
initServletBean Context initialization failed
org.springframework.beans.factory.BeanCreationException:
Error creating bean with name ‘sqlSessionFactory‘
defined in class path resource [spring-dao.xml]:
Invocation of init method failed; nested exception
is org.springframework.core.NestedIOException:
Failed to parse config resource: class path resource
[mybatis-config.xml]; nested exception is
org.apache.ibatis.builder.BuilderException:
Error parsing SQL Mapper Configuration.
Cause: org.apache.ibatis.builder.BuilderException:
The setting lohImpl is not known.
Make sure you spelled it correctly (case sensitive).
1、检查spring-dao.xml的配置文件引用,没有问题
2、检查mybatis-config.xml配置,发现setting中新增日志书写问题
解决方式:<setting name="logImpl" value="STDOUT_LOGGING"/>书写错误处理
问题:模糊查询拼接问题
解决方式:1、在调用处手动的去添加“%”通配符
2、%#{bookName}%程序会报错,原因是:缺少单引号。
3、‘%#{bookName}%’程序依然会报错,原因是:如果加上单引号,那么就当成是一个字符串,而#{ }写在字符串中不能识别,要改写成${ }这种形式
4、借助mysql的函数concat(‘%‘,#{bookName},‘%‘)
问题:applicationContext配置包扫描
解决方式:<!--自动扫描指定的包,包中的所有注解交由Spring管理-->
<context:component-scan base-package="com.min.controller"/>
问题:com.sun.org.apache.xerces.internal.impl.io.MalformedByteSequenceException:
1 字节的 UTF-8 序列的字节 1 无效。
解决方式:<?xml version="1.0" encoding="GBK"?>修改配置文件字符集GBK
以上都是个人学习随笔,获取详细资料和视频资源可以移步B站狂神说~
@狂神说
以上是关于ssm框架整合,个人学习记录的主要内容,如果未能解决你的问题,请参考以下文章