Java:71-项目的广告管理模块和用户管理模块

项目的广告管理模块和用户管理模块

在上一个博客中(70章博客),我们完成了课程管理模块,接下来我们完成广告管理模块和用户管理模块
广告管理模块:
实现以下功能:
广告位列表查询
添加广告位
回显广告位名称
修改广告位
广告分页查询
图片上传
新建广告
回显广告信息
修改广告
广告状态上下线

在这里插入图片描述

对应数据库表,在70章博客里有了
表关系介绍:
ER图:

在这里插入图片描述

对应字段信息在表里面可以看到
广告管理模块的实现:
广告位列表查询:
需求分析
需求:点击广告列表按钮进行广告列表展示
Dao层:PromotionSpaceMapper :
package com.lagou.dao;

import com.lagou.domain.PromotionSpace;

import java.util.List;

/**
 *
 */
public interface PromotionSpaceMapper {

    /*
    获取所有广告位
     */
    public List<PromotionSpace> findAllPromotionSpace();
}

对应映射配置文件(PromotionSpaceMapper .xml):
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">


<mapper namespace="com.lagou.dao.PromotionSpaceMapper">

    <!--查询所有广告位-->
    <select id="findAllPromotionSpace" resultType="PromotionSpace">
        select *
        from promotion_space
    </select>
</mapper>
Service层:PromotionSpaceService及其实现类 :
package com.lagou.service;

import com.lagou.domain.PromotionSpace;

import java.util.List;

/**
 *
 */
public interface PromotionSpaceService {

    /*
    获取所有广告位
     */
    public List<PromotionSpace> findAllPromotionSpace();
}

package com.lagou.service.impl;

import com.lagou.dao.PromotionSpaceMapper;
import com.lagou.domain.PromotionSpace;
import com.lagou.service.PromotionSpaceService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 *
 */
@Service
public class PromotionSpaceServiceImpl implements PromotionSpaceService {

    @Autowired
    private PromotionSpaceMapper promotionSpaceMapper;

    /*
   获取所有广告位
    */
    @Override
    public List<PromotionSpace> findAllPromotionSpace() {
        List<PromotionSpace> allPromotionSpace = promotionSpaceMapper.findAllPromotionSpace();

        return allPromotionSpace;
    }
}

Web层:PromotionSpaceController :
package com.lagou.controller;

import com.lagou.domain.PromotionSpace;
import com.lagou.domain.ResponseResult;
import com.lagou.service.PromotionSpaceService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

/**
 *
 */
@RestController
@RequestMapping("/PromotionSpace")
public class PromotionSpaceController {

    @Autowired
    private PromotionSpaceService promotionSpaceService;

    /*
  获取所有广告位
   */
    @RequestMapping("/findAllPromotionSpace")
    public ResponseResult findAllPromotionSpace(){
        List<PromotionSpace> allPromotionSpace = promotionSpaceService.findAllPromotionSpace();

        ResponseResult responseResult = new ResponseResult(true, 200, "查询所有广告位成功", 
                                                           allPromotionSpace);
        return responseResult;
    }

}

使用Postman测试接口
添加广告位
需求分析
添加:点击广告列表按钮进行广告列表展示

在这里插入图片描述

Dao层:添加部分PromotionSpaceMapper :
/*
    添加广告位
     */
    public void savePromotionSpace(PromotionSpace promotionSpace);
添加部分PromotionSpaceMapper .xml:
  <!--添加广告位-->
    <insert id="savePromotionSpace" parameterType="PromotionSpace">
        insert into promotion_space values(null, #{name}, #{spaceKey}, 
        #{createTime}, #{updateTime}, #{isDel})

<!--
这里说明一下:对应替换,是使用get方法,若没有get方法则直接赋值
且其他get后面名称首字母大小写忽略,直接赋值的必须一致

在这里,若没有某某get方法或者set方法也可以说成是没有匹配的对应get方法和对应set方法

而当所以的操作都没找到时,那么就会报错了,如这里的,没有对应get方法和对应直接赋值的变量,则会报错
-->
    </insert>
Service层:添加部分PromotionSpaceService及其实现类 :
    /*
    添加广告位
     */
    public void savePromotionSpace(PromotionSpace promotionSpace);
/*
    添加广告位
     */
    @Override
    public void savePromotionSpace(PromotionSpace promotionSpace) {
        promotionSpace.setSpaceKey(UUID.randomUUID().toString());
        //UUID是java自带的一个类
        Date date = new Date();
        promotionSpace.setCreateTime(date);
        promotionSpace.setUpdateTime(date);
        promotionSpace.setIsDel(0);

        promotionSpaceMapper.savePromotionSpace(promotionSpace);
    }
Web层:添加部分PromotionSpaceController :
/*
    添加广告位
    后面会进行修改的扩展
     */
    @RequestMapping("/saveOrUpdatePromotionSpace")
    public ResponseResult saveOrUpdatePromotionSpace(@RequestBody PromotionSpace promotionSpace){
        promotionSpaceService.savePromotionSpace(promotionSpace);
        ResponseResult responseResult = new ResponseResult(true, 200, "添加广告位成功",null);
        return responseResult;
    }
使用Postman测试接口
在进行修改前我们需要进行回显
回显广告位名称
需求分析
需求:点击编辑按钮,进行广告位信息回显

在这里插入图片描述

Dao层:添加部分PromotionSpaceMapper :
/*
    根据id查询广告位信息
     */
    public PromotionSpace findPromotionSpaceById(Integer id);
添加部分PromotionSpaceMapper .xml:
 <!--根据id查询广告位信息-->
    <select id="findPromotionSpaceById" parameterType="int" resultType="PromotionSpace">
        select id,name
        from promotion_space where id = #{id}
    </select>
Service层:添加部分PromotionSpaceService及其实现类 :
  /*
  根据id查询广告位信息
   */
    public PromotionSpace findPromotionSpaceById(Integer id);
   /*
根据id查询广告位信息
*/
    @Override
    public PromotionSpace findPromotionSpaceById(Integer id) {
        PromotionSpace promotionSpaceById = promotionSpaceMapper.findPromotionSpaceById(id);

        return promotionSpaceById;
    }
Web层:添加部分PromotionSpaceController :
 /*
    根据id查询广告位信息
     */
    @RequestMapping("/findPromotionSpaceById")
    public ResponseResult findPromotionSpaceById(Integer id) {
        //实际上得到的是对应int(判断Integer,然后就是String变成int,然后自动装箱)
        PromotionSpace promotionSpace = promotionSpaceService.findPromotionSpaceById(id);

        ResponseResult responseResult = new ResponseResult(true, 200, "查询具体广告位成功", 
                                                           promotionSpace);
        return responseResult;

    }
使用Postman测试接口
在回显后我们进行修改操作:
修改:页面回显基础上,点击提交按钮 真正进行数据修改

在这里插入图片描述

Dao层:添加部分PromotionSpaceMapper :
 /*
   修改广告位
    */
    public void updatePromotionSpace(PromotionSpace promotionSpace);
添加部分PromotionSpaceMapper .xml:
 <!--修改广告位-->
    <update id="updatePromotionSpace" parameterType="PromotionSpace">
            update promotion_space set name = #{name},updateTime = #{updateTime} where id = #{id}
    </update>
Service层:添加部分PromotionSpaceService及其实现类 :
/*
  修改广告位
   */
    public void updatePromotionSpace(PromotionSpace promotionSpace);
   /*
    修改广告位
     */
    @Override
    public void updatePromotionSpace(PromotionSpace promotionSpace) {

        promotionSpace.setUpdateTime(new Date());
        promotionSpaceMapper.updatePromotionSpace(promotionSpace);
    }
Web层:修改部分PromotionSpaceController (扩展saveOrUpdatePromotionSpace方法):
 @RequestMapping("/saveOrUpdatePromotionSpace")
    public ResponseResult saveOrUpdatePromotionSpace(@RequestBody PromotionSpace promotionSpace){

        ResponseResult responseResult;
        if(promotionSpace.getId() == null) {
            promotionSpaceService.savePromotionSpace(promotionSpace);
            responseResult = new ResponseResult(true, 200, "添加广告位成功", null);
        }else{
            promotionSpaceService.updatePromotionSpace(promotionSpace);
            responseResult = new ResponseResult(true, 200, "修改广告位成功", null);
        }
        return responseResult;
    }
使用Postman测试接口
广告分页查询
需求分析
需求:点击广告列表,对广告信息进行分页列表展示

在这里插入图片描述

在这之前,我们需要对应类(PromotionAd)进行改造一下:
添加对应变量及其get和set方法
//声明一方关系:PromotionSpace
    private PromotionSpace promotionSpace;

    public PromotionSpace getPromotionSpace() {
        return promotionSpace;
    }

    public void setPromotionSpace(PromotionSpace promotionSpace) {
        this.promotionSpace = promotionSpace;
    }
使得出现对应关系(虽然表没有对应外键,但并不会影响操纵,只是在自己操作或者特殊情况下可能会出现多余数据)
一般前端传递数据若是没有出错的话,一般都会直接对应,而不会出现多余数据,但是没有外键联系的话对应相应查询可能会慢
若表有外键联系的话,开发效率低一点,因为不好试错(如手动添加),最主要的是改变时不好进行改变(特别是业务改变时)
那么就出现了表的维护性和效率,一般我们不会通过外键去查询,而是通过主键去查询(这个一般都会设置,因为他只联系本身)
也就是说这个效率可以不做很大要求
那么由于维护性,当我们确定以后可能要修改的话,最好不要使用外键联系
当确定知道不会进行修改时,可以尽量进行外键联系,当然也可不使用(防止突然要修改,因为业务基本都会有)
综上所述:一般我们都不会使用外键,在维护性面前
多余的数据消除显的有点多余(因为可以通过程序来实现,只要程序不会出错)
Dao层:PromotionAdMapper:
package com.lagou.dao;

import com.lagou.domain.PromotionAd;

import java.util.List;

/**
 *
 */
public interface PromotionAdMapper {

    /*
    分页查询广告信息
     */
    public List<PromotionAd> findAllPromotionAdByPage();
}

对应映射配置文件(PromotionAdMapper.xml):
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.lagou.dao.PromotionAdMapper">

    
    <resultMap id="ad_space" type="PromotionAd">

        <id property="id" column="id"></id>
        <result property="name" column="name"></result>
        <result property="spaceId" column="spaceId"></result>
        <result property="keyword" column="keyword"></result>
        <result property="htmlContent" column="htmlContent"></result>
        <result property="text" column="text"></result>
        <result property="link" column="link"></result>
        <result property="startTime" column="startTime"></result>
        <result property="endTime" column="endTime"></result>
        <result property="createTime" column="createTime"></result>
        <result property="updateTime" column="updateTime"></result>
        <result property="status" column="status"></result>
        <result property="priority" column="priority"></result>
        <result property="img" column="img"></result>

        <association property="promotionSpace" javaType="PromotionSpace" 
                     select="com.lagou.dao.PromotionSpaceMapper.findPromotionSpaceById" 
                     column="spaceId">
             </association>
    <!--我们查询的数据,若使用指定,那么当操作类里面的对象时,就需要标签来指定了,而这里则使用默认指定-->
    </resultMap>

    <!--分页查询广告信息-->
    <!--注意:可能类里面有设置了关系的变量,但表未必一定会设置,如外键和主键(一般都会设置主键)-->
    
    <select id="findAllPromotionAdByPage" resultMap="ad_space">
            select * from promotion_ad
    </select>
    <!--
    注意:配置文件最好放在资源文件夹里,虽然最终的结果是放在项目下,但识别时,只会在资源文件夹里识别
    也就是说,虽然src与resources在路径的最终存放一样,但是将对应配置文件放在src里面
    maven不会去src识别,而是去resources识别,所有配置文件最好是在resources文件夹里面
    这是使用maven需要注意的地方,其他的不要maven的,一般不会这样
    因为他们是直接编写到最终路径的,而没有识别操作
    -->
</mapper>
要使用Mybatis的分页操作,我们通常都要配置插件,但在Mybatis中的那个配置文件已经被Spring整合了
所有我们需要在对应整合的地方进行配置,如下:
添加部分applicationContext-dao.xml(扩展applicationContext-dao.xml):
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <property name="typeAliasesPackage" value="com.lagou.domain"></property>
        <property name="plugins">  <!--配置插件-->
            <array>
                <bean class="com.github.pagehelper.PageHelper">
                    <property name="properties">
                        <value>helperDialect=mysql</value>
                    </property>
                </bean>
            </array>
            <!--
这些操作就相当于Mybatis里的
 <plugins>
        <plugin interceptor="com.github.pagehelper.PageHelper">
            <property name="dialect" value="mysql"/>
           dialect指定方言,因为不同数据库的对应分页操作不同,如mysql是limit
        </plugin>
    </plugins>
因为插件有很多,所以是array标签(设置的)
-->
        </property>
        <property name="configLocation" value="classpath:sqlMapConfig.xml"></property>
    </bean>
现在我们可以编写Service层了,但是前端一般会传递两个参数过来,我们可以使用两个参数来接收,也可以使用一个类来接收
这里我们使用类来接收,防止以后出现多个参数的传递(使用类,基本只需要修改Service层就可以了)
编写PromotionAdVo类
这个类不是用来存放两个表字段信息的,而是用来存放特定需要的参数的
实际上都是一样的作用
根据参数来说,前者存放两表信息,后者存放对应需要的参数,但都是变量的存放
也都实现了好维护性的操作,且没有多余变量,即少代码的同样操作
根据表来说,前者是为了实现表的参数合并,后者只是单纯的存放需要的参数
而我们使用实体类的参数时,一般直接使用实体类当参数,因为有对应类存在了(实体类存在了)
当然,若不嫌麻烦,也可以创建对应类来存放对应参数
但不管根据哪一种,都是为了解决需求以及方便维护的操作,当有更好的时,那么肯定是使用更好的:
package com.lagou.domain;

/**
 *
 */
public class PromotionAdVo {

    //当前页
    private Integer CurrentPage;

    //每页显示的条数
    private Integer PageSize;

    public Integer getCurrentPage() {
        return CurrentPage;
    }

    public void setCurrentPage(Integer currentPage) {
        CurrentPage = currentPage;
    }

    public Integer getPageSize() {
        return PageSize;
    }

    public void setPageSize(Integer pageSize) {
        PageSize = pageSize;
    }
}

接下来我们编写Service层
Service层:PromotionAdService及其实现类 :
package com.lagou.service;

import com.github.pagehelper.PageInfo;
import com.lagou.domain.PromotionAd;
import com.lagou.domain.PromotionAdVo;

import java.util.List;

/**
 *
 */
public interface PromotionAdService {

    /*
 分页查询广告信息
  */
    public PageInfo<PromotionAd> findAllPromotionAdByPage(PromotionAdVo promotionAdVo);
}

package com.lagou.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.lagou.dao.PromotionAdMapper;
import com.lagou.domain.PromotionAd;
import com.lagou.domain.PromotionAdVo;
import com.lagou.service.PromotionAdService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 *
 */
@Service
public class PromotionAdServiceImpl implements PromotionAdService {

    @Autowired
    private PromotionAdMapper promotionAdMapper;

    /*
 分页查询广告信息
  */
    @Override
    //注意:java会识别<>符合位分割符,也就是说
    //PageInfo<PromotionAd> findAllPromotionAdByPage和PageInfo<PromotionAd>findAllPromotionAdByPage
    //是一样的后面的虽然紧挨在一起,但实际上是分开的,在解释为class时,就会分开
    //而在maven中的target的对应classes里存放的就是class文件,而不是java文件,可以点击看一下就知道了
    public PageInfo<PromotionAd> findAllPromotionAdByPage(PromotionAdVo promotionAdVo) {
        //使用分页,那么在进行sql语句执行时,会进行对应参数
        //来实现limit语句操作拼接,也就是添加对应的limit的sql语句
        //在日志中可以看到:
        //Preparing: select * from promotion_ad limit ?,? 
        //Parameters: 0(Integer), 5(Integer) 
        //上面的形式
        PageHelper.startPage(promotionAdVo.getCurrentPage(),promotionAdVo.getPageSize());

        List<PromotionAd> allPromotionAdByPage = 
            promotionAdMapper.findAllPromotionAdByPage(promotionAdVo);

        //上面我们根据对应分页操作获得了对应数据了,但是根据需求,我们还需要一些其他数据,对应数据如下
        //要获得这些数据,要通过参数的地址(也就是上面list集合的地址)
        //来确定获得对应数据,因为我们使用分页时
        //也就是进行sql语句的拼接时,会保留这个获得数据的地址信息
        //当确定了是这个地址,那么可以获得我们操作的分页所得到的数据,因为要得到分页的数据
        //一般都会有总条数,当前页显示多少条,总页数,当前是第几页,当前页这些数据等等
        //我们在拼接之前,都会对传递的startPage方法的参数进行操作
        //而进行这些操作,就会需要对应的数据,如上面的对应数据
        //以及获得对应的数据(如list集合)等等,而我们进行对应sql执行时,拼接sql,返回执行的数据
        //在返回之前,将数据就与获得的地址进行绑定了,也就是说,只能通过这个地址来获得这些数据
        //否则是得不到对应数据的
        //比如你给出没有存放过的地址,那么对应的数据一般都是默认值
        //如0,或者false(boolean类型的默认值是false,这是基础,不要搞错了)等等
        //所以下面的参数就是获得的数据(这里是list集合),但一般只会操纵list集合(源码里只要list集合)
        //因为不是多条数据的,是没有分页的必要的,所以PageInfo类只操作了list集合
        PageInfo<PromotionAd> promotionAdPageInfo = new PageInfo<>(allPromotionAdByPage);
 	
        return promotionAdPageInfo; //返回对应的数据
    }
}

如图(日志):

在这里插入图片描述

可以发现,在日志中的确进行了拼接,对应参数是0,5,由于前端传递的参数是1,5,1表示当前页,5表示的是查询条数
发现对应参数0,5的确是第一页并查询的是5条,而这样的由来是因为limit 0,5在sql里面表示从第一条(下标为0)开始,查询5条
Web层:PromotionAdController :
package com.lagou.controller;

import com.github.pagehelper.PageInfo;
import com.lagou.domain.PromotionAd;
import com.lagou.domain.PromotionAdVo;
import com.lagou.domain.ResponseResult;
import com.lagou.service.PromotionAdService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 *
 */
@RestController
@RequestMapping("/PromotionAd")
public class PromotionAdController {

    @Autowired
    private PromotionAdService promotionAdService;

    /*
    广告分页查询
     */
    //实际上注解也不一定非得写在所操作的操作对象上面
    //只要符合操作对象是该注解的下一个就可以,所以变量左边可以写上注解
    //又或者@RequestMapping("/findAllPromotionAdByPage") public ResponseResult...(省略)这样的写法
    @RequestMapping("/findAllPromotionAdByPage")
    public ResponseResult findAllPromotionAdByPage(PromotionAdVo promotionAdVo){
        PageInfo<PromotionAd> allPromotionAdByPage = 
            promotionAdService.findAllPromotionAdByPage(promotionAdVo);
        //allPromotionAdByPage包含了其他分页数据和查询到的数据
        ResponseResult responseResult = new ResponseResult(true, 200, "广告分页查询成功", 
                                                           allPromotionAdByPage);

        return responseResult;
    }
}

使用Postman测试接口
图片上传接口
需求分析
需求:添加广告页面,点击上传按钮,需完成图片上传

在这里插入图片描述

在前面课程管理模块中,我们编写过一次图片的上传了,所以可以复制过来
图片上传只需要回显图片信息即可,而图片信息是直接存在服务器对应路径下,没有经过数据库,所以只需要Web层即可
课程管理模块的也是如此
Web层:添加部分PromotionAdController :
 /*
   广告图片上传
    */
    @RequestMapping("/PromotionAdUpload")
    public ResponseResult PromotionAdUpload(@RequestParam("file") MultipartFile file, 
                                            HttpServletRequest request) throws IOException {

        //判断接收到的上传文件是否为空
        //file.isEmpty()判断对应的数据是否为空
        if (file.isEmpty()) {
            throw new RuntimeException();
            //主动抛出异常,而不用等出现异常后执行对应异常信息(如try)
            //当然使用这个方法时也是需要对应处理异常的
        }

        //获取项目部署路径
        //D:\apache-tomcat-8.5.56\webapps\ssm_web\
        String realPath = request.getServletContext().getRealPath("/");
        //D:\apache-tomcat-8.5.56\webapps\
        String substring = realPath.substring(0, realPath.indexOf("ssm_web"));

        //获取原文件名
        //如lagou.jpg
        String originalFilename = file.getOriginalFilename();
        //让文件名基本不重复,一个用户基本不可能会有相同的名称
        //多个用户可能会有,但是用户之间肯定是不可互相访问的,所以这里就相当于设置了文件名不重复
        String newFileName = System.currentTimeMillis() + 
            originalFilename.substring(originalFilename.lastIndexOf("."));
        //得到后缀名,用时间戳当名称
        //如1651975001568.jpg

        //开始文件上传
        // D:\apache-tomcat-8.5.56\webapps\ upload\
        //注意:注释里面当出现\ u时,必须要有数,否则报错,所以上面我在\和u之间加了一个空格
        //\ u是转义字符,表示后面跟一个十六进制数,通过这个十六进制数来指定一个字符,若不是则报错
        String uploadPath = substring + "upload\\";
        //加上/也可以,但为了符号windows的目录化,就使用\\了,网页就是/
        File file1 = new File(uploadPath, newFileName);

        //如果目录不存在则创建目录(判断有没有父路径uploadPath,没有则创建)
        if (!file1.getParentFile().exists()) {
            file1.getParentFile().mkdirs();
            System.out.println("创建目录" + file1);
        }

        //图片进行上传
        file.transferTo(file1);

        //将文件名和文件路径返回给前端,使得前端显示图片
        HashMap<String, String> objectObjectHashMap = new HashMap<>();
        objectObjectHashMap.put("fileName", newFileName);
        //文件名,如1651975001568.jpg
        objectObjectHashMap.put("filePath", "http://localhost:8080/upload/" + newFileName);
        //在服务器上的访问路径,也就是通过端口访问服务器资源的路径

        ResponseResult responseResult = new ResponseResult(true, 200, "图片上传成功", 
                                                           objectObjectHashMap);

        return responseResult; //会解析集合的,也就是将map进行解析



    }
使用Postman测试接口
接下来我们操作新建和修改广告,若可以的话,可以不看后面代码自己进行编写
新建广告
需求分析
新建需求:点击提交按钮,将页面内容保存到数据库

在这里插入图片描述

Dao层:添加部分PromotionAdMapper:
/*
    添加广告
     */
    public void savePromotionAd(PromotionAd promotionAd);
添加部分PromotionAdMapper.xml:
  <!--添加广告-->

    <insert id="savePromotionAd" parameterType="PromotionAd">
        INSERT INTO promotion_ad
        VALUES(NULL,#{name},#{spaceId},#{keyword},
         #{htmlContent},#{text},#{link},#{startTime},#{endTime},#{createTime},
         #{updateTime},#{status},#{priority},#{img});
<!--
注意:有些关于时间的字段,其类型格式在类里面使用注解设置了,可以去类里面看一下
然后添加时,最好按照对应格式添加,否则基本报错
-->
    </insert>
Service层:添加部分PromotionAdService及其实现类 :

    /*
    添加广告
     */
    public void savePromotionAd(PromotionAd promotionAd);
 //添加广告
    @Override
    public void savePromotionAd(PromotionAd promotionAd) {

        //补全信息,这里我们可以说一下,为什么需要在后台补全信息
        //首先我们需要直到,前端获取的时间数据,若我们在前端直接加上信息,那么也就是需要多加几个参数
        //而后端只需要set方法一下,很明显方便一点,但无论哪一种,都是进行信息的操作
        //而使用方便,也就是维护性
        //也是尽量的好(当然也是可以不好的,或者故意不好的,这就是看你如何操作了,嘿嘿嘿)
        Date date = new Date();
        promotionAd.setCreateTime(date);
        promotionAd.setUpdateTime(date);

        promotionAdMapper.savePromotionAd(promotionAd);
    }
Web层:添加部分PromotionAdController :
 /*
    添加广告 后续进行修改扩展
     */
    @RequestMapping("/saveOrUpdatePromotionAd")
    public ResponseResult saveOrUpdatePromotionAd(@RequestBody PromotionAd promotionAd){

        promotionAdService.savePromotionAd(promotionAd);
        ResponseResult responseResult = new ResponseResult(true, 200, "添加广告成功", null);
        return responseResult;
    }
使用Postman测试接口
接下来我们进行修改操作
但在修改操作之前,我们需要进行回显
Dao层:添加部分PromotionAdMapper:
/*
    根据id查询广告
     */
    public PromotionAd findPromotionAdById(Integer id);
添加部分PromotionAdMapper.xml:
  <!--根据id查询广告-->
    <select id="findPromotionAdById" resultType="PromotionAd">
            select * from promotion_ad where id=#{id}
    </select>
Service层:添加部分PromotionAdService及其实现类 :
/*
    根据id查询广告
     */
    public PromotionAd findPromotionAdById(Integer id);
  /*
    根据id查询广告
     */
    @Override
    public PromotionAd findPromotionAdById(Integer id) {
        PromotionAd promotionAdById = promotionAdMapper.findPromotionAdById(id);

        return promotionAdById;
    }
Web层:添加部分PromotionAdController :
 /*
    根据id查询广告
     */
    @RequestMapping("/findPromotionAdById")
    public ResponseResult findPromotionAdById(Integer id){

        PromotionAd promotionAdById = promotionAdService.findPromotionAdById(id);

        ResponseResult responseResult = new ResponseResult(true, 200, "查询具体广告成功", 
                                                           promotionAdById);
        return responseResult;
    }
回显后,进行修改操作
Dao层:添加部分PromotionAdMapper:
  /*
   修改广告
    */
    public void updatePromotionAd(PromotionAd promotionAd);
添加部分PromotionAdMapper.xml:
    <!--修改广告-->
    <update id="updatePromotionAd" parameterType="PromotionAd">
        update promotion_ad
           <trim prefix="SET" suffixOverrides=",">
             <if test="name != null and name != ''">
               name = #{name},
             </if>
             <if test="spaceId != null and spaceId != ''">
               spaceId = #{spaceId},
             </if>
             <if test="link != null">
               link=#{link},
             </if>
             <if test="status != null and status != '' or status == 0">
            <!--
		这里说明一下,为什么对应整型可以判断'',这是因为替换之前,会将对应信息变成字符串
		所以无论对应类型是什么,都是字符串之间的值比较
		-->
               status=#{status},
             </if>
             <if test="img != null">
               img=#{img},
             </if>
             <if test="text != null">
               text=#{text},
             </if>
             <if test="startTime != null">
               startTime=#{startTime},
             </if>
             <if test="endTime != null">
               endTime=#{endTime},
             </if>
             <if test="updateTime != null">
               updateTime=#{updateTime},
             </if>
           </trim>
           <where>
             <if test="id != null and id != '' ">id = #{id}</if>
           </where>

    </update>
Service层:添加部分PromotionAdService及其实现类 :
 /*
 修改广告
  */
    public void updatePromotionAd(PromotionAd promotionAd);
    /*
 修改广告
  */
    @Override
    public void updatePromotionAd(PromotionAd promotionAd) {
        promotionAd.setUpdateTime(new Date());

        promotionAdMapper.updatePromotionAd(promotionAd);

    }
Web层:修改部分PromotionAdController (扩展saveOrUpdatePromotionAd方法):
  @RequestMapping("/saveOrUpdatePromotionAd")
    public ResponseResult saveOrUpdatePromotionAd(@RequestBody PromotionAd promotionAd){
        ResponseResult responseResult;
        if(promotionAd.getId() == null) {
            promotionAdService.savePromotionAd(promotionAd);
            responseResult= new ResponseResult(true, 200, "添加广告成功", null);

        }else{
            promotionAdService.updatePromotionAd(promotionAd);
            responseResult= new ResponseResult(true, 200, "修改广告成功", null);

        }
        return responseResult;
    }
广告状态上下线
需求分析
需求:点击按钮,实现状态的动态上下线

在这里插入图片描述

Dao层:添加部分PromotionAdMapper:
/*
    广告动态上下线
     */
    public void updatePromotionAdStatus(PromotionAd promotionAd);
添加部分PromotionAdMapper.xml:
 <!--广告动态上下线-->   
    <update id="updatePromotionAdStatus" parameterType="PromotionAd">
        update promotion_ad set status = #{status},updateTime = #{updateTime} where id = #{id}
    </update>
Service层:添加部分PromotionAdService及其实现类 :
 /*
    广告动态上下线
     */
    public void updatePromotionAdStatus(Integer id, Integer status);
    //在这里说明一下,之所以我们在dao层使用类,主要是因为sql语句的原因,使用类比使用多个参数方便
    //这里由于基本不会修改参数,所以我们进行固定的参数设置,而节省一点内存空间
    //而findAllPromotionAdByPage方法参数是类,主要是防止突然需要其他参数,使得变得修改麻烦
    //所以当确定会有其他参数会添加时,则使用类来操作,提高维护性(当小额度提升时,优先于维护性)
    //小额度:就是非常小的提升
 /*
   广告动态上下线
    */
    @Override
    public void updatePromotionAdStatus(Integer id, Integer status) {
        PromotionAd promotionAd = new PromotionAd();
        promotionAd.setId(id);
        promotionAd.setStatus(status);
        promotionAd.setUpdateTime(new Date());
        promotionAdMapper.updatePromotionAdStatus(promotionAd);
    }
Web层:添加部分PromotionAdController :
    /*
   广告动态上下线
    */
    @RequestMapping("/updatePromotionAdStatus")
     public ResponseResult updatePromotionAdStatus(Integer id,Integer status){
         promotionAdService.updatePromotionAdStatus(id,status);
        ResponseResult responseResult = new ResponseResult(true, 200, "广告动态上下线成功", null);
        return responseResult;

     }
使用Postman测试接口
用户管理模块:
用户管理模块功能分析 :
实现以下功能:
用户分页和条件查询一起操作
用户状态设置
下面也与用户操作关联,但会与权限相关,所以我们说明完权限管理模块后,再在用户对应代码里进行操作:
登陆(权限管理模块)
权限控制(显示管理模块的操作,权限管理模块)
分配角色(权限管理模块)
登录页面部分显示:

在这里插入图片描述

下面是用户可以操作的模块权限,若没有对应权限,那么对应的模块也就不会显示出现

在这里插入图片描述

对应数据库表,在70章博客里有了(实际上包含了所有数据库)
表关系介绍:

在这里插入图片描述

用户管理模块的实现 :
用户分页和条件查询的一起的操作
返回总体数据,实际上就是先进行条件查询,然后在进行分页,与前面广告的分页不同的是,这里在查询时
即加上了条件语句,又加上了分页语句,而广告那里只加上了分页语句
需求分析
需求:实现多条件分页组合查询

在这里插入图片描述

具体分析:

在这里插入图片描述

根据分析我们知道,我们需要编写一个类,而之所以我们不去扩展PromotionAdVo类,是因为,扩展的话
虽然现在对应内存空间是占优势,但随着广告分页的请求变多,初始化也就越来越多(两个变量,变成了五个变量了)
所以创建的对象也就越大,所以需要的内存空间也就会越来越多,在长远看来,还是新创建一个类比较好
创建UserVo类:
package com.lagou.domain;

import org.springframework.format.annotation.DateTimeFormat;

import java.util.Date;

/**
 *
 */
public class UserVo {
    private Integer currentPage;
    private Integer pageSize;
    //多条件查询:用户名(手机号)
    private String username;
    //注册起始时间
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    //使用这个后,springmvc只会操作这个注解获得对应Date类型了,而不会使用默认的两个转换(方法,虽然只说明过出参)进行操作了
    //只要是字符串,那么要变成Date类型,基本都要进行转换
    
    //但是也要注意,他们也只是操作赋值,对应的json并没有操作
    //这时就需要@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")来操作json了
    //但json默认解析Date字符串(这是肯定的,因为本来就可以操作Date,但一般都是字符串),即上面的注解也是一样
    //即这样是设置格式的
    
    //所以若是json格式赋值,那么默认是解析Date格式,且默认的格式是yyyy-MM-dd,设置了就使用设置的
    //这里是使用json的(后面使用了@RequestBody注解,所有操作的是json)
    //所以上面的 @DateTimeFormat(pattern = "yyyy-MM-dd")是不起作用,没有操作json,即不写也没关系
    private Date startCreateTime;
    //注册结束时间
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    /*
    使用这个注解,那么就与配置文件是一样的,但注解不用被激活
也就是<mvc:annotation-driven conversion-service="conversionService"></mvc:annotation-driven>
里面的conversion-service="conversionService"不用配置

    配置文件指定了对应类,而注解直接在这个类中指定了对应的类型
    并通过注解内容进行类型转换的操作(有方法的调用),所以原理与xml类似,只是底层帮我们调用了而已
    */
    private Date endCreateTime;

    public Integer getCurrentPage() {
        return currentPage;
    }

    public void setCurrentPage(Integer currentPage) {
        this.currentPage = currentPage;
    }

    public Integer getPageSize() {
        return pageSize;
    }

    public void setPageSize(Integer pageSize) {
        this.pageSize = pageSize;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public Date getStartCreateTime() {
        return startCreateTime;
    }

    public void setStartCreateTime(Date startCreateTime) {
        this.startCreateTime = startCreateTime;
    }

    public Date getEndCreateTime() {
        return endCreateTime;
    }

    public void setEndCreateTime(Date endCreateTime) {
        this.endCreateTime = endCreateTime;
    }
}

Dao层:UserMapper:
package com.lagou.dao;

import com.lagou.domain.User;
import com.lagou.domain.UserVo;

import java.util.List;

/**
 *
 */
public interface UserMapper {
    /*
    用户分页以及多条件组合查询
     */
    public List<User> findAllUserByPage(UserVo userVo);
}

对应映射配置文件(UserMapper.xml):
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.lagou.dao.UserMapper">
    <!--用户分页及其多条件组合查询-->
    <select id="findAllUserByPage" parameterType="UserVo" resultType="User">
        select * from user
        <where>
            <if test="true">
                and is_del !=1
            </if>
            <if test="username !=null and username != ''">
            <!--
            由于字符串会识别''进行操作,而不是字符串的识别''时,一般就是默认
            所以字符串通常需要判断'',其他类型的一般不需要
            -->
                and name = #{username}  <!--这里不进行模糊查询的-->
            </if>
            <if test="startCreateTime !=null and endCreateTime != null">
                and create_time between #{startCreateTime} and #{endCreateTime}
            </if>
        </where>
    </select>
</mapper>
Service层:UserService及其实现类 :
package com.lagou.service;

import com.github.pagehelper.PageInfo;
import com.lagou.domain.UserVo;

/**
 *
 */
public interface UserService {
    /*
    用户分页及其多条件查询
     */

    public PageInfo findAllUserByPage(UserVo userVo);
    //返回值类型在前面说过,即包含了分页所需的信息,也包含了对应的查询结果信息(通常是list集合)
}

package com.lagou.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.lagou.dao.UserMapper;
import com.lagou.domain.User;
import com.lagou.domain.UserVo;
import com.lagou.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 *
 */
@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserMapper userMapper;
    //用户分页及其多条件查询
    @Override
    public PageInfo findAllUserByPage(UserVo userVo) {

        //分页设置
        PageHelper.startPage(userVo.getCurrentPage(),userVo.getPageSize());

        List<User> allUserByPage = userMapper.findAllUserByPage(userVo);
        PageInfo<User> pageInfo = new PageInfo<>(allUserByPage);
        return pageInfo;
    }
}

Web层:UserController:
package com.lagou.controller;

import com.github.pagehelper.PageInfo;
import com.lagou.domain.ResponseResult;
import com.lagou.domain.UserVo;
import com.lagou.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 *
 */
@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private UserService userService;

    /*
    用户分页及其多条件查询
     */
    @RequestMapping("/findAllUserByPage")
    public ResponseResult findAllUserByPage(@RequestBody UserVo userVo) {

        PageInfo allUserByPage = userService.findAllUserByPage(userVo);
        ResponseResult responseResult = new ResponseResult(true, 200, "分页多条件查询成功", 
                                                           allUserByPage);
        return responseResult;
    }
}

使用Postman测试接口
用户状态设置:
通过上面的编写,若可以的话,可以不看后面代码,自己进行一次用户状态设置的修改代码的编写
需求分析
点击禁用,实现用户的状态变更
Dao层:添加部分UserMapper:
 /*
    用户状态修改
     */
    public void updateUserStatus(User user);
添加部分UserMapper.xml:
  <!--用户状态设置-->
    <update id="updateUserStatus" parameterType="User">
            update user set status = #{status},update_time = #{update_time} where id = #{id}
    </update>
Service层:添加部分UserService及其实现类 :
  /*
   用户状态修改
    */
    public void updateUserStatus(Integer id,String status);
 /*
       用户状态修改
        */
    @Override
    public void updateUserStatus(Integer id,String status) {

        User user = new User();
        user.setId(id);
        user.setStatus(status);
        user.setUpdate_time(new Date());

        userMapper.updateUserStatus(user);


    }
Web层:添加部分UserController:
  /*
    用户状态修改
     */
    @RequestMapping("/updateUserStatus")
    public ResponseResult updateUserStatus(Integer id,String status) {
        userService.updateUserStatus(id,status);
        ResponseResult responseResult = new ResponseResult(true, 200, "用户状态修改成功",status);
        return responseResult;
    }
使用Postman测试接口
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值