样卷
一、功能要求
请编写一个程序,完成对图书的管理 ,实现显示所有图书、添加图书、编辑图书、删除图书以及多条件查询图书功能。
二、具体功能要求及推荐实现步骤
导入sb-frame项目,在此之上实现上述功能,在工程名之后,加上班级和学号(如:sb-frame-ruanjian211-10),采用MVC 设计模式,并使用Springboot、SpringMVC、Mybatis 和Thymeleaf等技术开发此系统,需要定义如下类:
- 创建数据库bms,数据表:图书信息表(tb_book)、图书类别信息表(tb_type),设置主键自增,并添加不少于3条测试数据,表结构如表1、表2所示。
- 创建实体类Book、Type,根据业务提供需要的构造方法和setter/getter方法。
- 创建BookMapper类,编写添加图书方法、获取所有图书方法、删除图书、编辑图书和多条件查询图书(根据图书名称、图书类型、图书描述);创建TypeMapper,编写获取图书类别列表的方法。
- 编写controller接口实现以下功能:
- 处理查询所有图书的请求,界面命名为book_list.html;
- 处理跳转到添加图书页面的请求,界面命名为book_add.html;
- 处理图书添加的请求并跳转至列表界面;
- 处理跳转到编辑图书页面的请求,界面命名为book_edit.html;
- 处理图书修改的请求并跳转到列表界面;
- 处理删除图书的请求并跳转到列表界面;
- 处理多条件查询请求并跳转到列表界面;
表1 图书信息表
表名 | tb_book | |||
列名 | 数据类型(精度范围) | 空/非空 | 约束条件 | 注释 |
id | int | 非空 | PK | 图书id |
name | varchar(50) | 非空 | 图书名称 | |
desc | varchar(200) | 非空 | 图书描述 | |
type_id | int | 非空 | 图书类别id |
表2 图书分类信息表
表名 | tb_type | |||
列名 | 数据类型(精度范围) | 空/非空 | 约束条件 | 注释 |
id | int | 非空 | PK | 类别id |
type | varchar(30) | 非空 | 类别名称 |
一、执行下面的sql
CREATE DATABASE bms CHARACTER SET utf8mb4;
USE bms;
DROP TABLE IF EXISTS `tb_book`;
CREATE TABLE `tb_book` (
`id` INT NOT NULL AUTO_INCREMENT,
`name` VARCHAR(20) NOT NULL,
`desc` TEXT ,
`type_id` INT DEFAULT NULL,
PRIMARY KEY (`id`)
) ;
INSERT INTO `tb_book` VALUES (7,'gaodengshuxue','haoshu',3),(9,'测试数据','测试描述数据',2),(16,'测试数据increase','测试数据',3),(17,'测试数据increase','测试数据',4),(18,'xiyouji','bad',2),(19,'测试数据increase','测试数据',NULL),(27,'xiyouji2','bad',2),(28,'xiyouji2','bad',2),(29,'xiyouji2','bad',2);
DROP TABLE IF EXISTS `tb_type`;
CREATE TABLE `tb_type` (
`id` INT NOT NULL AUTO_INCREMENT,
`type` VARCHAR(30) DEFAULT NULL,
PRIMARY KEY (`id`)
);
INSERT INTO `tb_type` VALUES (1,'计算机'),(2,'文学'),(3,'数学'),(4,'历史');
二、导入项目的基本结构
三、在主配置文件里检查数据库名字并启动项目
application.properties:
spring.datasource.druid.url=jdbc:mysql://localhost:3306/bms?serverTimezone=UTC
如果控制台提示如下内容:
Tomcat started on port(s): 8081 (http) with context path ''
Started SbApplication in 2.066 seconds (JVM running for 2.459)
那么启动成功了。
四、查询所有图书
1、创建实体类Book和Type
public class Book {
private Integer id;
private String name;
private String type;
private String desc;
private Integer typeId;
public Book(String name, String type, String desc) {
super();
this.name = name;
this.type = type;
this.desc = desc;
}
public Book() {
super();
// TODO Auto-generated constructor stub
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
public Integer getTypeId() {
return typeId;
}
public void setTypeId(Integer typeId) {
this.typeId = typeId;
}
}
public class Type {
private Integer id;
private String type;
public Type() {
super();
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}
2、创建Mapper,添加查询所有图书的方法
@Mapper
public interface BookMapper {
@Select("select b.id,b.name,b.desc,t.type "
+ "from tb_book b left join tb_type t "
+ "on b.type_id = t.id")
List<Book> selectAll();
}
3、创建controller
@Controller
public class BookController {
@Autowired
private BookMapper dao;
@GetMapping("/books")
public String getAllBooks(Model model){
// 设置集合数据
List<Book> datas = dao.selectAll();
model.addAttribute("books", datas);
model.addAttribute("today", Calendar.getInstance());
return "book_list";
}
}
4、创建页面book_list.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>图书管理</title>
<style>
.oushu{
background-color: gray;
}
</style>
</head>
<body>
<p>
Today is: <span th:text="${#calendars.format(today,'yyyy MMMM dd')}">13 May 2011</span>
</p>
<table border="1" frame="below" rules="rows" width="100%" cellpadding="10">
<tr>
<th>序号</th>
<th>图书类型</th>
<th>图书名称</th>
<th>图书描述</th>
<th colspan="2">操作</th>
</tr>
<tr th:each="book ,status: ${books}" th:class="${status.even}?'oushu'">
<td th:text='${status.count}' align="center"></td>
<td th:text='${book.type}' align="center"></td>
<td th:text='${book.name}' align="center"></td>
<td th:text='${book.desc}' align="center"></td>
<td align="right"><a th:href="@{|/toEditPage/${book.id}|}">编辑</a></td>
<td align="left"><a th:href="@{|/delete/${book.id}|}">删除</a></td>
</tr>
</table>
</body>
</html>
5、请求如下:
如果出现如下图片,那么你完成了查询所有图书的操作。
五、删除某本书
在mapper中做删除操作要怎么写?
@Delete("delete from tb_book where id=#{id}")
int deleteById(Integer id);
在controller中处理删除请求的方法要怎么写?
@GetMapping("/delete/{id}")
public String deleteById(@PathVariable Integer id){
int i=dao.deleteById(id);
return "redirect:/books";
}
在列表页面里删除的链接要怎么写?
<a th:href="@{|/delete/${book.id}|}">删除</a>
上面双竖线的作用:拼接字符串,不用自己手动拼接字符串。
六、编辑某本书
0、编辑页面要怎么写?在该页面上你要填充某本书的数据。
<form th:action="@{/edit}" method="post">
<input type="hidden" name="id" th:value="${book.id}" />
<ul>
<li>图书名称:<input type="text" name="name" th:value="${book.name}"></li>
<li>图书描述:<input type="text" name="desc" th:value="${book.desc}"></li>
<li>图书类型:
<ul th:each="type:${types}">
<li><input type="radio" name="typeId" th:value="${type.id}"
th:text=${type.type}
th:checked="${book.typeId==type.id}?'checked'"></li>
</ul>
</li>
<li><input type="submit" value="保存"></li>
</ul>
</form>
1、跳到编辑页面的链接要怎么写?
<a th:href="@{|/toEditPage/${book.id}|}">编辑</a>
2、处理跳到编辑页面的请求要怎么写?
@GetMapping("/toEditPage/{id}")
public String toEditPage(@PathVariable Integer id,Model model){
Book book=dao.selectById(id);
model.addAttribute("book", book);
List<Type> types = typeDao.selectAll();
model.addAttribute("types", types);
return "book_edit";
}
在BookMapper中增加根据id查询书的方法:
@Select("select * from tb_book where id=#{id}")
Book selectById(Integer id);
创建TypeMapper接口,增加查询所有类型的方法:
@Mapper
public interface TypeMapper {
@Select("select * from tb_type")
List<Type> selectAll();
}
3、在你编辑完成后,点击保存,浏览器发送保存请求,那么服务端如何处理这个请求?
@PostMapping("/edit")
public String edit(Book book){
int i=dao.update(book);
return "redirect:/books";
}
在BookMapper中添加更新方法:
@Update("update tb_book set `name`=#{name},`desc`=#{desc},type_id=#{typeId} where id=#{id}")
int update(Book book);
七、新增某本书
0、编写新增页面
<form th:action="@{/add}" method="post">
图书名称:<input type="text" name="name" ><br/>
图书描述:<input type="text" name="desc" ><br/>
图书类型:<div th:each="type:${types}">
<input type="radio" name="typeId" th:text=${type.type} th:value=${type.id}>
</div>
<input type="submit" value="保存">
</form>
1、写出跳到新增页面的链接
<a th:href="@{/toAddPage}">新增</a>
2、处理跳到新增页面的请求
@GetMapping("/toAddPage")
public String toAddPage(Model model){
List<Type> types = typeDao.selectAll();
model.addAttribute("types", types);
return "book_add";
}
3、填写书的信息完毕后,点击保存,如何处理添加请求?
@PostMapping("/add")
public String add(Book book){
int i=dao.add(book);
return "redirect:/books";
}
在BookMapper中添加新增方法:
@Insert("insert into tb_book(name,`desc`,type_id) values(#{name},#{desc},#{typeId})")
int add(Book book);
八、根据多个条件查询图书
1、多个条件在页面上该怎么写
<form th:action="@{/search}" method="post">
<span>图书名称:<input type="text" name="name" ></span>
<span>图书描述:<input type="text" name="desc" ></span>
<span>图书类型:<input type="text" name="type" ></span>
<span><input type="submit" value="查询"></span>
</form>
2、处理/search请求该怎么写
@PostMapping("/search")
public String search(Book book,Model model) {
List<Book> list=dao.search(book);
model.addAttribute("books", list);
return "books";
}
3、BookMapper中search方法该怎么写
List<Book> search(Book book);
4、由于要对条件做动态拼接,所以采用xml形式开发
在src\main\resources\mapper下创建BookMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.zptc.mapper.BookMapper">
<select id="search" parameterType="book" resultType="book">
select * from tb_book b left join tb_type t on b.type_id =t.id
<where>
<if test="name!=null and name != '' ">
and b.name like CONCAT('%',#{name},'%')
</if>
<if test="desc != null and desc != '' ">
and b.desc like CONCAT('%',#{desc},'%')
</if>
<if test="type != null and type != '' ">
and t.type like CONCAT('%',#{type},'%')
</if>
</where>
</select>
</mapper>
还有在application.properties中配置xml文件的位置和实体类的别名包
mybatis.mapper-locations=classpath:mapper/*.xml
mybatis.type-aliases-package=cn.zptc.domain