java springboot新闻管理项目 实现添加搜索新闻功能

项目功能实现以上一篇博客为基础。
新闻管理页面如下
在这里插入图片描述

在controller层建立一个NewsController对象,用来处理与新闻有关的请求。显示新闻列表这一部分,和上一篇博客,显示type列表、tag列表类似不再进行介绍。先从新增和修改新闻部分开始,当页面发出一个id等于-1的请求时,表明正在新增新闻,需要产生要给news对象。
在这里插入图片描述id不为-1的请求,表明正在修改新闻。
在这里插入图片描述此时需要通过news的id调用service的方法,获取到一个news对象。在获取到news对象时,由于news对象中有以list形式存贮tag的id,无法直接用到前端页面,所以需要,将list形式tag的id转化为String类型,存储在news对象的tagIds的属性中,传给页面用来告诉用户已有的标签。同时也要将所有的types和tags传给页面进行添加或修改新的type和tag。

    @RequestMapping("/input/{id}")
    public String toInput(@PathVariable Long id, Model model) {
        if (id == -1) {
            model.addAttribute("news", new News());
        }else{
            News news = newsService.findNewsById(id);
            String tagIds = tagService.getTagIds(news.getTags());
            news.setTagIds(tagIds);
            model.addAttribute("news",news);
        }
        List<Type> types= typeService.listType();
        model.addAttribute("types",types);
        List<Tag> tags = tagService.listTag();
        model.addAttribute("tags",tags);

        return "admin/news-input";
    }

接着是将数据存入数据库,由于从新闻编辑页面传来的news对象,是没有user属性的,所以需要通过session获取到当前用户,并将用户的信息存入到news对象中,而news对象中的tag信息也是以String类型存储在tagIds中,需要将其取出并转化为list类型的tags,tag信息总要经过String和list类型的转化,是因为页面需要的是String类型,存储到数据库是又是调用JpaRepository接口下的方法用的是list类型的数据,两者没做到统一,所以就要进行一个转化了,最后通过调用service层的方法存入到数据库中,并返回news的界面。

    @RequestMapping("/input")
    public String input(News news, HttpSession session){
        User user = (User) session.getAttribute("user");
        news.setUser(user);
        List<Tag> tags = tagService.findTagByTagId(news.getTagIds());
        news.setTags(tags);
        newsService.input(news);
        return "redirect:/admin/news";
    }

可以看到界面还有一个搜索框,因而需要根据页面的查询条件进行sql查询,查询条件通过newQuery对传入,通过newQuery查询条件和pageable页面信息,来获取在查询条件下的page,并将得到的page添加到model中,来传给前端页面,应为不需要修改其他部分,所以只需要加载newList(即表格信息)。

    @RequestMapping("search")
    public String search(@PageableDefault(size = 5, sort = {"updateTime"}, direction = Sort.Direction.DESC) Pageable pageable,
                         NewQuery newQuery,
                         Model model){
        Page<News> page = newsService.searchNews(pageable,newQuery);
        model.addAttribute("page",page);
        return "admin/news :: newsList";
    }
}

接着是服务层接口对象方法的实现,首先新增或修改新闻,当news的id为空时,也就是新增的新闻,这时,需要设置新闻产生的时间,然后调用newDao接口保存新闻信息到数据库中。如果news的id不为空,也就是更新新闻的信息,这时需要设置新闻修改的时间,同时页面传来的news对象中的数据不包含一些未被修改的数据(如创建的时间)这时需要对缺失的数据进行补全,再存入数据库防止数据丢失。

@Override
    public void input(News news) {
        if(news.getId()==null){
            news.setCreateTime(new Date());
            newsDao.save(news);
        }else{
            news.setUpdateTime(new Date());
            News n = newsDao.getOne(news.getId());
            BeanUtils.copyProperties(news,n, MyBeanUtils.getNullPropertyNames(news));
            newsDao.save(n);
        }
    }

通过id获取新闻对象,这个比较简单直接调用newDao接口下的方法就行了。

    @Override
    public News findNewsById(Long id) {
        return newsDao.getOne(id);
    }

接着是进行较为复杂的搜索查询,JpaRepository接口只能实现一些简单的sql查询,如果要进行多重条件的sql查询,则还需要继承JpaSpecificationExecutor接口。

public interface NewsDao extends JpaRepository <News,Long> , JpaSpecificationExecutor<News> {
}

继承接口后newsDao层findAll又有了新的实现方法。通过Specification接口和pageable对象实现多个条件的sql查询,而Specification接口下需要重写Predicate接口,并需要通过Root,CriteriaQuery,CriteriaBuilder 进行实例化,Root可用查询的表实例化,CriteriaQuery查询的字段, CriteriaBuilder 构造字段之间的关系。

    @Override
    public Page<News> searchNews(Pageable pageable, NewQuery newQuery) {
        Page<News> news = newsDao.findAll(new Specification<News>() {
            @Override
            public Predicate toPredicate(Root<News> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                List<Predicate> predicates = new ArrayList<>();
                if(!StringUtils.isEmpty(newQuery.getTitle())){
                    predicates.add(criteriaBuilder.like(root.<String>get("title"),"%"+newQuery.getTitle()+"%"));
                }
                if(!StringUtils.isEmpty(newQuery.getTypeId())){
                    predicates.add(criteriaBuilder.equal(root.<Type>get("type").get("id"),newQuery.getTypeId()));
                }
                if(!StringUtils.isEmpty(newQuery.getRecommend())){
                    predicates.add(criteriaBuilder.equal(root.<Boolean>get("recommend"),newQuery.getRecommend()));
                }
                criteriaQuery.where(predicates.toArray(new Predicate[predicates.size()]));
                return null;
            }
        },pageable);
        return news;
    }

前端页面传递查询条件代码如下
在这里插入图片描述
代码已上传GitHub

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值