4、开发service层、前端页面流程

开发service层、前端页面流程


domain 实体类

还有一个放在domain的实体类Book

public class Book {

    private Integer id;
    private String name;
    private double price;
    private String author;


开发service层


Service 组件

如何开发Service组件:只要定义Service类,并使用@Service注解修饰它即可。
创建一个service接口及其实现类。
在这里插入图片描述


实现类代码

然后写上添加、查看 和 删除 方法。业务逻辑先弄假数据。


//添加这个@Service注解,springboot就可以自动扫描这个Service组件的实现类,然后把这个类部署成容器中的bean。
@Service
public class BookServiceImpl implements BookService {

    //添加书籍的方法
    @Override
    public Integer addBook(Book book) {
        return 1;
    }

    //查看所有书籍的方法
    @Override
    public List<Book> getAllBooks() {
        Book book = new Book();
        book.setId(1);
        book.setName("七龙珠");
        book.setAuthor("鸟山明");
        book.setPrice(200);
        List<Book> listBooks = new ArrayList<>();
        listBooks.add(book);
        return listBooks;
    }

    //删除书籍的方法
    @Override
    public void deleteBookById(Integer id) {
        System.err.println("删除书籍成功");
    }
}

controller 接口代码

然后 controller 这边再去调用 service 的方法。


具体代码
   /*
     *  将Service组件注入Controller
     *  方式一:(传统):使用@Autowired注解。
     *  方式二:(目前主流方式):定义有参数的构造器即可。
     */

    //方式二:定义有参数的构造器即可。这个就不需要使用@Autowired注解了。

    private BookService bookService;
    //这个就是springboot推荐的注入方式,就是利用有参数的构造器
    public BookController (BookService bookService){
        this.bookService = bookService;
    }

    //进入bookForm添加书籍页面的方法
    @GetMapping("/bookForm")
    public String bookForm(){

        //在Spring MVC中,当控制器方法返回一个字符串时,它通常被视图解析器解析为一个视图名,而不是一个普通的字符串
        //视图解析器会根据配置将这个视图名解析为相应的视图文件,然后进行渲染和返回给客户端

        //返回页面--会被视图解析器自动解析为名字为bookForm的视图。
        return "bookForm";
    }


    //添加书籍方法
    //映射地址
    @PostMapping("/addBook")
    public String addBook(Book book,Model model){

        Integer integer = bookService.addBook(book);

        if (integer>0){
            //添加成功,重定向到指定地址(listBooks页面)
            return "redirect:listBooks";
        }else {
            //添加失败,返回原本的添加页面。
            model.addAttribute("tip","书籍添加失败");
            return "bookForm";
        }

    }

    //查看所有的书籍
    @GetMapping("/listBooks")
    public String list(Model model){
        //查询所有图书数据
        List<Book> allBooks = bookService.getAllBooks();

        for (Book allBook : allBooks) {
            System.err.println(allBook);
        }

        //存入到books属性中
        model.addAttribute("books",allBooks);
        //返回视图页面
        return "listBooks";
    }

    //@PathVariable 映射 URL 绑定的占位符,通过 @PathVariable 可以将 URL 中占位符参数绑定到控制器处理方法的入参中:URL 中的 {xxx} 占位符可以通过
    //删除书籍
    @GetMapping("/deleteBook/{id}")
    public String deleteBook(@PathVariable  Integer id){

        bookService.deleteBookById(id);

        //重定向到指定地址,要加个/斜杠,表示跳转到根目录下的listBooks这里。
        //不加/斜杠的话,就会变成 listBooks 去替换 这个{id},导致路径出错
        return "redirect:/listBooks";

    }

注意点1:有参构造器介绍及使用

以前习惯用 @autowired 这种注解进行service组件注入。这次用定义的有参数的构造器来试一试

用有参数的构造器来进行注入的优点

1、避免空指针:使用函数构造注入时,如果依赖无法注入,那么在启动的时候就会报错,而不是运行时才报错。

2、可以添加final,保证依赖不可变。

如 private final BookService bookService;

一旦Controller通过构造函数注入依赖,那么这个依赖关系在Controller实例的生命周期内将不会发生变化。这可以提高代码的可靠性和稳定性。


注意点2:

在Spring MVC中,当控制器方法返回一个字符串时,它通常被视图解析器解析为一个视图名,而不是一个普通的字符串,视图解析器会根据配置将这个视图名解析为相应的视图文件,然后进行渲染和返回给客户端。


注意点3:

删除图书方法中,因为需要接收前端传来的id,等业务逻辑操作完后,重定向到 listBooks 视图,这个时候需要再 /listBooks 前加斜杠,表示重定向时跳转到根目录下的listBooks视图。
如果不在listBooks前面加斜杠,那么在访问删除方法的时候,return 的这个 listBooks 会替换这个参数路径上的 {id} ,导致访问路径出错。


前端页面


1、添加书籍的视图页面 bookForm.html

<!DOCTYPE html>
<!-- HTML引入Thymeleaf ,导入命名空间 , 把thymeleaf的域名加进来就可以使用了-->
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>添加图书页面</title>
    <!--  导入 webjar 包中的 bootstrap 样式库  -->
    <link ref="stylesheet" th:href="@{/webjars/bootstrap/4.6.0/css/bootstrap.css}">

</head>
<body>
<!--  class="container" :相当于类名,就是这个div模块的名字-->
<!--  class="alert alert-primary" : 警报框  -->
<div class="container">

    <div th:text="${tip}" class="alert alert-primary">书籍添加失败显示的提示信息</div>

    <h2>添加图书</h2>
    <!--  submit提交表单的时候,就会走这个addBook方法  -->
    <form method="post" th:action="@{/addBook}">
        <div class="form-group row">
            <label for="name" class="col-sm-3 col-form-label">图书名:</label>
            <div class="col-sm-9">
                <input type="text" id="name" name="name" class="form-control" placeholder="输入图书名">
            </div>
        </div>
        <div class="form-group row">
            <label for="author" class="col-sm-3 col-form-label">作者:</label>
            <div class="col-sm-9">
                <input type="text" id="author" name="author" class="form-control" placeholder="输入作者">
            </div>
        </div>
        <div class="form-group row">
            <label for="price" class="col-sm-3 col-form-label">价格:</label>
            <div class="col-sm-9">
                <input type="number" step="0.1" id="price" name="price" class="form-control" placeholder="输入价格">
            </div>
        </div>
        <div class="form-group row">
            <div class="col-sm-6 text-right">
                <button type="submit" class="btn btn-primary">添加</button>
            </div>
            <div class="col-sm-6">
                <button type="reset" class="btn btn-danger">重置</button>
            </div>
        </div>
    </form>


</div>
</body>
</html>


2、书籍列表视图页面 listBooks.html

<!DOCTYPE html>
<!-- HTML引入Thymeleaf ,导入命名空间 , 把thymeleaf的域名加进来就可以使用了-->
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>书籍列表页面</title>
    <!--  导入 webjar 包中的 bootstrap 样式库  -->
    <link ref="stylesheet" th:href="@{/webjars/bootstrap/4.6.0/css/bootstrap.css}">

</head>
<body>
<!--  class="container" :相当于类名,就是这个div模块的名字-->
<!--  class="alert alert-primary" : 警报框  -->
<div class="container">
    <table class="table table-hover">
        <tr>
            <th>书名</th>
            <th>价格</th>
            <th>作者</th>
            <th>删除</th>
        </tr>
        <!--  循环迭代  ${books}就是后端传来的集合数据, book就是循环后的变量  -->
        <tr th:each="book: ${books}">
            <td th:text="${book.name}">书名</td>
            <td th:text="${book.price}">价格</td>
            <td th:text="${book.author}">作者</td>
            <td><a th:href="@{/deleteBook/} + ${book.id}">删除</a> </td>
        </tr>
    </table>
</div>
</body>
</html>

测试

测试后,添加,查看、删除都能成功执行。

在这里插入图片描述


  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_L_J_H_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值