你能学到什么
- 一个简单的项目——图书管理系统(浏览器:谷歌)
- 基础版我们只做两个功能(因为其它的功能涉及的会比较多,索性就放在升级版里了,基础版先入个门)
-
- 登录: ⽤⼾输⼊账号,密码完成登录功能
-
- 列表展⽰: 展⽰图书
-
- 升级版将会在下个博客发布
正文
成品效果展示
新建项目
前端代码准备
由于主做后端,写前端代码有些吃力,可以在我分享的网盘中拿到下面的前端文件
链接: https://pan.baidu.com/s/1J9LCqfNmpG6CKykj3l772A?pwd=qqu2
提取码: qqu2
测试前端代码
然后运行整个程序,使用浏览器,访问http://127.0.0.1:8080/login.html
看看是否能正常显示,也能访问其他html文件看看是否能正常显示。如果能正常显示就说明复制过来的前端代码没问题,不要计较前端加载的那些数据,那些都是假数据,后期那些代码是需要我们改的。
直接添加Mybatis依赖发生的问题
运行结果:
由于我们没有配置数据库信息,所以会发生报错,解决方案:
- 1,配置数据库信息
- 2,先将Mybatis的依赖删掉,在用的时候在手动添加上,再配置数据库(注意无论是删除还是添加,最好每进行一步刷新一次Maven,这样就不会有缓存问题了)
这两个就是Mybatis的依赖:
编写后端代码
需求分析
根据需求可以得知, 后端需要提供两个接⼝
- 登录账号密码校验接⼝: 根据输⼊⽤⼾名和密码校验登录是否通过
- 图书列表: 提供图书列表信息
登录接口
有了需求文档我们就知道了下一步该做什么,要想验证密码和用户名正不正确,前端肯定会向后端发送用户名和密码。此时我们只需要将用户传过来的用户名和密码和我们存储的用户名和密码对比,如果相同就返回true,反之,返回false。
这里为了方便起见我们就先将用户名和密码写死
name:zhangsan
password:123456
接下就是写代码了,为了实现应用分层,我还是在Controller包里写controller代码
package com.example.blogssystems_blogs.Controller;import jakarta.servlet.http.HttpSession;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;//注意:一定不要写错注解,否则会付出血和泪的教训啊
@RequestMapping("/user")
@RestController
public class UserController {@RequestMapping("/login")public boolean login(String name, String password, HttpSession session){//账号或密码为空if (!StringUtils.hasLength(name) || !StringUtils.hasLength(password)){return false;}if("zhangsan".equals(name) && "123456".equals(password)){//如果正确,就将该信息储存在session里session.setAttribute("username",name);return true;}return false;}}
测试登录代码
我们使用Postman来测试一下
图书列表展示接口
接下来就是获取图书列表接口了,我们知道要想返回图书信息,我们得先有一个图书类啊,用来描述图书
图书实体类代码:
package com.example.blogssystems_blogs.model;import lombok.Data;import java.math.BigDecimal;
import java.util.Date;@Data
public class BookInfo {//图书IDprivate Integer id;//书名private String bookName;//作者private String author;//数量private Integer count;//定价,BigDecimal有兴趣的可以查一查这个类型private BigDecimal price;//出版社private String publish;//状态 0-⽆效 1-允许借阅 2-不允许借阅private Integer status;//statusCN是根据status来改变的,比如:status是0——》statusCN就是 “不可借阅”// status是1——》statusCN就是 ”可借阅“// status是2——》statusCN就是 “不可借阅”//本质上statusCN这个属性就是根据status的状态来改变对前端页面的显示(反过来想一想:你总不可能在前端直接显示0,1,2吧//或者如果你直接使用statusCN,那样传参会很麻烦,之后升级版会有更简单的方法(使用枚举))private String statusCN;//创建时间,这里的Date是util包里的(先用起来,下面会说)private Date createTime;//更新时间private Date updateTime;
}
- BigDecimal 的官方文档
其实说人话:BigDecimal就是精确的小数,可以和BigInteger类比一下,至于多精确,那还得看官方文档,这里就不深究了。 - 这是Date的官方文档
图书类都创建好了,接下来就是提供图书信息的功能了
package com.example.blogssystems_blogs.Controller;import com.example.blogssystems_blogs.model.BookInfo;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;@RequestMapping("/book")
@RestController
public class BookController {@RequestMapping("/getList")public List<BookInfo> getList(){List<BookInfo> books = mockBookData();//在这里就将StatusCN用上了,就是这样用的for (BookInfo book: books) {if(book.getStatus() == 1){book.setStatusCN("可借阅");}else{book.setStatusCN("不可借阅");}}return books;}//创建一个假的图书列表,由于我们还没有引进数据库,所以就先将就一下private List<BookInfo> mockBookData() {List<BookInfo> books = new ArrayList<>();for (int i = 0; i < 5; i++) {BookInfo book = new BookInfo();book.setId(i);book.setBookName("书籍" + i);book.setAuthor("作者" + i);book.setCount(i * 5 + 3);book.setPrice(new BigDecimal(new Random().nextInt(100)));book.setPublish("出版社" + i);book.setStatus(1);books.add(book);}return books;}
}
测试图书列表接口代码
我们还是使用Postman来发送请求。
可以看到没有任何问题
前端代码修改
前端登录
后端的代码确保正确了以后,就该修改前端代码了。由于我提供的前端代码只是个框架,所以还需要修改
我们先修改前端的登录页面:
前端只需要修改login函数里的代码就行了。
<script>function login() {$.ajax({type:"post",url:"user/login",data:{name:$("#userName").val(),password:$("#password").val()},//ret是后端的返回值,如果是true说明账号密码正确,跳转至图书列表页面success:function (ret){if(ret == true){location.href = "book_list.html"}else{alert("账号或密码错误")}}});}</script>
测试前端登录代码
前端图书展示
代码:
function getBookList() {$.ajax({type:"post",url:"book/getList",success:function (ret) {if(ret != null){var finalHtml = "";for (var book of ret) {finalHtml+="<tr>";finalHtml+="<td><input type=\"checkbox\" name=\"selectBook\" value=\"+book.id+\" id=\"selectBook\" class=\"book-select\"></td>";finalHtml+="<td>"+book.id+"</td>";finalHtml+="<td>"+book.bookName+"</td>";finalHtml+="<td>"+book.author+"</td>";finalHtml+="<td>"+book.count+"</td>";finalHtml+="<td>"+book.price+"</td>";finalHtml+="<td>"+book.publish+"</td>";finalHtml+="<td>"+book.statusCN+"</td>";finalHtml+="<td>";finalHtml+="<div class=\"op\">";finalHtml+="<a href=\"book_update.html?bookId=4\">修改</a>";finalHtml+="<a href=\"javascript:void(0)\" οnclick=\"deleteBook(4)\">删除</a>";finalHtml+="</div>";finalHtml+="</td>";finalHtml+="</tr>";}$("tbody").html(finalHtml);}}});
测试图书展示代码
可以看到图书的显示没有任何问题
- 注意:
简易版只实现上述两个功能,如有兴趣还请看下一期的升级版,升级版将会实现页面上的各个功能,以及解决统一事务的处理方式。
一个小瑕疵
由于我的大意,将图书管理系统BooksSystem的名字起成了博客系统BlogsSystem,在写的时候我竟然一点都没有察觉,写完了才发现名字起的不对,如果要改,截图就都要一起改了,成本有点大,再加上最近也在准备升级版,希望大家见谅,凑合着看,很抱歉,以后我一定会严于律己,不再马虎的。出错的只有名字,不耽误图书管理的功能的,大家可以放心看内容。