需要熟练掌握MySQL数据库,Spring,JavaWeb及Mybatis知识,基本的前端知识;
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
<!--依赖--> <dependencies> <!--junit--> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> </dependency> <!--mysql驱动--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.47</version> </dependency> <!--数据库连接池--> <dependency> <groupId>com.mchange</groupId> <artifactId>c3p0</artifactId> <version>0.9.5.2</version> </dependency> <!--servlet,jsp--> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.5</version> </dependency> <dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>jsp-api</artifactId> <version>2.2</version> </dependency> <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.5</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>2.0.5</version> </dependency> <!--spring--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>5.2.7.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.2.8.RELEASE</version> </dependency> </dependencies>
<!--资源过滤--> <build> <resources> <resource> <directory>src/main/java</directory> <includes> <include>**/*.properties</include> <include>**/*.xml</include> </includes> <filtering>false</filtering> </resource> <resource> <directory>src/main/resources</directory> <includes> <include>**/*.properties</include> <include>**/*.xml</include> </includes> <filtering>false</filtering> </resource> </resources> </build>
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核心配置文件--> <configuration> </configuration>
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"> </beans>
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
<?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核心配置文件--> <configuration> <settings> <!--开启自动驼峰命名规则,数据库带_字段名自动转换为驼峰命名,user_id -> userId --> <setting name="mapUnderscoreToCamelCase" value="true"/> </settings> <!--批量命名别名,默认命名为的别名为类名小写--> <typeAliases> <package name="com.spong.pojo"/> </typeAliases> </configuration>
Books
(可选择)使用lombok插件生成有参、无参构造及get、set方法
@Data @AllArgsConstructor @NoArgsConstructor public class Books { private Integer bookId; private String bookName; private Integer bookCounts; private String detail; }
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); //查询所有书 List<Books> queryAllBooks(); }
BookMapper.xml实现BookMapper接口
<?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.spong.dao.BookMapper"> <insert id="addBook" parameterType="Books"> insert into ssmbuild.books(book_name, book_counts, detail) values (#{bookName},#{bookCounts},#{detail}); </insert> <delete id="deleteBook" parameterType="Integer"> delete from ssmbuild.books where book_id=#{bookId}; </delete> <update id="updateBook" parameterType="Books"> update ssmbuild.books set book_name=#{bookName}, book_counts=#{bookCounts}, detail=#{detail} where book_id=#{bookId}; </update> <select id="queryBookById" parameterType="Integer" resultType="Books"> select * from ssmbuild.books where book_id=#{bookId}; </select> <select id="queryAllBooks" resultType="Books"> select * from ssmbuild.books; </select> </mapper>
每创建一个mapper就在mybatis核心配置文件中配置
<mappers> <mapper class="com.spong.dao.BookMapper"/> </mappers>
service层调用dao层,使用组合
BookService
public interface BookService { //新增一本书 int addBook(Books books); //删除一本书 int deleteBook(Integer id); //修改一本书 int updateBook(Books books); //查询一本书 Books queryBookById(Integer id); //查询所有书 List<Books> queryAllBooks(); }
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 List<Books> queryAllBooks() { return bookMapper.queryAllBooks(); } }
Spring关联数据库配置文件
<context:property-placeholder location="classpath:database.properties"/>
连接池(这里使用c3p0)
注册SQLSessionFactory
扫描dao包,动态注入到Spring容器中
扫描service下的包,实现动态注入
<context:component-scan base-package="com.spong.service"/>
也可以选择直接配置service实现类(1,2选一)
声明事务配置
https://www.cnblogs.com/spang/p/13488174.html 供参考
DispatcherServlet 配置
dispatcherServlet</servlet-name> org.springframework.web.servlet.DispatcherServlet</servlet-class>
<param-name>contextConfigLocation</param-name> <param-value>classpath:spring-mvc.xml</param-value>
</init-param> </servlet> dispatcherServlet</servlet-name> /</url-pattern> </servlet-mapping>
Filter过滤器
encodingFilter org.springframework.web.filter.CharacterEncodingFilter encodingFilter</filter-name> /*</url-pattern> </filter-mapping>
注意这里的url-pattern需要 /* 即jsp页面也需要过滤
关于web.xml的url映射的小知识: < url-pattern>/</url-pattern> 会匹配到/login这样的路径型url,不会匹配到模式为*.jsp这样的后缀型url < url-pattern>/*</url-pattern> 会匹配所有url:路径型的和后缀型的url(包括/login,*.jsp,*.js和*.html等)
Session相关配置
15</session-timeout> </session-config>
<!--1.开启注解驱动--> <mvc:annotation-driven/> <!--2.开启静态资源过滤--> <mvc:default-servlet-handler/> <!--3.扫描包:controller--> <context:component-scan base-package="com.spong.controller"/> <!--4.视图解析器--> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/jsp/"/> <property name="suffix" value=".jsp"/> </bean>
最后将所有配置文件在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"/> <import resource="classpath:spring-mvc.xml"/> </beans>
到此框架整合完毕,开始视图层和controller层的编写
@Controller @RequestMapping("/books") public class BookController { //Controller层调Service层 //Spring容器自动注入其中的bookService @Autowired private BookService bookService; //查询全部书籍,并返回一个显示所有书籍的页面 @RequestMapping("/allBooks") public String queryAllBooks(Model model){ List<Books> booksList = bookService.queryAllBooks(); model.addAttribute("booksList",booksList); return "allBooks"; } }
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>新增书籍</title> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" > </head> <body> <div class="container"> <div class="row clearfix"> <div class="col-md-12 column"> <div class="page-header"> <h1> <small>书籍列表————新增书籍</small> </h1> </div> </div> </div> <form action="${pageContext.request.contextPath}/books/addBook" method="post"> <div class="form-group"> <label for="bookName">书籍名称</label> <input type="text" name="bookName" class="form-control" id="bookName" required> </div> <div class="form-group"> <label for="bookCounts">书籍数量</label> <input type="text" name="bookCounts" class="form-control" id="bookCounts" required> </div> <div class="form-group"> <label for="detail">书籍详情</label> <input type="text" name="detail" class="form-control" id="detail" required> </div> <button type="submit" class="btn btn-default">添加</button> </form> </div> </body> </html>
//跳转到书籍添加页面 @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"; //重定向到首页 }
跳转
<div class="col-md-4 column"> <a class="btn btn-primary" href="${pageContext.request.contextPath}/books/toAddBook">新增书籍</a> </div>
页面
//跳转到修改页面 @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"; }
<a href="${pageContext.request.contextPath}/books/toUpdateBook?id=${book.bookId}">修改</a> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>修改书籍</title> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" > </head> <body> <div class="container"> <div class="row clearfix"> <div class="col-md-12 column"> <div class="page-header"> <h1> <small>书籍列表————修改书籍</small> </h1> </div> </div> </div> <form action="${pageContext.request.contextPath}/books/updateBook" method="post"> <%--id通过hidden传递--%> <input type="hidden" name="bookId" value="${qBook.bookId}"> <div class="form-group"> <label for="bookName">书籍名称</label> <input type="text" name="bookName" class="form-control" id="bookName" value="${qBook.bookName}" required> </div> <div class="form-group"> <label for="bookCounts">书籍数量</label> <input type="text" name="bookCounts" class="form-control" id="bookCounts" value="${qBook.bookCounts}" required> </div> <div class="form-group"> <label for="detail">书籍详情</label> <input type="text" name="detail" class="form-control" id="detail" value="${qBook.detail}" required> </div> <button type="submit" class="btn btn-default">修改</button> </form> </div> </body> </html>
//删除书籍 @RequestMapping("/deleteBook") public String deleteBook(Integer id){ System.out.println("deleteBookId=>"+id); bookService.deleteBook(id); return "redirect:/books/allBooks"; }
<a href="${pageContext.request.contextPath}/books/deleteBook?id=${book.bookId}">删除</a>
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<Books> 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:
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>所有书籍记录</title> <%--bootStrap界面美化--%> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" > </head> <body> <div class="container"> <div class="row clearfix"> <div class="col-md-12 column"> <div class="page-header"> <h1> <small>书籍列表————显示所有书籍</small> </h1> </div> </div> </div> <div class="row"> <div class="col-md-4 column"> <a class="btn btn-primary" href="${pageContext.request.contextPath}/books/toAddBook">新增书籍</a> </div> <div class="col-md-4 column" style="float:right"> <form action="${pageContext.request.contextPath}/books/allBooks" method="post" class="form-inline"> <input type="text" name="bookName" class="form-control" placeholder="请输入书籍名称"> <input type="submit" class="btn btn-primary" value="查询"> </form> </div> </div> <div class="row clearfix"> <div class="col-md-12 column"> <table class="table table-hover table-striped"> <thead> <tr> <th>书籍编号</th> <th>书籍名称</th> <th>书籍数量</th> <th>书籍详情</th> <th>操作</th> </tr> </thead> <%--书籍从数据库中查询出来,在list中遍历:foreach--%> <tbody> <c:forEach var="book" items="${booksList}"> <tr> <td>${book.bookId}</td> <td>${book.bookName}</td> <td>${book.bookCounts}</td> <td>${book.detail}</td> <td> <a href="${pageContext.request.contextPath}/books/toUpdateBook?id=${book.bookId}">修改</a> | <a href="${pageContext.request.contextPath}/books/deleteBook?id=${book.bookId}">删除</a> </td> </tr> </c:forEach> </tbody> </table> </div> </div> </div> </body> </html>
addBook.jsp:
updateBook.jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>修改书籍</title> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" > </head> <body> <div class="container"> <div class="row clearfix"> <div class="col-md-12 column"> <div class="page-header"> <h1> <small>书籍列表————修改书籍</small> </h1> </div> </div> </div> <form action="${pageContext.request.contextPath}/books/updateBook" method="post"> <%--id通过hidden传递--%> <input type="hidden" name="bookId" value="${qBook.bookId}"> <div class="form-group"> <label for="bookName">书籍名称</label> <input type="text" name="bookName" class="form-control" id="bookName" value="${qBook.bookName}" required> </div> <div class="form-group"> <label for="bookCounts">书籍数量</label> <input type="text" name="bookCounts" class="form-control" id="bookCounts" value="${qBook.bookCounts}" required> </div> <div class="form-group"> <label for="detail">书籍详情</label> <input type="text" name="detail" class="form-control" id="detail" value="${qBook.detail}" required> </div> <button type="submit" class="btn btn-default">修改</button> </form> </div> </body> </html>
界面演示:
这里只实现了基本ssm框架的整合以及简单增删改查业务的实现
更加复杂的业务还等着我们去面临和解决
对于框架底层的学习还远远不够,学会多看底层代码,深入理解原理,对以后框架的优化会有极大帮助
为方便SQL语句bug的查询,可在mybatis配置setting开启日志
<!--开启日志--> <setting name="logImpl" value="STDOUT_LOGGING"/>
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字段名冲突,
<property 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
原因:web.xml中Filter的没有初始化encoding参数utf-8
由于CharacterEncodingFilter类的encoding属性允许为空,所以没有提示,一定要注意。
public class CharacterEncodingFilter extends OncePerRequestFilter { @Nullable private String encoding;
修改web.xml中Filter配置
<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>
原文链接:https://www.cnblogs.com/spang/p/13494896.html