springboot图书馆管理系统后端

March 27, 2019 · 开发 · 292次阅读

后端部分

后端部分完全采用springboot的jpa方式进行数据库的操作,在接收请求方面采用的是restful风格

后端工程目录,如图:

工程目录

依次为

  1. 配置类(仅解决跨域)
  2. DAO类(数据库接口)
  3. 异常类(捕捉全局的异常)
  4. 实体类
  5. 服务类(封装操作数据库(DAO)的方法)
  6. 工具类(包含一个分页改进的分页功能和登录页面返回的结果信息类)
  7. 控制器类(实现页面跳转,和返回数据)

分类管理

TIM截图20190326102748.png

分类表格的实现流程如下:

listCategory.png
接下来依次叙述springboot一个实现分类目录列表的每一个类:

  1. 实体类Category:
    通过
        @Entity
        @Table(name = "category")
        @JsonIgnoreProperties({ "handler","hibernateLazyInitializer" })
        
        public class Category {
            @Id
            @GeneratedValue(strategy = GenerationType.IDENTITY) 
            @Column(name = "id")    
            int id;
            
            String name;
            
            public int getId() {
                return id;
            }
            public void setId(int id) {
                this.id = id;
            }
            
            public String getName() {
                return name;
            }
            public void setName(String name) {
                this.name = name;
            }
        }
  1. 数据库接口类
        public interface CategoryDAO extends JpaRepository<Category,Integer>{
        
        }
  1. 服务类
        @Service
        public class CategoryService {
            @Autowired CategoryDAO categoryDAO;
        
        
            public Page4Navigator<Book> list(int start, int size, int navigatePages) {
                Sort sort = new Sort(Sort.Direction.DESC, "id");
                Pageable pageable = new PageRequest(start, size,sort);
                Page pageFromJPA =categoryDAO.findAll(pageable);  //categoryDAO.findAll方法返回的结果就是一个page对象。当然是jpa中封装好的方法
        
                return new Page4Navigator<>(pageFromJPA,navigatePages);
        //        return pageFromJPA;
            }
            public List<Category> list() {
                Sort sort = new Sort(Sort.Direction.DESC, "id");
                return categoryDAO.findAll(sort);
            }
            public void add(Category bean){
                categoryDAO.save(bean);
            }
            public void delete(int id){
                categoryDAO.delete(id);
            }
            public Category get(int id){
                Category c = categoryDAO.findOne(id);
                return c;
            }
            public void update(Category c){
                categoryDAO.save(c);
            }
        }
  1. controller类
        @RestController
        public class CategoryController {
            @Autowired CategoryService categoryService;
        
            @GetMapping("/categories")
            public Page4Navigator<Book> list(@RequestParam(value = "start", defaultValue = "0") int start, @RequestParam(value = "size", defaultValue = "5") int size) throws Exception {
                start = start<0?0:start;
                Page4Navigator<Book> page =categoryService.list(start, size, 5);  //5表示导航分页最多有5个,像 [1,2,3,4,5] 这样
                return page;
            }
            @PostMapping("/categories")
            public Object add(@RequestBody Category bean){
                categoryService.add(bean);
                return bean;
            }
        
            @DeleteMapping("/categories/{id}")
            public String delete(@PathVariable("id") int id,HttpServletRequest request){
                categoryService.delete(id);
                File imageFile = new File(request.getServletContext().getRealPath("/img/category"));
                File file = new File(imageFile,id+".jpg");
                file.delete();
                return null;
            }
            @GetMapping("/categories/{id}")
            public Category get(@PathVariable("id") int id) throws Exception{
                Category bean = categoryService.get(id);
                return bean;
            }
            @PutMapping("/categories")
            public Object update(@RequestBody Category bean){
                categoryService.update(bean);
                return bean;
            }
        }
        

分类名称修改流程:

  1. 点击修改图标,超链地址为(:href为vue超链写法,可以在链接中加vue对象属性):

        <a :href="'admin_book_list?cid=' + bean.id ">
  2. admin_book_list在adminPagecontroller中跳转到editCategory.html页面
        @GetMapping(value = "/admin_category_edit")
        public String editCategory(){
            return "admin/editCategory";
        }
  1. editCategory自动执行脚本中的get方法,获得超链问号之后的参数值bean.id即当前修改项的id值,并请求服务器返回当前id值的分类项的名称,放到编辑框中。
  2. 修改之后,点击提交按钮,执行update函数,提交请求和修改后的bean给服务器,服务器成功返回信息后,跳转页面至分类页面。
        <tr class="submitTR">
            <td colspan="2" align="center">
                <input type="hidden" name="id"   v-model.trim="bean.id" >
                <a href="#nowhere" class="btn btn-success" @click="update">提 交</a>
            </td>
        </tr>
        
        $(function () {     //$(function(){...})jquery中表示文档一载入完毕就执行
            var data4Vue={
                uri:'categories',
                listURL:'admin_category_list',
                bean:{id:0,name:''},
            };
            var vue = new Vue({
                el:'#workingArea',
                data:data4Vue,
                mounted:function(){
                    this.get();             //mounted内自动执行
                },
                methods:{    //methods注意s,不是method
                    get:function (){             //get方法请求服务器返回该分类对象
                        var id = getUrlParms("id");
                        var url = this.uri+"/"+id;
                        axios.get(url).then(function (response) {
                            vue.bean = response.data;
                        })
                    },
                    update:function () {
                        var id = getUrlParms("id");
                        var url = this.uri;
                        axios.put(url,vue.bean).then(function (response) {
                            location.href = vue.listURL;
                        });
                    }
                }
            });
        });

新增分类项

新增分类比较简单,比修改简单,直接绑定的按钮执行add函数将请求的地址与bean一起传给服务器,服务器执行成功返回信息时更新列表。但因为整体用的是==restful风格==,因此axios请求插件在修改里用的是==put==方法,增加用的是==post==方法,对应于后端程序中的==PutMapping==和==PostMapping==,这样可以请求一致的url,但后台可以执行不同的方法

TIM截图20190327203922.png

删除分类项

跟增加基本无异,但在vue中delete是关键字,在命名delete方法时改成deletebean,并且restful规范删除成功后服务器端要返回null,所以前端进行判断返回的数据是否为null,如果不为空,则打印处数据。

                deleteBean:function (id) {
                  if(!checkDeleteLink())
                      return;
                  var url = this.uri+"/"+id;
                  axios.delete(url).then(function (response) {
                      if (0!=response.data.length) //rest规范删除数据要求要会返回空字符串(控制器类中delete返回null),所以进行判断
                          alert(response.data);
                      else
                          vue.list(0); //是空字符串则调第一页
                  })
                }

分类下的书籍查询:

  1. 由于书籍和分类时多对一的关系,因此在书籍实体类中要用注解标明,如下在category属性上注解@ManyToOne和JoinColumn(name="cid")表示外键cid与category关联:
            @Entity
        public class Book {
            @Id
            @Column(name = "id")
            @GeneratedValue(strategy = GenerationType.IDENTITY)
            private int id;
            private String name;
            @ManyToOne
            @JoinColumn(name = "cid")
            private Category category;
        
            public String getName() {
                return name;
            }
        
            public void setName(String name) {
                this.name = name;
            }
        
            public Category getCategory() {
                return category;
            }
        
            public void setCategory(Category category) {
                this.category = category;
            }
        
            public int getId() {
                return id;
            }
        
            public void setId(int id) {
                this.id = id;
            }
        }
  1. 在DAO接口中写一个通过分类查询的方法,这方法命名规则是定死的,按照命名规则写,在==@AutoWired==生成的DAO对象中自动就有这个方法的具体实现。
        public interface BookDAO extends JpaRepository<Book,Integer> {
            Page<Book> findByCategory(Category category, Pageable pageable);
            //List<Book> findByNameLike(String keyword,Pageable pageable); //这个是后面用到的搜索
        }
  1. 在service中,bookService.java中,除了增删改查的service方法还要加入一个通过分类名查询的方法。
        public Page4Navigator<Book> list(int cid,int start,int size,int navigatePages ){
            Category category = categoryService.get(cid); //获取分类对象
            Sort sort = new Sort(Sort.Direction.DESC,"id"); //设置排序方式的对象
            Pageable pageable = new PageRequest(start,size,sort); //设置分页的对象
            Page<Book> pageFromJPA = bookDAO.findByCategory(category,pageable); //DAO中通过分类查询到的结果
            return new Page4Navigator<>(pageFromJPA,navigatePages);//返回查询的包含分页信息的书籍项
        }
  1. 最后在bookController中接收页面发来的请求信息,来返回分类查询结果
        @GetMapping("/categories/{cid}/books")
        public Page4Navigator<Book> list(@PathVariable("cid") int cid, @RequestParam(value = "start",defaultValue = "0")int start,
                                         @RequestParam(value = "size",defaultValue = "5")int size){
            start = start<0?0:start;
            Page4Navigator<Book> page = bookService.list(cid,start,size,5);
            return page;
        }

搜索书籍功能

搜索书籍功能放在前端的所有书籍页面里面。

  1. 在vue的data属性里定义号关键字keyword:"",并与搜索输入框绑定。
        <input type="text" class="form-control input-lg col-xs-4" v-model="keyword">
  1. 编写搜索请求函数listSearch,与按钮绑定:
        <span @click="listSearch" class="input-group-addon btn btn-primary">

                listSearch:function () {
                    var url = "search?keyword="+vue.keyword;
                    axios.post(url).then(function (response) {
                        vue.beans = response.data;
                    })
                },
  1. 在bookDAO中添加方法。名字定义方式findByNameLike,传入的参数为关键字,和分页信息
        public interface BookDAO extends JpaRepository<Book,Integer> {
            //Page<Book> findByCategory(Category category, Pageable pageable);
            List<Book> findByNameLike(String keyword,Pageable pageable);
        }
  1. 在service中封装该方法
        public List<Book> search(String name, int start, int size){
            Sort sort = new Sort(Sort.Direction.DESC,"id");
            Pageable page = new PageRequest(start,size,sort);
            List<Book> books = bookDAO.findByNameLike("%"+name+"%",page);//"%"+name+"%"表模糊查询
            return books;
        }
  1. 在searchController中接收关键字请求信息,返回搜索结果。

    • [ ] searchController可以与bookController合并
            @Autowired
            BookService bookService;
            @PostMapping("/search")
            public Object search(@RequestParam(value = "keyword") String keyWord){
                return bookService.search(keyWord,0,20);
            }

登录功能

登录功能与前面的分类增加功能类似,前端将表单中的信息use.namer和user.password封装一个json数据user,发送给后端,后端通过注解@Requestbody自动将值赋给usr对象,userDAO将这个对象拿进数据库查询看是否在数据库中。判断后返回result对象,判断里面返回的信息是否是查询成功,成功则跳转到分类页面 ,查询结果为null的话则返回失败信息。

        //userDAO添加通过用户名和密码查询的方式
        public interface UserDAO extends JpaRepository<User,Integer> {
            User getByNameAndPassWord(String name,String password);
        }
---
        //登录页面的login函数请求服务器
                login:function () {
                    axios.post(vue.uri,this.user).then(function (response) {
                      vue.result =  response.data
                        if (vue.result.code ==1){
                            location.href="admin_category_list"
                        }
                        else{
                            alert(vue.result.message)
                        }
                    })
                }

        //在searchController中将传过来的user的name和password进行查询
        @RestController
        public class LoginController {
            @Autowired
            UserService userService;
            @PostMapping("/login")
            public Object login(@RequestBody User userParam, HttpSession httpSession){
                User user = userService.get(userParam.getName(),userParam.getPassWord());
                if (user==null){
                    return Result.fail();
                } else {
                    httpSession.setAttribute("user",userParam);
                    return Result.success();
                }
            }
        }

标签:none

最后编辑于:2020/06/18 10:21

添加新评论

控制面板