SpringBoot+JPA完成博客分类相关功能

简单完成分类添加、删除、更新、分页展示功能

Entity层

@Entity
public class Type {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    @NotBlank(message = "分类名称不能为空")
    private String name;
    @OneToMany(mappedBy = "type")
    private List<Blog> blogs=new ArrayList<>();

    public Type() {
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public List<Blog> getBlogs() {
        return blogs;
    }

    public void setBlogs(List<Blog> blogs) {
        this.blogs = blogs;
    }
}

Dao层

public interface TypeRepository extends JpaRepository<Type, Long> {
    Page<Type> findAll(Pageable pageable);
    Type getById(Long id);
    Type findByName(String name);
}

Service层

@Service
public interface TypeService {
    Type save(Type type);
    Type getType(Long id);
    Page<Type> listType(Pageable pageable);
    Type updateType(Long id,Type type);
    void deleteType(Long id);
    Type getTypeByName(String name);
    List<Type> listType();
}
@Service
public class TypeServiceImpl implements TypeService {

@Autowired
TypeRepository typeRepository;
    @Transactional
    @Override
    public Type save(Type type) {
        return typeRepository.save(type);
    }
    @Transactional
    @Override
    public Type getType(Long id) {
        return typeRepository.getById(id);
    }
    @Transactional
    @Override
    public Page<Type> listType(Pageable pageable) {
        return typeRepository.findAll(pageable);
    }
   @Transactional
    @Override
    public Type updateType(Long id, Type type) {
        Type t=typeRepository.getById(id);
        if(t==null){
            throw new NotFoundException("不存在该类型!");
        }
        BeanUtils.copyProperties(type,t);
       return typeRepository.save(t);
    }
    @Transactional
    @Override
    public void deleteType(Long id) {
     typeRepository.deleteById(id);
    }

    @Override
    public Type getTypeByName(String name) {
        return typeRepository.findByName(name);
    }

    @Override
    public List<Type> listType() {
        return typeRepository.findAll();
    }
}

Controller层

@Controller
@RequestMapping("/admin")
public class TypeController {
    @Autowired
    private TypeService typeService;
    @GetMapping("/types")
    public String types(@PageableDefault(size=4,sort = {"id"},direction= Sort.Direction.DESC)
                                    Pageable pageable, Model model){
        model.addAttribute("page", typeService.listType(pageable));
        return "types/typesManage";
    }
    @GetMapping("/types/input")
    public String input(Model model){
        model.addAttribute("type",new Type());
        return "types/typesInput";
    }
    @GetMapping("types/{id}/input")
    //加注解来保证形参的id和上述的id是一致的,完成参数映射
    public String editInput(@PathVariable Long id, Model model){
        model.addAttribute("type",typeService.getType(id));
        return "types/typesInput";
    }
    @PostMapping("/types")
    public String post(@Valid Type type, BindingResult result, RedirectAttributes attributes){
        Type type1=typeService.getTypeByName(type.getName());
        if(type1!=null){
            //验证的是name,和type里面的属性一致。验证的结果nameError
            result.rejectValue("name","nameError","不能添加重复的分类!");
        }
        if(result.hasErrors()){
            return "types/typesInput";
        }
        Type t=typeService.save(type);
        if(t==null){
            attributes.addFlashAttribute("message","新增失败!");
        }else{
            attributes.addFlashAttribute("message","新增成功!");
        }
        return "redirect:/admin/types";
    }

    @PostMapping("/types/{id}")
    //根据id来修改type
    public String editPost(@Valid Type type, BindingResult result,@PathVariable Long id,RedirectAttributes attributes){
        Type type1=typeService.getTypeByName(type.getName());
        if(type1!=null){
            //验证的是name,和type里面的属性一致。验证的结果nameError
            result.rejectValue("name","nameError","不能添加重复的分类!");
        }
        if(result.hasErrors()){
            return "types/typesInput";
        }
        Type t=typeService.updateType(id,type);
        if(t==null){
            attributes.addFlashAttribute("message","更新失败!");
        }else{
            attributes.addFlashAttribute("message","更新成功!");
        }
        return "redirect:/admin/types";
    }
    @GetMapping("types/{id}/delete")
    public String delete(@PathVariable Long id,RedirectAttributes attributes){
        typeService.deleteType(id);
        attributes.addFlashAttribute("message","删除成功");
        return "redirect:/admin/types";
    }


}

前端展示页面
分类输入表单:

<div class="m-container-small m-padding-tb-big">
<!--    查询表单-->
    <div class="ui container">
        <form method="post"    th:object="${type}" th:action="*{id}==null ? @{/admin/types} : @{/admin/types/{id}(id=*{id})} " class="ui form">
            <input type="hidden" name="id" th:value="*{id}">
            <div class="required field">
                <div class="ui left labeled input">
                    <label  class="ui teal basic label">名称</label>
<!--                    将拿到的name值赋值给我们的name输入域-->
                    <input type="text" name="name" placeholder="分类名称" th:value="*{name}">
                </div>

            </div>
            <div class="ui right aligned container">
                <button type="button" class="ui basic button" onclick="window.history.go(-1)">返回</button>

                <button class="ui teal basic submit button">提交</button>
            </div>
        </form>

分类管理、展示页面:

<table class="ui celled table">
            <thead>
            <tr>
                <th></th>
                <th>名称</th>
                <th>操作</th>
            </tr>
            </thead>
            <tbody>
<!--            以循环的方式-->
            <tr th:each="type,iterStat:${page.content}" >
                <td th:text="${iterStat.count}">1</td>
                <td th:text="${type.name}">刻意练习清单</td>

                <td>
                    <a href="#" th:href="@{/admin/types/{id}/input(id=${type.id})}"  class="ui mini teal basic button">编辑</a>
                    <a href="#" th:href="@{/admin/types/{id}/delete(id=${type.id})}"class="ui mini red basic button">删除</a>
                </td>
            </tr>
            </tbody>
            <tfoot>
            <tr >
                <th colspan="6" >
                    <div class="ui mini pagination menu" th:if="${page.totalPages}>1">

                        <a class="item"  th:href="@{/admin/types(page=${page.number}-1)}" th:unless="${page.first}">上一页</a>
                        <a class="item" th:href="@{/admin/types(page=${page.number}+1)}" th:unless="${page.last}">下一页</a>
                    </div>

                    <a href="#" th:href="@{/admin/types/input}" class="ui mini right floated teal basic button">新增</a>
                </th>
            </tr>
            </tfoot>
        </table>
上一篇:Spring Boot 入门系列(二十七)使用Spring Data JPA 自定义查询如此简单,完全不需要写SQL!


下一篇:解决JPA对查询对象set属性值导致数据更新的问题