图书管理系统(SpringBoot+SpringMVC+MyBatis)

1.数据库表设计

数据库表是应⽤程序开发中的⼀个重要环节, 数据库表的设计往往会决定我们的应⽤需求是否能顺利实现, 甚至决定我们的实现方式. 如何设计表以及这些表有哪些字段、关系也是非常重要的.

数据库表设计是依据业务需求来设计的,数据库表通常分两种: 实体表和关系表.

创建数据库 book_test

 
  1. -- 创建数据库

  2. DROP DATABASE IF EXISTS book_test;

  3. CREATE DATABASE book_test DEFAULT CHARACTER SET utf8mb4;

  4. USE book_test;

  5. -- ⽤户表

  6. DROP TABLE IF EXISTS user_info;

  7. CREATE TABLE user_info (

  8. `id` INT NOT NULL AUTO_INCREMENT,

  9. `user_name` VARCHAR ( 128 ) NOT NULL,

  10. `password` VARCHAR ( 128 ) NOT NULL,

  11. `delete_flag` TINYINT ( 4 ) NULL DEFAULT 0,

  12. `create_time` DATETIME DEFAULT now(),

  13. `update_time` DATETIME DEFAULT now() ON UPDATE now(),

  14. PRIMARY KEY ( `id` ),

  15. UNIQUE INDEX `user_name_UNIQUE` ( `user_name` ASC )) ENGINE = INNODB DEFAULT CHARSET = utf8mb4 COMMENT = '⽤户表 ';

  16. -- 图书表

  17. DROP TABLE IF EXISTS book_info;

  18. CREATE TABLE `book_info` (

  19. `id` INT ( 11 ) NOT NULL AUTO_INCREMENT,

  20. `book_name` VARCHAR ( 127 ) NOT NULL,

  21. `author` VARCHAR ( 127 ) NOT NULL,

  22. `count` INT ( 11 ) NOT NULL,

  23. `price` DECIMAL (7,2 ) NOT NULL,

  24. `publish` VARCHAR ( 256 ) NOT NULL,

  25. `status` TINYINT ( 4 ) DEFAULT 1 COMMENT '0-⽆效 , 1-正常 , 2-不允许借阅 ',

  26. `create_time` DATETIME DEFAULT now(),

  27. `update_time` DATETIME DEFAULT now() ON UPDATE now(),

  28. PRIMARY KEY ( `id` )

  29. ) ENGINE = INNODB DEFAULT CHARSET = utf8mb4;

  30. -- 初始化数据

  31. INSERT INTO user_info ( user_name, PASSWORD ) VALUES ( "admin", "admin" );

  32. INSERT INTO user_info ( user_name, PASSWORD ) VALUES ( "zhangsan", "123456" );

  33. -- 初始化图书数据

  34. INSERT INTO `book_info` (book_name,author,count, price, publish) VALUES ('活着 ','Romised',100,12.2,'出版社');

  35. INSERT INTO `book_info` (book_name,author,count, price, publish) VALUES ('不活着', 'Romised', 100, 22.2, '出版社');

  36. INSERT INTO `book_info` (book_name,author,count, price, publish) VALUES ('想活着 ','Romised',100,32.2,'出版社');

  37. INSERT INTO `book_info` (book_name,author,count, price, publish) VALUES ('要活着 ','Romised',100,42.2,'出版社');

2.引入MyBatis和MySQL驱动依赖

修改pom.xml文件:

<dependency>

  1. <groupId>org.mybatis.spring.boot</groupId>

  2. <artifactId>mybatis-spring-boot-starter</artifactId>

  3. <version>2.3.1</version>

  4. </dependency>

  5. <dependency>

  6. <groupId>com.mysql</groupId>

  7. <artifactId>mysql-connector-j</artifactId>

  8. <scope>runtime</scope>

  9. </dependency>

3.配置数据库&日志

修改application.yml配置文件:

  1. # 数据库连接配置

  2. spring:

  3. datasource:

  4. url: jdbc:mysql://127.0.0.1:3306/book_test?characterEncoding=utf8&useSSL=false

  5. username: root

  6. password: 123456

  7. driver-class-name: com.mysql.cj.jdbc.Driver

  8. mybatis:

  9. configuration:

  10. map-underscore-to-camel-case: true #配置驼峰自动转换

  11. # log-impl: org.apache.ibatis.logging.stdout.StdOutImpl #打印sql语句

  12. mapper-locations: classpath:mapper/**Mapper.xml

  13. # 设置日志文件的文件名

  14. logging:

  15. file:

  16. name: logger/spring-book.log

4.Model创建

创建UserInfo类:

  1. @Data

  2. public class UserInfo {

  3. private Integer id;

  4. private String userName;

  5. private String password;

  6. private Integer deleteFlag;

  7. private Date createTime;

  8. private Date updateTime;

  9. }

创建BookInfo类:

 
  1. @Data

  2. public class BookInfo {

  3. private Integer id;

  4. private String bookName;

  5. private String author;

  6. private Integer count;

  7. //前端展示精度

  8. @JsonFormat(shape = JsonFormat.Shape.STRING)

  9. private BigDecimal price;

  10. private String publish;

  11. private Integer status; //0-删除 1-可借阅,2-不可借阅

  12. private String statusCN;

  13. }

5.用户登录功能实现

约定前后端交互接口:

 
  1. [请求]

  2. /user/login

  3. Content-Type: application/x-www-form-urlencoded; charset=UTF-8

  4. [参数]

  5. name=zhangsan&password=123456 8

  6. [响应]

  7. true //账号密码验证正确 , 否则返回false

浏览器给服务器发送/user/login这样的HTTP请求,服务器给浏览器返回Boolean类型的数据

实现服务器代码

控制层:从数据库中, 根据名称查询用户, 如果可以查到, 并且密码⼀致, 就认为登录成功 

创建UserController:

 
  1. @RequestMapping("/user")

  2. @RestController

  3. public class UserController {

  4. @Autowired

  5. private UserService userService;

  6. @RequestMapping("/login")

  7. public Boolean login(String userName, String password, HttpSession session){

  8. //校验参数是否为空

  9. if (!StringUtils.hasLength(userName) || !StringUtils.hasLength(password)){

  10. return false;

  11. }

  12. //验证账号密码是否正确

  13. //1. 根据用户名去查找用户信息

  14. UserInfo userInfo = userService.getUserInfoByName(userName);

  15. //2. 比对密码是否正确

  16. if (userInfo==null || userInfo.getId()<=0){

  17. return false;

  18. }

  19. if (password.equals(userInfo.getPassword())){

  20. //账号密码正确

  21. //存Session

  22. userInfo.setPassword("");

  23. session.setAttribute(Constants.SESSION_USER_KEY,userInfo);

  24. return true;

  25. }

  26. return false;

  27. }

  28. }

业务层:

创建UserService:

  1. @Service

  2. public class UserService {

  3. @Autowired

  4. private UserInfoMapper userInfoMapper;

  5. public UserInfo getUserInfoByName(String name){

  6. return userInfoMapper.selectUserByName(name);

  7. }

  8. }

数据层:

创建UserInfoMapper:

  1. @Mapper

  2. public interface UserInfoMapper {

  3. /**

  4. * 根据用户名称查询用户信息

  5. * @param name

  6. * @return

  7. */

  8. @Select("select * from user_info where user_name=#{name}")

  9. UserInfo selectUserByName(String name);

  10. }

这边使用*是为了方便观察,开发中需要挨个写出数据库字段名

 测试:

部署程序,验证服务器是否能够正确返回数据,可以在Postman中输入URL进行测试,最好联动前端一起进行测试:

输⼊错误的⽤户名和密码, 页面弹窗警告

 输入正确的用户名和密码, 页面正常跳转到booklist.html页面

 6.实现添加图书功能

约定前后端交互接口:

 
  1. [请求]

  2. /book/addBook

  3. Content-Type: application/x-www-form-urlencoded; charset=UTF-8

  4. [参数]

  5. bookName=图书1&author=作者1&count=23&price=36&publish=出版社1&status=1

  6. [响应]

  7. "" //失败信息 , 成功时返回空字符串

我们约定,浏览器给服务器发送book/addBook这样的HTTP请求,以from表单的形式提交数据

服务器返回处理结果, 返回""表示添加图书成功, 否则, 返回失败信息.

实现服务器代码 

控制层:

创建BookController:

 
  1. @Slf4j

  2. @RequestMapping("/book")

  3. @RestController

  4. public class BookController {

  5. @Autowired

  6. private BookService bookService;

  7. @RequestMapping("/getBookListByPage")

  8. public Result getBookListByPage(PageRequest pageRequest, HttpSession session){

  9. log.info("查询翻页信息, pageRequest:{}",pageRequest);

  10. //用户登录校验

  11. UserInfo userInfo = (UserInfo) session.getAttribute(Constants.SESSION_USER_KEY);

  12. if (userInfo==null|| userInfo.getId()<=0 || "".equals(userInfo.getUserName())){

  13. //用户未登录

  14. return Result.unlogin();

  15. }

  16. //校验成功

  17. if (pageRequest.getPageSize()<0 || pageRequest.getCurrentPage()<1){

  18. return Result.fail("参数校验失败");

  19. }

  20. PageResult<BookInfo> bookInfoPageResult = null;

  21. try {

  22. bookInfoPageResult = bookService.selectBookInfoByPage(pageRequest);

  23. return Result.success(bookInfoPageResult);

  24. }catch (Exception e){

  25. log.error("查询翻页信息错误,e:{}",e);

  26. return Result.fail(e.getMessage());

  27. }

  28. }

  29. @RequestMapping(value = "/addBook", produces = "application/json")

  30. public String addBook(BookInfo bookInfo){

  31. log.info("接收到添加图书请求, bookInfo:{}",bookInfo);

  32. //参数校验

  33. if (!StringUtils.hasLength(bookInfo.getBookName())

  34. || !StringUtils.hasLength(bookInfo.getAuthor())

  35. || bookInfo.getCount()<0

  36. || bookInfo.getPrice()==null

  37. || !StringUtils.hasLength(bookInfo.getPublish())){

  38. return "参数校验失败, 请检查入参";

  39. }

  40. Integer result = bookService.addBook(bookInfo);

  41. if (result<=0){

  42. log.error("添加图书出错:bookInfo:{}",bookInfo);

  43. return "添加图书出错, 请联系管理人";

  44. }

  45. return "";

  46. }

  47. }

业务层:

创建BookService:

 
  1. @Slf4j

  2. @Service

  3. public class BookService {

  4. @Autowired

  5. private BookInfoMapper bookInfoMapper;

  6. /**

  7. * 添加图书

  8. *

  9. * @param bookInfo

  10. * @return

  11. */

  12. public Integer addBook(BookInfo bookInfo) {

  13. Integer result = 0;

  14. try {

  15. result = bookInfoMapper.insertBook(bookInfo);

  16. } catch (Exception e) {

  17. log.error("添加图书出错, e:{}", e);

  18. }

  19. return result;

  20. }

  21. }

数据层:

创建BookInfoMapper文件:

 
  1. @Mapper

  2. public interface BookInfoMapper {

  3. /**

  4. * 获取当前页的信息

  5. * @param offset

  6. * @param pageSize

  7. * @return

  8. */

  9. @Select("select * from book_info where status !=0 " +

  10. "order by id asc limit #{offset},#{pageSize}")

  11. List<BookInfo> selectBookInfoByPage(Integer offset, Integer pageSize);

  12. @Insert("insert into book_info (book_name,author, count, price, publish, status) " +

  13. "values(#{bookName}, #{author}, #{count}, #{price},#{publish}, #{status})")

  14. Integer insertBook(BookInfo bookInfo);

  15. }

前端代码中补全add():

 
  1. function add() {

  2. $.ajax({

  3. type:"post",

  4. url: "/book/addBook",

  5. data:$("#addBook").serialize(),//提交整个form表单

  6. success:function(result){

  7. if (result != null && result.code == "SUCCESS" && result.data=="") {

  8. //图书添加成功

  9. location.href = "book_list.html";

  10. }else{

  11. console.log(result.code);

  12. alert(result);

  13. }

  14. },

  15. error: function (error) {

  16. console.log(error);

  17. //用户未登录

  18. if (error != null && error.status == 401) {

  19. location.href = "login.html";

  20. }

  21. }

  22. });

  23. }

7.实现翻页功能

假设数据库中的数据有很多,一下子全部展示出来肯定不现实,我们可以使用分页来解决这个问题

分页时, 数据是如何展示的呢 第1页: 显⽰1-10 条的数据、第2页: 显⽰11-20 条的数据 第3页: 显⽰21-30 条的数据 以此类推...

要想实现这个功能, 从数据库中进行分页查询 ,我们要使用LIMIT关键字

查询第一页的SQL语句:

 SELECT * FROM book_info LIMIT 0,10

查询第二页的SQL语句:

 SELECT * FROM book_info LIMIT 10,10

查询第三页的SQL语句:

 SELECT * FROM book_info LIMIT 20,10

观察以上SQL语句 ,发现: 开始索引⼀直在改变, 每页显⽰条数是固定的 开始索引的计算公式: 开始索引 = (当前页码 - 1) * 每页显示条数

前端在发起查询请求时 ,需要向服务端传递的参数 。

currentPage  当前页码,默认值为1

pageSize 每页显示条数,默认值为10

为了项⽬更好的扩展性, 通常不设置固定值,而是以参数的形式来进行传递 扩展性: 软件系统具备面对未来需求变化而进行扩展的能⼒

比如当前需求⼀页显示10条, 后期需求改为⼀页显示20条, 后端代码不需要任何修改

后端响应时, 需要响应给前端的数据

records 所查询到的数据列表(存储到List 集合中)

total  总记录数 (用于告诉前端显示多少页, 显示页数为:(total+pageSize-1)/pageSize

显示页数totalPage 计算公式为 : total % pagesize == 0 ? total / pagesize : (total / pagesize)+1 ;

pagesize - 1 是 total / pageSize 的最⼤的余数 ,所以(total + pagesize -1) / pagesize就得到总页数

 翻页请求和响应部分, 我们通常封装在两个对象中

翻页请求对象:

 
  1. @Data

  2. public class PageRequest {

  3. private int currentPage = 1; // 当前页

  4. private int pageSize = 10; // 每页中的记录数

  5. private int offset;

  6. public int getOffset() {

  7. return (currentPage-1) * pageSize;

  8. }

  9. }

翻页列表结果类:

 
  1. import lombok.Data;

  2. import java.util.List;

  3. @Data

  4. public class PageResult<T> {

  5. private int total;//所有记录数

  6. private List<T> records; // 当前页数据

  7. public PageResult(Integer total, List<T> records) {

  8. this.total = total;

  9. this.records = records;

  10. }

  11. }

 返回结果中, 使⽤泛型来定义记录的类型 

约定前后端交互接口

 
  1. [请求]

  2. /book/getListByPage?currentPage=1

  3. Content-Type: application/x-www-form-urlencoded; charset=UTF-8

  4. [参数]

  5. [响应]

  6. Content-Type: application/json 10

  7. {

  8. "total": 25,

  9. "records": [{

  10. "id": 25,

  11. "bookName": "图书21",

  12. "author": "作者2",

  13. "count": 29,

  14. "price": 22.00,

  15. "publish": "出版社1",

  16. "status": 1,

  17. "statusCN": "可借阅 "

  18. }, {

  19. ......

  20. } ]

  21. }

我们约定,浏览器给服务器发送book/getListByPage这样的HTTP请求,通过currentPage参数告诉服务器当前请求为第几页的数据, 后端根据请求参数, 返回对应页的数据

实现服务器代码 

控制层:

完善 BookController:

 
  1. @Slf4j

  2. @RequestMapping("/book")

  3. @RestController

  4. public class BookController {

  5. @Autowired

  6. private BookService bookService;

  7. @RequestMapping("/getBookListByPage")

  8. public Result getBookListByPage(PageRequest pageRequest, HttpSession session){

  9. log.info("查询翻页信息, pageRequest:{}",pageRequest);

  10. // //用户登录校验

  11. // UserInfo userInfo = (UserInfo) session.getAttribute(Constants.SESSION_USER_KEY);

  12. // if (userInfo==null|| userInfo.getId()<=0 || "".equals(userInfo.getUserName())){

  13. // //用户未登录

  14. // return Result.unlogin();

  15. // }

  16. //校验成功

  17. if (pageRequest.getPageSize()<0 || pageRequest.getCurrentPage()<1){

  18. return Result.fail("参数校验失败");

  19. }

  20. PageResult<BookInfo> bookInfoPageResult = null;

  21. try {

  22. bookInfoPageResult = bookService.selectBookInfoByPage(pageRequest);

  23. return Result.success(bookInfoPageResult);

  24. }catch (Exception e){

  25. log.error("查询翻页信息错误,e:{}",e);

  26. return Result.fail(e.getMessage());

  27. }

  28. }

  29. @RequestMapping(value = "/addBook", produces = "application/json")

  30. public String addBook(BookInfo bookInfo){

  31. log.info("接收到添加图书请求, bookInfo:{}",bookInfo);

  32. //参数校验

  33. if (!StringUtils.hasLength(bookInfo.getBookName())

  34. || !StringUtils.hasLength(bookInfo.getAuthor())

  35. || bookInfo.getCount()<0

  36. || bookInfo.getPrice()==null

  37. || !StringUtils.hasLength(bookInfo.getPublish())){

  38. return "参数校验失败, 请检查入参";

  39. }

  40. Integer result = bookService.addBook(bookInfo);

  41. if (result<=0){

  42. log.error("添加图书出错:bookInfo:{}",bookInfo);

  43. return "添加图书出错, 请联系管理人";

  44. }

  45. return "";

  46. }

  47. @RequestMapping("/queryBookInfoById")

  48. public BookInfo queryBookInfoById(Integer bookId){

  49. // long start = System.currentTimeMillis();

  50. log.info("根据ID查询图书, bookId:"+bookId);

  51. BookInfo bookInfo = null;

  52. try {

  53. bookInfo = bookService.queryBookInfoById(bookId);

  54. }catch (Exception e){

  55. log.error("查询图书失败, e:{}",e);

  56. }

  57. // long end = System.currentTimeMillis();

  58. // log.info("queryBookInfoById 执行耗时: "+ (end-start) + "ms");

  59. return bookInfo;

  60. }

  61. @RequestMapping(value = "/updateBook", produces = "application/json")

  62. public String updateBook(BookInfo bookInfo){

  63. log.info("接收到更新图书的请求, bookInfo:{}",bookInfo);

  64. Integer result = bookService.updateBook(bookInfo);

  65. if (result == 0){

  66. log.error("更新图书失败, 请联系管理员");

  67. return "更新图书失败, 请联系管理员";

  68. }

  69. return "";

  70. }

  71. @RequestMapping(value = "/batchDelete", produces = "application/json")

  72. public String batchDelete(@RequestParam List<Integer> ids){

  73. log.info("接收请求, 批量删除图书, 图书ID:{}",ids);

  74. Integer result = bookService.batchDelete(ids);

  75. if (result<=0){

  76. log.error("批量删除失败, ids:{}",ids);

  77. return "批量删除失败, 请联系管理员";

  78. }

  79. return "";

  80. }

  81. }

业务层:

BookService

 
  1. @Slf4j

  2. @Service

  3. public class BookService {

  4. @Autowired

  5. private BookInfoMapper bookInfoMapper;

  6. public PageResult<BookInfo> selectBookInfoByPage(PageRequest pageRequest) {

  7. if (pageRequest == null) {

  8. return null;

  9. }

  10. //获取总记录数

  11. Integer count = bookInfoMapper.count();

  12. //获取当前记录

  13. List<BookInfo> bookInfos = bookInfoMapper.selectBookInfoByPage(pageRequest.getOffset(), pageRequest.getPageSize());

  14. if (bookInfos != null && bookInfos.size() > 0) {

  15. for (BookInfo bookInfo : bookInfos) {

  16. //根据status 获取状态的定义

  17. bookInfo.setStatusCN(BookStatusEnum.getNameByCode(bookInfo.getStatus()).getName());

  18. }

  19. }

  20. return new PageResult<>(bookInfos, count, pageRequest);

  21. }

  22. /**

  23. * 添加图书

  24. *

  25. * @param bookInfo

  26. * @return

  27. */

  28. public Integer addBook(BookInfo bookInfo) {

  29. Integer result = 0;

  30. try {

  31. result = bookInfoMapper.insertBook(bookInfo);

  32. } catch (Exception e) {

  33. log.error("添加图书出错, e:{}", e);

  34. }

  35. return result;

  36. }

  37. public BookInfo queryBookInfoById(Integer id) {

  38. return bookInfoMapper.queryBookInfoById(id);

  39. }

  40. /**

  41. * 更新图书

  42. * @param bookInfo

  43. * @return

  44. */

  45. public Integer updateBook(BookInfo bookInfo) {

  46. Integer result = 0;

  47. try {

  48. result = bookInfoMapper.updateBook(bookInfo);

  49. } catch (Exception e) {

  50. log.error("更新图书失败, e:{}", e);

  51. }

  52. return result;

  53. }

  54. public Integer batchDelete(List<Integer> ids){

  55. Integer result =0;

  56. try {

  57. result = bookInfoMapper.batchDelete(ids);

  58. }catch (Exception e){

  59. log.error("批量删除图书失败, ids:{}",ids);

  60. }

  61. return result;

  62. }

  63. }

 翻页信息需要返回数据的总数和列表信息, 需要查两次SQL

 图书状态: 图书状态和数据库存储的status有⼀定的对应关系

如果后续状态码有变动, 我们需要修改项目中所有涉及的代码, 这种情况, 通常采用枚举类来处理映射关系

数据层:

翻页查询SQL

 
  1. @Mapper

  2. public interface BookInfoMapper {

  3. /**

  4. * 获取当前页的信息

  5. * @param offset

  6. * @param pageSize

  7. * @return

  8. */

  9. @Select("select * from book_info where status !=0 " +

  10. "order by id asc limit #{offset},#{pageSize}")

  11. List<BookInfo> selectBookInfoByPage(Integer offset, Integer pageSize);

  12. /**

  13. * 获取总记录数

  14. * @return

  15. */

  16. @Select("select count(1) from book_info where status !=0")

  17. Integer count();

  18. }

 实现客户端代码:

 
  1. function getBookList() {

  2. $.ajax({

  3. type: "get",

  4. url: "/book/getBookListByPage" + location.search,

  5. success: function (result) {

  6. //真实的前端处理逻辑, 要比咱们代码复杂

  7. if (result.code == "UNLOGIN") {

  8. location.href = "login.html";

  9. return;

  10. }

  11. var finalHtml = "";

  12. //加载列表

  13. var pageResult = result.data;

  14. for (var book of pageResult.records) {

  15. //根据每一条记录去拼接html, 也就是一个tr

  16. finalHtml += '<tr>';

  17. finalHtml += '<td><input type="checkbox" name="selectBook" value="' + book.id + '" id="selectBook" class="book-select"></td>';

  18. finalHtml += '<td>' + book.id + '</td>';

  19. finalHtml += '<td>' + book.bookName + '</td>';

  20. finalHtml += '<td>' + book.author + '</td>';

  21. finalHtml += '<td>' + book.count + '</td>';

  22. finalHtml += '<td>' + book.price + '</td>';

  23. finalHtml += '<td>' + book.publish + '</td>';

  24. finalHtml += '<td>' + book.statusCN + '</td>';

  25. finalHtml += '<td><div class="op">';

  26. finalHtml += '<a href="book_update.html?bookId=' + book.id + '">修改</a>';

  27. finalHtml += '<a href="javascript:void(0)" onclick="deleteBook(' + book.id + ')">删除</a>';

  28. finalHtml += '</div></td></tr>';

  29. }

  30. $("tbody").html(finalHtml);

  31. //翻页信息

  32. $("#pageContainer").jqPaginator({

  33. totalCounts: pageResult.total, //总记录数

  34. pageSize: 10, //每页的个数

  35. visiblePages: 5, //可视页数

  36. currentPage: pageResult.pageRequest.currentPage, //当前页码

  37. first: '<li class="page-item"><a class="page-link">首页</a></li>',

  38. prev: '<li class="page-item"><a class="page-link" href="javascript:void(0);">上一页<\/a><\/li>',

  39. next: '<li class="page-item"><a class="page-link" href="javascript:void(0);">下一页<\/a><\/li>',

  40. last: '<li class="page-item"><a class="page-link" href="javascript:void(0);">最后一页<\/a><\/li>',

  41. page: '<li class="page-item"><a class="page-link" href="javascript:void(0);">{{page}}<\/a><\/li>',

  42. //页面初始化和页码点击时都会执行

  43. onPageChange: function (page, type) {

  44. console.log("第" + page + "页, 类型:" + type);

  45. if (type == "change") {

  46. location.href = "book_list.html?currentPage=" + page;

  47. }

  48. }

  49. });

  50. },

  51. error: function (error) {

  52. console.log(error);

  53. if (error.status == 401) {

  54. console.log("401");

  55. location.href = "login.html";

  56. }

  57. }

  58. });

  59. }

  • 27
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面是使用SpringBootSpringMVCMyBatis、MySQL完成图书信息管理系统的代码示例: 1. 配置文件application.properties ```properties # 数据库连接配置 spring.datasource.driver-class-name=com.mysql.jdbc.Driver spring.datasource.url=jdbc:mysql://localhost:3306/book_manager?useUnicode=true&characterEncoding=utf-8&useSSL=false spring.datasource.username=root spring.datasource.password=123456 # MyBatis配置 mybatis.type-aliases-package=com.example.bookmanager.entity mybatis.mapper-locations=classpath:mapper/*.xml # Spring Boot配置 server.port=8080 ``` 2. 实体类Book.java ```java public class Book { private Integer id; private String name; private String author; private String description; // 省略getter和setter方法 } ``` 3. Dao层BookDao.java ```java @Mapper public interface BookDao { // 查询所有图书信息 List<Book> findAllBooks(); // 根据id查询图书信息 Book findBookById(Integer id); // 添加图书信息 void addBook(Book book); // 更新图书信息 void updateBook(Book book); // 删除图书信息 void deleteBook(Integer id); } ``` 4. Mapper文件BookMapper.xml ```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="com.example.bookmanager.dao.BookDao"> <!-- 查询所有图书信息 --> <select id="findAllBooks" resultType="com.example.bookmanager.entity.Book"> select * from book </select> <!-- 根据id查询图书信息 --> <select id="findBookById" parameterType="int" resultType="com.example.bookmanager.entity.Book"> select * from book where id = #{id} </select> <!-- 添加图书信息 --> <insert id="addBook" parameterType="com.example.bookmanager.entity.Book"> insert into book(name, author, description) values(#{name}, #{author}, #{description}) </insert> <!-- 更新图书信息 --> <update id="updateBook" parameterType="com.example.bookmanager.entity.Book"> update book set name=#{name}, author=#{author}, description=#{description} where id=#{id} </update> <!-- 删除图书信息 --> <delete id="deleteBook" parameterType="int"> delete from book where id=#{id} </delete> </mapper> ``` 5. Service层BookService.java ```java @Service public class BookService { @Autowired private BookDao bookDao; // 查询所有图书信息 public List<Book> findAllBooks() { return bookDao.findAllBooks(); } // 根据id查询图书信息 public Book findBookById(Integer id) { return bookDao.findBookById(id); } // 添加图书信息 public void addBook(Book book) { bookDao.addBook(book); } // 更新图书信息 public void updateBook(Book book) { bookDao.updateBook(book); } // 删除图书信息 public void deleteBook(Integer id) { bookDao.deleteBook(id); } } ``` 6. Controller层BookController.java ```java @RestController @RequestMapping("/book") public class BookController { @Autowired private BookService bookService; // 查询所有图书信息 @GetMapping("/findAllBooks") public List<Book> findAllBooks() { return bookService.findAllBooks(); } // 根据id查询图书信息 @GetMapping("/findBookById") public Book findBookById(Integer id) { return bookService.findBookById(id); } // 添加图书信息 @PostMapping("/addBook") public void addBook(@RequestBody Book book) { bookService.addBook(book); } // 更新图书信息 @PostMapping("/updateBook") public void updateBook(@RequestBody Book book) { bookService.updateBook(book); } // 删除图书信息 @GetMapping("/deleteBook") public void deleteBook(Integer id) { bookService.deleteBook(id); } } ``` 以上就是使用SpringBootSpringMVCMyBatis、MySQL完成图书信息管理系统的代码示例,希望能对您有所帮助!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值