10.1、创建项目
需求分析,设计数据库,编写业务,前端交互
1.创建数据库
CREATE DATABASE ssmbuild;
USE ssmbuild
DROP TABLE IF EXISTS books;
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,'白雪公主',10,'童话'),(2,'农夫与蛇',4,'语言'),(3,'后羿射日',22,'神话');
2.创建maven项目
- 导包,添加web支持
<dependencies>
<!--junit,数据库驱动,数据库连接池,servlet,jsp,jstl,mybatis,spring-jdbc,spring-webmvc,mybatis-spring,-->
...
</dependencies>
<!--静态资源导出问题-->
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
<include>**/*.properties</include>
</includes>
<filtering>false</filtering>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.xml</include>
<include>**/*.properties</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
</build>
- 在idea中连接数据库,添加mysql语言注入:在sql语句旁边alt+enter,添加语言注入,选择mysql,就会有sql语句的提示
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LpLO9gpW-1688718274662)(C:\Users\31998\AppData\Roaming\Typora\typora-user-images\image-20230627111232962.png)]
- 创建包结构和配置文件,pojo,controller,service,mapper,db.properties,spring.xml,mybatis.xml…
10.2、整合配置文件(可直接复制粘贴使用)
1.mybatis-config.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!--别名-->
<typeAliases>
<package name="com.likea.pojo"/>
</typeAliases>
</configuration>
2.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>
3.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
https://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.连接池,数据源:spring原生的org.springframework.jdbc.datasource.DriverManagerDataSource,
jdbc:半自动化操作,不能自动连接
c3p0:自动化操作(自动化的加载配置文件,能自动设置到对象中)
druid:
hikari:
-->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${driver}"/>
<property name="jdbcUrl" value="${url}"/>
<property name="user" value="${user}"/>
<property name="password" value="${password}"/>
<!--c3p0的私有属性-->
<property name="maxPoolSize" value="30"/>
<property name="minPoolSize" value="20"/>
<!--关闭连接后不自动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接口.方式一:可以注入到Spring容器中-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!--注入sqlSessionFactory-->
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
<!--要扫描的dao包-->
<property name="basePackage" value="com.likea.mapper"/>
</bean>
<!--方式二:编写dao接口的实现类,继承SqlSessionDaoSupport直接getSqlSession()或者添加SqlSessionTemplate属性-->
</beans>
4.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
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
http://www.springframework.org/schema/aop">
<!--1.扫描包-->
<context:component-scan base-package="com.likea.service"/>
<!--2.将业务类注入到spring,方式一:配置bean,方式二:注解@Service和@AutoWired-->
<bean id="booksService" class="com.likea.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事务支持-->
</beans>
5.springmvc-servlet.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.likea.controller"/>
<mvc:default-servlet-handler/>
<mvc:annotation-driven/>
<!--添加视图解析器,视图解析器:dispatcherServlet给它的ModelandView-->
<bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!--前缀-->
<property name="prefix" value="/WEB-INF/jsp/"/>
<!--后缀-->
<property name="suffix" value=".jsp"/>
</bean>
</beans>
6.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">
<!--注册DispatcherServlet-->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--关联一个springmvc的配置文件-->
<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>
<!--
/和/*的区别
/:只匹配所有的请求,不包括.jsp文件
/*:匹配所有的请求,包括.jsp文件
如果请求.jsp文件是不需要再添加前缀后缀的,直接返回给用户即可
-->
<url-pattern>/</url-pattern>
</servlet-mapping>
<!--配置springMVC自带的乱码过滤器-->
<filter>
<filter-name>encoding</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>encoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!--3.session超时时间:15分钟-->
<session-config>
<session-timeout>15</session-timeout>
</session-config>
</web-app>
7.db.properties
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/数据库名称?useUnicode=true&characterEncoding=UTF-8
user=root
password=****
10.3、排错
-
问题:bean不存在
-
查看这个bean注入是否成功!
-
junit单元测试,看我们的代码是否能够查询出来结果!
@Test public void test(){ ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); BooksService booksService = (BooksService) context.getBean("booksService"); List<Books> books = booksService.getBooks(); for (Books book : books) { System.out.println(book); } }
-
SpringMVC,整合的时候没调用到我们的service层的bean:
- applicationContext.xml配置文件中是否导入了bean所在的xml文件;
- web.xml中绑定的xml文件也需要有bean的配置,需要绑定applicationContext.xml
-
-
配置username引入的是电脑本地用户名“***”@localhost,而不是数据库用户名root,用$(username}之后会取当前计算机用户名来连数据库,将spring-dao.xml和jdbc.properties的中username改成user,测试成功!!!
10.4、CURD
增删该需要提交事务,在spring中织入aop,查询不需要
1.查询/删除数据
- mapper接口添加查询全部书籍的类,编写mapper.xml查询语句
- service接口编写查询类,service实现类引入mapper,调用mapper层,并返回查询的数据
- controller层编写查询查询方法,返回数据展示页面,引入service实现类,调用service层,返回数据给前端
- 编写数据展示页面,获取数据并展示
2.添加/修改数据
- 在书籍列表页面添加按钮,跳转到添加书籍页面
- 编写添加书籍的jsp页面
- controller层编写跳转页面的方法,返回添加页面,编写添加方法,获取前台数据,调用service层添加数据,返回指定页面
- 添加和修改的不同,修改在跳转到修改页面前需要获取数据id,并查询出数据,将其带到前端显示,必须隐藏id但不能不写,修改的sql语句需要id
3.bootstrap前端开发框架
-
引入
<link href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
-
bootstrap中文文档,查找css样式,复制粘贴即可使用
10.5、关键代码展示
-
mapper.xml
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "https://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!--一个mapper对应一个mapper.xml--> <mapper namespace="com.likea.mapper.BooksMapper"> <select id="getBooks" resultType="books"> select * from books </select> </mapper>
-
serviceImpl
@Service public class BooksServiceImpl implements BooksService{ //业务层调用dao层:组合dao @Autowired private BooksMapper booksMapper; public void setBooksMapper(BooksMapper booksMapper) { this.booksMapper = booksMapper; } public List<Books> getBooks() { return booksMapper.getBooks(); } }
-
controller
@Controller @RequestMapping("/books") public class BooksController { //Controller调用service @Autowired(required = false) @Qualifier("booksService") private BooksService booksService; @RequestMapping("/allBook") public String bookList(Model model) { List<Books> books = booksService.getBooks(); model.addAttribute("list", books); return "allBook"; } //跳转到添加书籍页面 @RequestMapping("/insert") public String insertBook() { return "addBook"; } //添加书籍的请求 @RequestMapping("/addBook") public String addBook(Books book) { booksService.addBook(book); return "redirect:/books/allBook";//重定向到/allBook请求 } //删除图书 @RequestMapping("/delete/{bookId}") public String delete(@PathVariable("bookId") int bookId) { booksService.deleteBookById(bookId); return "redirect:/books/allBook"; } //修改图书页面 @RequestMapping("/update") public String update(int bookId, Model model) { Books book = booksService.getBookById(bookId);//跳转页面的时候带参数id model.addAttribute("book", book);//根据参数查询书籍信息,带给前端显示,input中的value设置默认值 return "updateBook"; } //修改图书 @RequestMapping("/updateBook") public String update(Books book, HttpServletRequest request) { booksService.updateBook(book); return "redirect:/books/allBook"; } //查询书籍 @RequestMapping("/queryBook") public String queryBookByName(String queryBookName, Model model) { List<Books> books = booksService.getBookByName(queryBookName); if (books.size() == 0) {//书籍未查到,返回全部书籍 model.addAttribute("error", "未查到"); books = booksService.getBooks(); } model.addAttribute("list", books);//返回查到的书籍 return "allBook"; } }
-
jsp
-
allBook.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <html> <head> <%--导入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"> <div class="page-header"> <h1> <small>书籍列表------显示所有书籍</small> </h1> </div> </div> <div class="row"> <div class="col-md-4 column"> <%--跳转到添加书籍页面--%> <a class="btn btn-primary" href="${pageContext.request.contextPath}/books/insert">新增图书</a> <a class="btn btn-primary" href="${pageContext.request.contextPath}/books/allBook">显示所有书籍</a> </div> <div class="col-md-8 column"> <form action="${pageContext.request.contextPath}/books/queryBook" method="post" class="form-inline" style="float: right"> <%--input的name值必须和controller方法的参数名保持一致,才能从前端获取到数据--%> <input type="text" name="queryBookName" class="form-control" placeholder="输入书籍名称" required> <input type="submit" class="btn btn-primary" value="查询"> </form> <span style="color: red;font-weight: bold;font-size: 18px;float: right;line-height: 34px">${error}</span> </div> </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="${list}"> <tr> <td>${book.bookId}</td> <td>${book.bookName}</td> <td>${book.bookCounts}</td> <td>${book.detail}</td> <td> <a href="${pageContext.request.contextPath}/books/update?bookId=${book.bookId}">修改</a> | <a href="${pageContext.request.contextPath}/books/delete/${book.bookId}">删除</a> </td> </tr> </c:forEach> </tbody> </table> </div> </div> </div> </body>
-
addBook.jsp
<head> <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"> <div class="page-header"> <h1> <small>新增书籍</small> </h1> </div> </div> </div> <form action="${pageContext.request.contextPath}/books/addBook" method="post"> <div class="from-group"> <label>书籍名称:</label> <%--input的name属性名必须和实体类的属性名一致--%> <%--required确保表单填完整,才能提交--%> <input type="text" class="from-control" name="bookName" required/> </div> <div class="from-group"> <label>书籍数量:</label> <input type="text" class="from-control" name="bookCounts" required/> </div> <div class="from-group"> <label>书籍描述:</label> <input type="text" class="from-control" name="detail" required/> </div> <div class="from-group"> <input type="submit" class="from-control" value="提交"/> </div> </form> </div> </body>
-
updateBook.jsp
<head> <title>update</title> <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"> <div class="page-header"> <h1> <small>修改书籍</small> </h1> </div> </div> </div> <form action="${pageContext.request.contextPath}/books/updateBook" method="post"> <div class="from-group"> <label>书籍Id:</label> <input type="hidden" name="bookId" value="${book.bookId}"/> </div> <div class="from-group"> <label>书籍名称:</label> <input type="text" class="from-control" name="bookName"value="${book.bookName}" required/> </div> <div class="from-group"> <label>书籍数量:</label> <input type="text" class="from-control" name="bookCounts" value="${book.bookCounts}" required/> </div> <div class="from-group"> <label>书籍描述:</label> <input type="text" class="from-control" name="detail" value="${book.detail}" required/> </div> <div class="from-group"> <input type="submit" class="from-control" value="修改"/> </div> </form> </div> </body>
-