1、数据库用表:
CREATE DATABASE ssmbuild; USE ssmbuild; CREATE TABLE `books`( `bookID` INT NOT NULL AUTO_INCREMENT COMMENT '书id', `bookName` VARCHAR(100) NOT NULL COMMENT '书名', `bookCounts` INT NOT NULL COMMENT '数量', `detail` VARCHAR(200) NOT NULL COMMENT '描述', KEY `bookID`(`bookID`) )ENGINE=INNODB DEFAULT CHARSET=utf8; INSERT INTO `books`(`bookID`,`bookName`,`bookCounts`,`detail`)VALUES (1,'Java',1,'从入门到放弃'), (2,'MySQL',10,'从删库到跑路'), (3,'Linux',5,'从进门到进牢')
2、新建一个maven项目,添加web支持
3、添加pom依赖
<dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope> </dependency> <!--servlet依赖--> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>4.0.1</version> </dependency> <!--jsp依赖--> <dependency> <groupId>javax.servlet</groupId> <artifactId>jsp-api</artifactId> <version>2.0</version> </dependency> <!--mysql-jdbc依赖--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.48</version> </dependency> <!--JSTL表达式依赖--> <dependency> <groupId>javax.servlet.jsp.jstl</groupId> <artifactId>jstl-api</artifactId> <version>1.2</version> </dependency> <!--standard标签库依赖--> <dependency> <groupId>taglibs</groupId> <artifactId>standard</artifactId> <version>1.1.2</version> </dependency> <!--mybatis依赖--> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.4.6</version> </dependency> <!--自动生成set/get等方法的注解--> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.12</version> </dependency> <!--spring依赖--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.2.12.RELEASE</version> </dependency> <!--springAOP的包--> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.9.4</version> </dependency> <!--ssm整合jdbc依赖--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>5.2.12.RELEASE</version> </dependency> <!--mybatis整合依赖--> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>2.0.5</version> </dependency> <!--JSON转换--> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.10.2</version> </dependency> <!--c3po数据库连接池--> <dependency> <groupId>com.mchange</groupId> <artifactId>c3p0</artifactId> <version>0.9.5.2</version> </dependency> <!--阿里巴巴的JSON格式转换--> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.75</version> </dependency> </dependencies>
4、maven资源过滤(资源导出问题)
<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>
5、使用idea测试连接数据库
6、建立基本结构包
- com/zhixi/pojo -->编写跟数据库对应的实体类
- com/zhixi/dao -->数据库持久化层,数据访问对象。他只负责对数据进行访问
- com/zhixi/service -->业务逻辑都会放在这里处理,比如用户的增删改查
- com/zhixi/controller -->负责请求转发,接受页面过来的参数,传给Service处理,接到返回值,再传给页面
============================================================================================
7、pojo实体类
package com.zhixi.pojo; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; /** * @author zhangzhixi */ @Data @NoArgsConstructor @AllArgsConstructor public class Books { private Integer bookID; private String bookName; private Integer bookCounts; private String detail; }
8、dao层
package com.zhixi.dao; import com.zhixi.pojo.Books; import org.apache.ibatis.annotations.Param; import java.util.List; /** * @author zhangzhixi */ public interface BooksMapper { // 增加一本书 int addBook(Books book); // 删除一本书 int delBook(@Param("bookId") int id); // 查询一本书 Books queryBookById(int id); // 更新一本书 int updateBook(Books book); // 查询所有的书 List<Books> queryBooks(); // 根据书名查询书籍 Books queryBookByName(@Param("bookName") String bookName); }
9、service层:与dao层业务方法保持一致
service层接口:
package com.zhixi.service; import com.zhixi.pojo.Books; import org.apache.ibatis.annotations.Param; import java.util.List; /** * @author zhangzhixi */ public interface BooksService { // 增加一本书 int addBook(Books book); // 删除一本书 int delBook(int id); // 查询一本书 Books queryBookById(int id); // 更新一本书 int updateBook(Books book); // 查询所有的书 List<Books> queryBooks(); // 根据书名查询书籍 Books queryBookByName(String bookName); }
service层接口实现类:service调dao层(含有dao层接口对象的引用)
package com.zhixi.service; import com.zhixi.dao.BooksMapper; import com.zhixi.pojo.Books; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.util.List; @Service public class BooksServiceImpl implements BooksService { // 业务层service调dao层 private BooksMapper booksMapper; public void setBooksMapper(BooksMapper booksMapper) { this.booksMapper = booksMapper; } public int addBook(Books book) { return booksMapper.addBook(book); } public int delBook(int id) { return booksMapper.delBook(id); } public Books queryBookById(int id) { return booksMapper.queryBookById(id); } public int updateBook(Books book) { return booksMapper.updateBook(book); } public List<Books> queryBooks() { return booksMapper.queryBooks(); } public Books queryBookByName(String bookName) { return booksMapper.queryBookByName(bookName); } }
☆:Controller层:
package com.zhixi.controller; import com.zhixi.pojo.Books; import com.zhixi.service.BooksService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import java.util.ArrayList; import java.util.List; /** * @author zhangzhixi */ @Controller @RequestMapping("/books") public class BookController { // controller调service层 @Autowired @Qualifier("booksService") private BooksService booksService; // 1、查询全部的书籍,并跳转到书籍展示页面 @RequestMapping("/allBook") public String queryBooks(Model model) { List<Books> list = booksService.queryBooks(); model.addAttribute("list", list); return "queryAllBookPage"; } // 2、添加书籍页面 @RequestMapping("/toBookPage") public String toBookPage() { return "addBookPage"; } // 2.1、添加书籍 @RequestMapping("/addBook") public String addBook(Books books) { // 添加书籍 booksService.addBook(books); // 跳转到查询全部书籍的页面【使用重定向】 return "redirect:/books/allBook"; } // 3、修改书籍页面 @RequestMapping("/updateBookPage") // 这个id是从jsp页面拿到的,可以知道是对哪个用户进行修改数据 public String updateBook(int id, Model model) { Books books = booksService.queryBookById(id); model.addAttribute("QUpdate", books); return "updateBookPage"; } // 3.1、修改书籍 @RequestMapping("/toUpdate") public String toUpdate(Books books) { booksService.updateBook(books); // 返回书籍首页 return "redirect:/books/allBook"; } // 4、删除书籍,删除完成后跳转到书籍首页 @RequestMapping("/delBook") public String delBook(int id) { booksService.delBook(id); return "redirect:/books/allBook"; } // 5、根据id查找书籍 @RequestMapping("/queryById") // RequestParam是为了设置前端过来的请求与参数名不一致的情况 public String queryBookById(@RequestParam("bookById") int id, Model model) { List<Books> list = new ArrayList<Books>(); // 根据id查询 Books books = booksService.queryBookById(id); list.add(books); if (books == null) {// 没有查询到书籍,就回到书籍首页并显示错误信息 list = booksService.queryBooks(); model.addAttribute("errorById", "没有查询到书籍!"); } model.addAttribute("list", list); return "queryAllBookPage"; } // 6、根据书名查找书籍 @RequestMapping("/queryByName") public String queryBookByName(@RequestParam("bookName") String bookName, Model model) { List<Books> list = new ArrayList<Books>(); Books books = booksService.queryBookByName(bookName); list.add(books); if (books == null) { // 没有查询到书籍,就回到书籍首页并显示错误信息 list = booksService.queryBooks(); model.addAttribute("errorByName", "没有查询到书籍!"); } model.addAttribute("list", list); return "queryAllBookPage"; } }
10、mybatis-config.xml :mybatis配置文件
因为是整合项目,都交给spring做了,所以mybatis中几乎都保留很少的功能,比如日志,给实体类起别名等设置
<?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> <!--日志--> <settings> <setting name="logImpl" value="STDOUT_LOGGING"/> </settings> <!--设置实体类别名--> <typeAliases> <package name="com.zhixi.pojo"/> </typeAliases> </configuration>
11、resources/mapper/BooksMapper.xml :dao层的映射文件-->做mybatis的CRUD
dao层接口的映射文件,主要是做CRUD操作
<?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.zhixi.dao.BooksMapper"> <!--添加书籍--> <insert id="addBook" parameterType="books"> insert into ssmbuild.books (bookName, bookCounts, detail) values (#{bookName}, #{bookCounts}, #{detail}) </insert> <!--根据id删除书籍--> <delete id="delBook" parameterType="int"> delete from ssmbuild.books where bookID = #{bookId} </delete> <!--修改书籍--> <update id="updateBook" parameterType="books"> update ssmbuild.books set bookName=#{bookName}, bookCounts=#{bookCounts}, detail = #{detail} /*这里的bookID需要指定,是因为要与修改的jsp给id起的name保持一致*/ where bookID = #{bookID} </update> <!--查询所有书籍--> <select id="queryBooks" resultType="books"> select * from ssmbuild.books; </select> <!--根据id查询书籍--> <select id="queryBookById" resultType="books" parameterType="int"> select * from ssmbuild.books where bookID = #{bookById}; </select> <!--根据名字查询书籍--> <select id="queryBookByName" parameterType="java.lang.String" resultType="books"> select * from ssmbuild.books where bookName = #{bookName} </select> </mapper>
12、spring-dao.xml:主要跟数据连接打交道
jdbc.properties:数据连接池的基本配置文件:
需要注意的是如果是mysql8以上的版本需要在后面加上时区serverTimezone=UTC
因为中国时区比美国早八个小时,所以我们要在mysql中进行设置时区(防止以后的各种bug)
具体操作可以看我的这篇博客:https://www.cnblogs.com/zhangzhixi/p/14286664.html
jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/ssmbuild?useSSL=true&useUnicode=true&;characterEncoding=UTF-8&;serverTimezone=UTC jdbc.username=root jdbc.password=zhixi158
<?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:jdbc.properties"/> <!--2、导入c3p0数据库连接池--> <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}"/> </bean> <!--spring提供的数据连接池--> <!-- <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <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>--> <!--3、sqlSessionFactor--> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> <!--4、绑定mybatis配置文件--> <property name="configLocation" value="classpath:mybatis-config.xml"/> <!--mapper映射器,也可以在mybatis中配置--> <property name="mapperLocations" value="classpath:mapper/BooksMapper.xml"/> </bean> <!--5、配置dao层接口扫描包,动态的实现了Dao层接口可以注入到Spring容器中!--> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <!--注入SQLSessionFactory--> <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/> <!--要扫描的dao包--> <property name="basePackage" value="com.zhixi.dao"/> </bean> </beans>
13、spring-service.xml:做一些事务以及aop的植入
<?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" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd "> <!--1、统一管理bean--> <context:component-scan base-package="com.zhixi.service"/> <!--2、将所有业务类,注入到bean--> <bean id="booksService" class="com.zhixi.service.BooksServiceImpl"> <property name="booksMapper" ref="booksMapper"/> </bean> <!--3、声明式事务配置:开启事务--> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean> <!--4、aop事务支持--> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <tx:method name="*" propagation="REQUIRED"/> </tx:attributes> </tx:advice> <!--配置事务切入--> <aop:config> <!-- 配置切入点表达式:指定哪些包中类, 要使用事务 id:切入点表达式的名称,唯一值 expression :切入点表达式, 指定哪些类要使用事务, aspectj会创建代理对象 --> <aop:pointcut id="exPoint" expression="execution(* com.zhixi.dao.*.*(..))"/> <!--配置增强类--> <aop:advisor advice-ref="txAdvice" pointcut-ref="exPoint"/> </aop:config> </beans>
14、spring-mvc.xml:映射controller层
<?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: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/aop https://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd"> <!--1、注解驱动--> <mvc:annotation-driven/> <!--2、静态资源过滤--> <mvc:default-servlet-handler/> <!--3、扫描controller包--> <context:component-scan base-package="com.zhixi.controller"/> <!--4、配置视图解析器--> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <!--前缀跟后缀--> <property name="prefix" value="/WEB-INF/jsp/"/> <property name="suffix" value=".jsp"/> </bean> </beans>
15、applicationContext.xml:spring总的配置文件,为了方便管理所有的spring文件
<?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" 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/aop https://www.springframework.org/schema/aop/spring-aop.xsd"> <!--注解的支持--> <context:annotation-config/> <import resource="classpath:spring-dao.xml"/> <import resource="classpath:spring-service.xml"/> <import resource="classpath:spring-mvc.xml"/> </beans>
16、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"> <!-- <error-page> <error-code>500</error-code> <location>/WEB-INF/error/500.jpg</location> </error-page>--> <!--1、配置spring提供的servlet--> <servlet> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!--2、关联配置文件--> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext.xml</param-value> </init-param> <!--3、设置启动级别--> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>springmvc</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <!--4、乱码过滤--> <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> </web-app>
17、JSP页面
index.jsp:网站首页-->跳转到暑假展示页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>首页</title> </head> <body> <div align="center"> <a href="${pageContext.request.contextPath}/books/allBook">跳转到书籍展示页面</a> </div> </body> </html>
jsp/queryAllBookPage.jsp:查询全部书籍页面
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>书籍展示页面</title> </head> <body> <center><h1>欢迎来到书籍展示页面</h1></center> <div style="text-align: center"> <div> <%--跳转到添加书籍的页面--%> <a href="${pageContext.request.contextPath}/books/toBookPage">添加书籍</a> <a href="${pageContext.request.contextPath}/books/allBook">查询全部书籍</a> </div> <div> <%--根据id查询书籍--%> <form method="post" action="${pageContext.request.contextPath}/books/queryById"> <input type="text" name="bookById" placeholder="输入id查询书籍"> <input type="submit" value="查询"/><span style="color: #ff6659">${errorById}</span> </form> </div> <div> <%--根据书名查询书籍--%> <form method="post" action="${pageContext.request.contextPath}/books/queryByName"> <input type="text" name="bookName" placeholder="输入书名查询书籍"> <input type="submit" value="查询"><span style="color: red">${errorByName}</span> </form> </div> <table border="1" align="center" style="text-align: center"> <tr> <th>书籍编号</th> <th>书籍名称</th> <th>书籍数量</th> <th>书籍详情</th> <th>操作</th> </tr> <c:forEach var="books" items="${list}"> <tr> <td>${books.bookID}</td> <td>${books.bookName}</td> <td>${books.bookCounts}</td> <td>${books.detail}</td> <td> <a href="${pageContext.request.contextPath}/books/updateBookPage?id=${books.bookID}">修改</a> | <a href="${pageContext.request.contextPath}/books/delBook?id=${books.bookID}">删除</a> </td> </tr> </c:forEach> </table> </div> </body> </html>
jsp/addBookPage.jsp:添加书籍页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>添加书籍页面</title> </head> <body> <form style="text-align: center" action="${pageContext.request.contextPath}/books/addBook" method="post"> <div>书籍名称:<input type="text" name="bookName" required/></div> <div>书籍数量:<input type="text" name="bookCounts" required/></div> <div>书籍描述:<input type="text" name="detail" required/></div> <div><input type="submit" value="提交"></div> </form> </body> </html>
jsp/updateBookPage.jsp:修改书籍页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>修改书籍页面</title> </head> <body> <form style="text-align: center" action="${pageContext.request.contextPath}/books/toUpdate" method="post"> <%-- 出现的问题:我们提交了修改的SQL请求,但是修改失败,初次考虑,是事务问题,配置完毕事务,依旧失败! 看一下SQL语句,能否执行成功: SQL执行失败,修改未完成 前端传递隐藏域 --%> <input type="hidden" name="bookID" value="${QUpdate.bookID}"> <div>书籍名称:<input type="text" name="bookName" value="${QUpdate.bookName}" required/></div> <div>书籍数量:<input type="text" name="bookCounts" value="${QUpdate.bookCounts}" required/></div> <div>书籍描述:<input type="text" name="detail" value="${QUpdate.detail}" required/></div> <div><input type="submit" value="修改"/></div> </form> </body> </html>