“ 感谢今年大家的互相鼓励和支持,马上就要过新年啦,恰巧赶在年前,把总结写完,就可以开开心心休假啦!”
Java-----SSM三大框架整合(图书管理)
搭建数据库,创建数据表
create DATABASE ssmbuild;
use ssmbuild;
drop table if EXISTS books;
CREATE table books(
bookId int(10) not NULL auto_increment PRIMARY KEY COMMENT '书id',
bookname VARCHAR(100) not null COMMENT '书名',
bookCounts int(11) not NULL COMMENT '数量',
detail VARCHAR(200) not null COMMENT '描述'
)ENGINE = INNODB DEFAULT CHARSET = utf8;
show tables;
insert into books(bookId, bookname,bookCounts,detail) VALUES
(1,'java',1,'从入门到放弃'),
(2,'mysql',10,'从删库到跑路'),
(3,'linux',5,'从进门到进牢');
SELECT * from books;
创建maven项目
项目目录
porm.xml中导入jar包
junit 数据库驱动 连接池(c3p0) servlet jsp mybatis mybatis-spring spring lombok 以及 导出配置文件的build
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
</dependency>
<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>
<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.jsp.jstl</groupId>
<artifactId>jstl-api</artifactId>
<version>1.2</version>
</dependency>
<!-- 标准库依赖-->
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.2</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.2</version>
</dependency>
<!-- Spring核心依赖 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.1.9.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.1.9.RELEASE</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.10</version>
</dependency>
</dependencies>
<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>
那就开始我们的mybatis层的配置吧
idea连接数据库
总之就是要确保数据表可以使用
编写db.properties数据库配置信息
不过最后我使用的是spring默认提供的DriverManagerDataSource来配置数据库信息
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/ssmbuild?useSSL=true&useUnicode=true&characterEncoding=UTF-8
username=root
password=root
编写pojo实体类
属性名与数据表字段保持一致
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Books {
private int bookId;
private String bookName;
private int bookCounts;
private String detail;
}
编写dao层
图书管理的五个操作:增删改查+查询全部书籍
BookMapper接口
public interface BookMapper {
int addBook(Books books);
int deleteBooksById(@Param("bookId") int id);
int updateBook(Books books);
Books queryBooksById(@Param("bookId") int id);
List<Books> queryAllBook();
}
然后立刻编写BookMapper.xml配置文件
sql语句最基本的增删改查操作
<?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.huang.dao.BookMapper">
<insert id="addBook" parameterType="Books">
insert into ssmbuild.books(bookName, bookCounts, detail) values
(#{bookName},#{bookCounts},#{detail})
</insert>
<delete id="deleteBooksById" parameterType="int">
delete from ssmbuild.books where bookId = #{bookId}
</delete>
<update id="updateBook" parameterType="Books">
update ssmbuild.books
set bookCounts = #{bookCounts} ,bookName = #{bookName},detail = #{detail}
where bookId = #{bookId};
</update>
<select id="queryBooksById" resultType="Books">
select *
from ssmbuild.books where bookId = #{bookId};
</select>
<select id="queryAllBook" resultType="Books">
select * from ssmbuild.books
</select>
</mapper>
/mybatis.-config.xml配置文件
在使用spring整合后,我们通常在mybatis配置文件中只配置settings和typeAliases以及mappers三大块
<?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"/>
<setting name="mapUnderscoreToCamelCase" value="true" />
</settings>
<typeAliases>
<package name="com.huang.pojo"/>
</typeAliases>
<mappers>
<mapper class="com.huang.dao.BookMapper"/>
</mappers>
</configuration>
/applicationContext.xml中导入MVC各层的配置文件
这里是已经整合完三层后的配置
<?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
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<import resource="classpath:spring-dao.xml"/>
<import resource="classpath:spring-service.xml"/>
<import resource="classpath:spring-mvc.xml"/>
</beans>
那么到这里我们的mybatis层就已经搭建好了,接下来我们进入到spring层! 突然想听一首五月天的咸鱼,放松放松
spring层的搭建
编写业务层接口和类实现对dao层的实现
BookService接口
说明:业务层其实和dao层方法是一样的,只不过我们参照了静态代理的思想,方便我们的功能扩展。
public interface BookService {
int addBook(Books books);
int deleteBooksById(int id);
int updateBook(Books books);
Books queryBooksById(int id);
List<Books> queryAllBook();
}
接下来最重要的BookService接口的实现类BookServiceImpl
相信到这里,我们应该豁然开朗,我们只需要在spring中给一个bean来创建BookServiceImpl的对象,然后在property中给属性bookMapper赋值,我们就可以调用BookServiceImp的一系列方法来间接调用dao层操作数据库的方法。
<bean id="BookServiceImpl" class="com.huang.service.BookServiceImpl">
<property name="bookMapper" ref="bookMapper"/>
</bean>
是不是突然明白?xue微有点绕,哎,好气啊
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 deleteBooksById(int id) {
return bookMapper.deleteBooksById(id);
}
public int updateBook(Books books) {
return bookMapper.updateBook(books);
}
public Books queryBooksById(int id) {
return bookMapper.queryBooksById(id);
}
public List<Books> queryAllBook() {
return bookMapper.queryAllBook();
}
}
/spring-service.xml配置文件 spring整合业务层
该配置文件做三件事:
- 扫描业务层的包
- spring提供的声明式事务管理
- 创建BookServiceImpl实现类的对象
<?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-3.0.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="com.huang.service"/>
<bean id="TransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<bean id="BookServiceImpl" class="com.huang.service.BookServiceImpl">
<property name="bookMapper" ref="bookMapper"/>
</bean>
</beans>
/spring-dao.xml配置文件 spring整合dao层
该配置文件做三件事:
- 配置数据库配置信息
- sqlSessionFactory的配置, 该配置项中还要绑定mybatis配置文件
- sqlSession的配置,但在这里提供另外一种扫描包的方式,直接读取dao层下的所有包文件
这部分可以当做固定配置
<?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
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/ssmbuild?useSSL=true&useUnicode=true&characterEncoding=UTF-8"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</bean>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation" value="classpath:mybatis.-config.xml"/>
</bean>
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
<property name="basePackage" value="com.huang.dao"/>
</bean>
</beans>
接下来轻松的进入到springMVC层,我们就可以调用方法读取数据,渲染前端界面了1
springmvc层搭建
添加web服务
配置web.xml
常用的配置:springMVC提供的任务分发DispatcherServletj和编码过滤器CharacterEncodingFilter
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<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>
<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>
配置/spring-mvc.xml
想到这里,立刻联想到上周分享过的处理器映射器,处理器适配器,视图解析器,似乎是亘古不变的
包含controller层扫描包,静态资源处理器等
<context:component-scan base-package="com.huang.controller" />
<mvc:default-servlet-handler />
<mvc:annotation-driven/>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
controller层搭建
在BookController我们使用注解,注解意思在上篇博客已经说明
说明:
在controller层,我们调用业务层,给bookService自动装配BookServiceImpl实现类,bookService.queryAllBook();就相当于调用BookServiceImpl.queryAllBook(),在BookServiceImpl的queryAllBook方法中我们又调用了dao层bookMapper的queryAllBook方法来查询数据。
理解了最绕的一环,我们就快看到胜利了!
@Controller
@RequestMapping("/book")
public class BookController {
@Autowired
@Qualifier("BookServiceImpl")
private BookService bookService;
// 查询全部数据,并返回到一个书籍展示页面
@RequestMapping("/allBook")
public String list(Model model){
List<Books> books = bookService.queryAllBook();
model.addAttribute("list",books);
return "allBook";
}
}
前端页面(在这里使用的是jsp)
查看全部图书信息
后台返回的list字符串**(由于没有使用jackson)**,前端页面${list}拿到后可以渲染
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h3>书籍展示页面</h3>
<table>
<thead>
<tr>
<th>书籍编号</th>
<th>书籍名称</th>
<th>书籍数量</th>
<th>书籍详情</th>
</tr>
</thead>
<tbody>
<c:forEach var ="book" items="${list}">
<tr>
<td>${book.bookId}</td>
<td>${book.bookName}</td>
<td>${book.bookCounts}</td>
<td>${book.detail}</td>
</tr>
</c:forEach>
</tbody>
</table>
</body>
</html>
效果图:
添加书籍
那么总结完这个案例我们就到此为止啦,接下来的道路任重道远,继续努力哈
我们在查看全部书籍页面添加添加书籍的超链接
<a href="${pageContext.request.contextPath}/book/toAllBook">进入添加图书页面</a>
在BookController类中新增两个方法
一个用来跳转到新增书籍页面:return “addBook”;;一个用来实现新增书籍并重定向到查看所有书籍的页面:return “redirect:/book/allBook”;
@RequestMapping("/toAllBook")
public String toAddBook(){
return "addBook";
}
@RequestMapping("/addBook")
public String addBook(Books books){
System.out.println("addBook"+books);
bookService.addBook(books);
return "redirect:/book/allBook";
}
/addBook.jsp前端代码
当我们的action指定的路径匹配到后台的接口名,后台在接受前端参数时,前端一定要使用name属性来标明该字段,且必须和数据表中的字段保持一致
<form action="${pageContext.request.contextPath}/book/addBook" method="post">
<span>书籍名称:</span>
<input type="text" name="bookName" required/>
<br>
<span>书籍数量:</span>
<input type="text" name="bookCounts" required/>
<br>
<span>书籍描述:</span>
<input type="text" name="detail" required/>
<br>
<input type="submit" value="确认添加"/>
</form>
到这里,我们来看一段专业前端代码:
现在知道为什么前端的参数名要和后台保持一致了吧,不然后台会报错:空指针异常
let params = {
type: 0,
backAcctId: this.backAcctId,
materialType:this.picVideo,
};
const {data:res} = await axios.post(
'/adminjson/ERP_AddJrttAdMaterial',
params
);
浏览器效果图:
点击添加后:
到这里我们可以发现:
我们似乎只需要编写controller层的接口以及前端的代码,实现联调,就能够完成开发了
恭喜你,和我一起完成一场酣畅淋漓的学习之旅!
结语
Java学习和前端学习之路任重道远,趁年轻,努力学习。
在追求技术的道路上,一定要精益求精!
祝大家新年快乐,明年再一起更上一层楼!