1、环境要求
IDEA
MySQL 5.7
Tomcat 9
Maven 3.6
需要熟练掌握MySQL数据库,Spring,JavaWeb及Mybatis知识,基本的前端知识;
2、数据库环境
create database ssmbuild;
use ssmbuild;
drop table id exists `books`;
CREATE TABLE `books` (
`book_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '书id',
`book_name` varchar(255) NOT NULL COMMENT '名书',
`book_counts` int(11) NOT NULL COMMENT '量数',
`detail` varchar(255) NOT NULL COMMENT '描述',
PRIMARY KEY (`book_id`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8
3、基本环境搭建
1、新建maven项目,添加web支持
2、pom依赖导入
junit
junit
4.12
mysql
mysql-connector-java
5.1.47
com.mchange
c3p0
0.9.5.2
javax.servlet
servlet-api
2.5
javax.servlet.jsp
jsp-api
2.2
javax.servlet
jstl
1.2
org.mybatis
mybatis
3.5.5
org.mybatis
mybatis-spring
2.0.5
org.springframework
spring-jdbc
5.2.7.RELEASE
org.springframework
spring-webmvc
5.2.8.RELEASE
3、maven资源过滤问题
src/main/java
**/*.properties
**/*.xml
false
src/main/resources
**/*.properties
**/*.xml
false
4、建立基本的结构和框架配置
mybatis-config.xml:
xml version="1.0" encoding="UTF-8" ?>
br /> PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
applicationContext.xml:
xml version="1.0" encoding="UTF-8"?>
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">
4、Mybatis层编写
1、数据库配置文件database.properties
driver=com.mysql.jdbc.Driver
# 如果使用的是MySQL 8.0+ 需要增加一个时区的配置 serverTimezone=UTC
url=jdbc:mysql://localhost:3306/ssmbuild?useSSL=true&useUnicode=true&characterEncoding=utf
username=root
password=123465
2、IDEA关联数据库
3、编写mybatis核心配置文件
xml version="1.0" encoding="UTF-8" ?>
br /> PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
name="mapUnderscoreToCamelCase" value="true"/>
name="com.spong.pojo"/>
4、pojo下创建实体类
Books
(可选择)使用lombok插件生成有参、无参构造及get、set方法
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Books {
private Integer bookId;
private String bookName;
private Integer bookCounts;
private String detail;
}
5、编写dao层
BookMapper接口
public interface BookMapper {
//新增一本书
int addBook(Books books);
//删除一本书
//@Param 作用是用于传递参数,从而可以与SQL中的的字段名相对应
int deleteBook(@Param("bookId") Integer id);
//修改一本书
int updateBook(Books books);
//查询一本书
Books queryBookById(@Param("bookId") Integer id);
//查询所有书
ListqueryAllBooks();
}
BookMapper.xml实现BookMapper接口
xml version="1.0" encoding="UTF-8" ?>
br /> PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
namespace="com.spong.dao.BookMapper">
id="addBook" parameterType="Books">
insert into ssmbuild.books(book_name, book_counts, detail)
values (#{bookName},#{bookCounts},#{detail});
id="deleteBook" parameterType="Integer">
delete from ssmbuild.books
where book_id=#{bookId};
id="updateBook" parameterType="Books">
update ssmbuild.books
set book_name=#{bookName},
book_counts=#{bookCounts},
detail=#{detail}
where book_id=#{bookId};
id="queryBookById" parameterType="Integer" resultType="Books">
select *
from ssmbuild.books
where book_id=#{bookId};
id="queryAllBooks" resultType="Books">
select * from ssmbuild.books;
每创建一个mapper就在mybatis核心配置文件中配置
class="com.spong.dao.BookMapper"/>
6、编写service层
service层调用dao层,使用组合
BookService
public interface BookService {
//新增一本书
int addBook(Books books);
//删除一本书
int deleteBook(Integer id);
//修改一本书
int updateBook(Books books);
//查询一本书
Books queryBookById(Integer id);
//查询所有书
ListqueryAllBooks();
}
BookServiceImpl
public class BookServiceImpl implements BookService {
//service层调用dao层 组合Dao
private BookMapper bookMapper;
public void setBookMapper(BookMapper bookMapper) {
this.bookMapper = bookMapper;
}
public int addBook(Books books) {
return bookMapper.addBook(books);
}
public int deleteBook(Integer id) {
return bookMapper.deleteBook(id);
}
public int updateBook(Books books) {
return bookMapper.updateBook(books);
}
public Books queryBookById(Integer id) {
return bookMapper.queryBookById(id);
}
public ListqueryAllBooks() {return bookMapper.queryAllBooks();
}
}
5、Spring层编写
1、spring-dao.xml配置
Spring关联数据库配置文件
location="classpath:database.properties"/>连接池(这里使用c3p0)
id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
name="driverClass" value="${driver}"/>
name="jdbcUrl" value="${url}"/>
name="user" value="${username}"/>
name="password" value="${password}"/>
name="maxPoolSize" value="30"/>
name="minPoolSize" value="10"/>
name="autoCommitOnClose" value="false"/>
name="checkoutTimeout" value="10000"/>
name="acquireRetryAttempts" value="2"/>注册SQLSessionFactory
id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
name="dataSource" ref="dataSource"/>
name="configLocation" value="classpath:mybatis-config.xml"/>扫描dao包,动态注入到Spring容器中
class="org.mybatis.spring.mapper.MapperScannerConfigurer">
name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
name="basePackage" value="com.spong.dao"/>
2、Spring-service.xml配置(事务)
扫描service下的包,实现动态注入
base-package="com.spong.service"/>也可以选择直接配置service实现类(1,2选一)
id="BookServiceImpl" class="com.spong.service.BookServiceImpl">
name="bookMapper" ref="bookMapper"/>声明事务配置
id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
name="dataSource" ref="dataSource"/>AOP事务(根据需要添加)
https://www.cnblogs.com/spang/p/13488174.html 供参考
6、SpringMVC层编写
1、web.xml配置
DispatcherServlet 配置
dispatcherServlet
org.springframework.web.servlet.DispatcherServlet
contextConfigLocation
classpath:spring-mvc.xml
dispatcherServlet
/Filter过滤器
encodingFilter
org.springframework.web.filter.CharacterEncodingFilter
encodingFilter
/*注意这里的url-pattern需要 /* 即jsp页面也需要过滤
关于web.xml的url映射的小知识:
< url-pattern>/ 会匹配到/login这样的路径型url,不会匹配到模式为*.jsp这样的后缀型url
< url-pattern>/* 会匹配所有url:路径型的和后缀型的url(包括/login,*.jsp,*.js和*.html等)Session相关配置
15
2、Spring-mvc.xml配置
base-package="com.spong.controller"/>
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
name="prefix" value="/WEB-INF/jsp/"/>
name="suffix" value=".jsp"/>
最后将所有配置文件在applicationContext.xml文件中整合:
xml version="1.0" encoding="UTF-8"?>
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">
resource="classpath:spring-dao.xml"/>
resource="classpath:spring-service.xml"/>
resource="classpath:spring-mvc.xml"/>
到此框架整合完毕,开始视图层和controller层的编写
7、Controller层及视图页面
1.BookController类编写 方法一:查询全部书籍
@Controller
@RequestMapping("/books")
public class BookController {
//Controller层调Service层
//Spring容器自动注入其中的bookService
@Autowired
private BookService bookService;
//查询全部书籍,并返回一个显示所有书籍的页面
@RequestMapping("/allBooks")
public String queryAllBooks(Model model){
List booksList = bookService.queryAllBooks();
model.addAttribute("booksList",booksList);return "allBooks";
}
}
2、书籍列表页面:
"text/html;charset=UTF-8" language="java" %>
新增书籍
"stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" >
class="container">
class="row clearfix">
class="col-md-12 column">
class="page-header">
书籍列表————新增书籍
"${pageContext.request.contextPath}/books/addBook" method="post">
class="form-group">for="bookName">书籍名称"text" name="bookName" class="form-control" id="bookName" required>
class="form-group">for="bookCounts">书籍数量"text" name="bookCounts" class="form-control" id="bookCounts" required>
class="form-group">for="detail">书籍详情"text" name="detail" class="form-control" id="detail" required>
"submit" class="btn btn-default">添加
3.方法二 添加书籍
//跳转到书籍添加页面
@RequestMapping("/toAddBook")
public String toAddBook(){
return "addBook";
}
//添加书籍
@RequestMapping("/addBook")
public String addBook(Books books){
System.out.println("addBook=>"+books);
bookService.addBook(books);
return "redirect:/books/allBooks"; //重定向到首页
}
4.新增书籍链接以及页面
跳转
class="col-md-4 column">class="btn btn-primary" href="${pageContext.request.contextPath}/books/toAddBook">新增书籍
页面
"text/html;charset=UTF-8" language="java" %>
新增书籍
"stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" >
class="container">
class="row clearfix">
class="col-md-12 column">
class="page-header">
书籍列表————新增书籍
"${pageContext.request.contextPath}/books/addBook" method="post">
class="form-group">for="bookName">书籍名称"text" name="bookName" class="form-control" id="bookName" required>
class="form-group">for="bookCounts">书籍数量"text" name="bookCounts" class="form-control" id="bookCounts" required>
class="form-group">for="detail">书籍详情"text" name="detail" class="form-control" id="detail" required>
"submit" class="btn btn-default">添加
5、方法三 修改书籍
//跳转到修改页面
@RequestMapping("/toUpdateBook")
public String toUpdateBook(Integer id, Model model){
System.out.println(id);
Books books = bookService.queryBookById(id);
model.addAttribute("qBook",books);
return "updateBook";
}
//修改书籍
@RequestMapping("/updateBook")
public String updateBook(Books books){
System.out.println("updateBook=>"+books);
bookService.updateBook(books);
return "redirect:/books/allBooks";
}
6、链接以及修改书籍页面
"${pageContext.request.contextPath}/books/toUpdateBook?id=${book.bookId}">修改
"text/html;charset=UTF-8" language="java" %>
修改书籍
"stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" >
class="container">
class="row clearfix">
class="col-md-12 column">
class="page-header">
书籍列表————修改书籍
"${pageContext.request.contextPath}/books/updateBook" method="post">"hidden" name="bookId" value="${qBook.bookId}">
class="form-group">for="bookName">书籍名称"text" name="bookName" class="form-control" id="bookName" value="${qBook.bookName}" required>
class="form-group">for="bookCounts">书籍数量"text" name="bookCounts" class="form-control" id="bookCounts" value="${qBook.bookCounts}" required>
class="form-group">for="detail">书籍详情"text" name="detail" class="form-control" id="detail" value="${qBook.detail}" required>
"submit" class="btn btn-default">修改
7、方法四 删除书籍
//删除书籍
@RequestMapping("/deleteBook")
public String deleteBook(Integer id){
System.out.println("deleteBookId=>"+id);
bookService.deleteBook(id);
return "redirect:/books/allBooks";
}
8、删除链接
"${pageContext.request.contextPath}/books/deleteBook?id=${book.bookId}">删除
8、最终框架结构如下
BookController:
@Controller
@RequestMapping("/books")
public class BookController {
//Controller层调Service层
@Autowired
private BookService bookService;
//books为空时 查询全部书籍,并返回一个显示所有书籍的页面
//books.bookName有值时,模糊查询
@RequestMapping("/allBooks")
public String queryAllBooks(Books books,Model model){
System.out.println(books);
List booksList = bookService.queryAllBooks(books);
model.addAttribute("booksList",booksList);return "allBooks";
}//跳转到书籍添加页面@RequestMapping("/toAddBook")public String toAddBook(){return "addBook";
}//添加书籍@RequestMapping("/addBook")public String addBook(Books books){
System.out.println("addBook=>"+books);
bookService.addBook(books);return "redirect:/books/allBooks"; //重定向到首页
}//跳转到修改页面@RequestMapping("/toUpdateBook")public String toUpdateBook(Integer id, Model model){
System.out.println(id);
Books books = bookService.queryBookById(id);
model.addAttribute("qBook",books);return "updateBook";
}//修改书籍@RequestMapping("/updateBook")public String updateBook(Books books){
System.out.println("updateBook=>"+books);
bookService.updateBook(books);return "redirect:/books/allBooks";
}//删除书籍@RequestMapping("/deleteBook")public String deleteBook(Integer id){
System.out.println("deleteBookId=>"+id);
bookService.deleteBook(id);return "redirect:/books/allBooks";
}
}
allBook.jsp:
"text/html;charset=UTF-8" language="java" %>
所有书籍记录
"stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" >
class="container">
class="row clearfix">
class="col-md-12 column">
class="page-header">
书籍列表————显示所有书籍
class="row">
class="col-md-4 column">class="btn btn-primary" href="${pageContext.request.contextPath}/books/toAddBook">新增书籍
class="col-md-4 column" style="float:right">"${pageContext.request.contextPath}/books/allBooks" method="post" class="form-inline">"text" name="bookName" class="form-control" placeholder="请输入书籍名称">"submit" class="btn btn-primary" value="查询">
class="row clearfix">
class="col-md-12 column">
class="table table-hover table-striped">书籍编号书籍名称书籍数量书籍详情操作"book" items="${booksList}">${book.bookId}${book.bookName}${book.bookCounts}${book.detail}"${pageContext.request.contextPath}/books/toUpdateBook?id=${book.bookId}">修改
| "${pageContext.request.contextPath}/books/deleteBook?id=${book.bookId}">删除
addBook.jsp:
"text/html;charset=UTF-8" language="java" %>
新增书籍
"stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" >
class="container">
class="row clearfix">
class="col-md-12 column">
class="page-header">
书籍列表————新增书籍
"${pageContext.request.contextPath}/books/addBook" method="post">
class="form-group">for="bookName">书籍名称"text" name="bookName" class="form-control" id="bookName" required>
class="form-group">for="bookCounts">书籍数量"text" name="bookCounts" class="form-control" id="bookCounts" required>
class="form-group">for="detail">书籍详情"text" name="detail" class="form-control" id="detail" required>
"submit" class="btn btn-default">添加
updateBook.jsp:
"text/html;charset=UTF-8" language="java" %>
修改书籍
"stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" >
class="container">
class="row clearfix">
class="col-md-12 column">
class="page-header">
书籍列表————修改书籍
"${pageContext.request.contextPath}/books/updateBook" method="post">"hidden" name="bookId" value="${qBook.bookId}">
class="form-group">for="bookName">书籍名称"text" name="bookName" class="form-control" id="bookName" value="${qBook.bookName}" required>
class="form-group">for="bookCounts">书籍数量"text" name="bookCounts" class="form-control" id="bookCounts" value="${qBook.bookCounts}" required>
class="form-group">for="detail">书籍详情"text" name="detail" class="form-control" id="detail" value="${qBook.detail}" required>
"submit" class="btn btn-default">修改
界面演示:
9、小结
这里只实现了基本ssm框架的整合以及简单增删改查业务的实现
更加复杂的业务还等着我们去面临和解决
对于框架底层的学习还远远不够,学会多看底层代码,深入理解原理,对以后框架的优化会有极大帮助
可能出现的BUG处理:
为方便SQL语句bug的查询,可在mybatis配置setting开启日志
name="logImpl" value="STDOUT_LOGGING"/>
1.在对数据库进行查询时出现异常
java.sql.SQLException: Access denied for user 'Poison'@'localhost' (using password: YES)
经检查driver,url,username,password等内容都无错误
原来db.properties配置如下:
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/ssmbuild?useSSL=true&useUnicode=true&characterEncoding=utf8
username=root
password=123456
网上查询后得知:配置数据库用户名username和Spring中默认的username字段名冲突,
name="username" value="${username}"/>
在这里${username}默认查询的是系统用户名,而不是db.properties中配置的username
于是为了防止重名,将db.properties中的变量名修改如下,问题解决
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/ssmbuild?useSSL=true&useUnicode=true&characterEncoding=utf8
jdbc.username=root
jdbc.password=123456
2.新增记录后刷新页面显示乱码
原因:web.xml中Filter的没有初始化encoding参数utf-8
由于CharacterEncodingFilter类的encoding属性允许为空,所以没有提示,一定要注意。
public class CharacterEncodingFilter extends OncePerRequestFilter {
@Nullable
private String encoding;
修改web.xml中Filter配置
encodingFilter
org.springframework.web.filter.CharacterEncodingFilter
encoding
utf-8