寻找写代码感觉(七)之封装请求参数和返回参数
一、目的
封装请求参数的目的,是为了统一和方便。直白点说,如果只查询一个属性,传一个入参,这是没问题的,要是一个对象有100个属性,查询需要多个参数关联,就需要统一方便管理了,简单说传对象就完了,哈哈哈。
二、实际案例
先举个例子,大家一看便知,比如我现在想搞个模糊查询,按照名称查询。
1、接口改造
还是那个查询接口开始改造,示例代码如下:
package com.rongrong.wiki.controller;
import com.rongrong.wiki.domain.EBook;
import com.rongrong.wiki.resp.CommonResp;
import com.rongrong.wiki.service.EBookService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.List;
/**
* @author longrong.lang
* @version 1.0
* @description
*/
@RestController
@RequestMapping("/ebook")
public class EBookController {
@Resource
private EBookService eBookService;
@GetMapping("/list")
public CommonResp list(String name) {
CommonResp<List<EBook>> resp = new CommonResp<>();
List<EBook> list = eBookService.list(name);
resp.setMessage("执行查询成功!");
resp.setContent(list);
return resp;
}
}
2、从Service层改造
那么我先从Service
加个入参,比如Name
,这就是我们常说的按照关键字查询,Sql
来看的话就是like
一下,这块我就不废话了,有点墨迹了,示例代码如下:
package com.rongrong.wiki.service;
import com.rongrong.wiki.domain.EBook;
import com.rongrong.wiki.domain.EBookExample;
import com.rongrong.wiki.mapper.EBookMapper;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
/**
* @author rongrong
* @version 1.0
* @description
* @date 2021/10/13 10:09
*/
@Service
public class EBookService {
@Resource
private EBookMapper eBookMapper;
public List<EBook> list(String name) {
EBookExample eBookExample = new EBookExample();
//此处代码的意思相当于,搞了一个Sql的where条件
EBookExample.Criteria criteria = eBookExample.createCriteria();
criteria.andNameLike("%"+name+"%");
return eBookMapper.selectByExample(eBookExample);
}
}
3、接口改造测试
查询结果:
三、需求变更
现在我想通过ID
和Name
来查询,或者多个参数来查询,该怎么办?
1、构造统一入参
很简单,直接传个类(对象即可),那么我们先来个统一的入参构造吧,先以两个参数作为入参为例,示例代码如下:
package com.rongrong.wiki.req;
public class EBookReq {
private Long id;
private String name;
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;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(getClass().getSimpleName());
sb.append(" [");
sb.append("Hash = ").append(hashCode());
sb.append(", id=").append(id);
sb.append(", name=").append(name);
sb.append("]");
return sb.toString();
}
}
2、构造统一返回
为什么构造统一返回信息?
比如我们登录成功,不能把密码字段,也返回给用户吧,感觉好不专业是不是,正常只返回几个字段即可,所以才有了统一返回信息一说。
示例代码如下:
package com.rongrong.wiki.resp;
public class EBookResp {
private Long id;
private String name;
private Long category1Id;
private Long category2Id;
private String description;
private String cover;
private Integer docCount;
private Integer viewCount;
private Integer voteCount;
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 Long getCategory1Id() {
return category1Id;
}
public void setCategory1Id(Long category1Id) {
this.category1Id = category1Id;
}
public Long getCategory2Id() {
return category2Id;
}
public void setCategory2Id(Long category2Id) {
this.category2Id = category2Id;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getCover() {
return cover;
}
public void setCover(String cover) {
this.cover = cover;
}
public Integer getDocCount() {
return docCount;
}
public void setDocCount(Integer docCount) {
this.docCount = docCount;
}
public Integer getViewCount() {
return viewCount;
}
public void setViewCount(Integer viewCount) {
this.viewCount = viewCount;
}
public Integer getVoteCount() {
return voteCount;
}
public void setVoteCount(Integer voteCount) {
this.voteCount = voteCount;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(getClass().getSimpleName());
sb.append(" [");
sb.append("Hash = ").append(hashCode());
sb.append(", id=").append(id);
sb.append(", name=").append(name);
sb.append(", category1Id=").append(category1Id);
sb.append(", category2Id=").append(category2Id);
sb.append(", description=").append(description);
sb.append(", cover=").append(cover);
sb.append(", docCount=").append(docCount);
sb.append(", viewCount=").append(viewCount);
sb.append(", voteCount=").append(voteCount);
sb.append("]");
return sb.toString();
}
}
3、接口改造
示例代码如下:
package com.rongrong.wiki.controller;
import com.rongrong.wiki.req.EBookReq;
import com.rongrong.wiki.resp.CommonResp;
import com.rongrong.wiki.resp.EBookResp;
import com.rongrong.wiki.service.EBookService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.List;
/**
* @author longrong.lang
* @version 1.0
* @description
*/
@RestController
@RequestMapping("/ebook")
public class EBookController {
@Resource
private EBookService eBookService;
@GetMapping("/list")
public CommonResp list(EBookReq eBookReq) {
CommonResp<List<EBookResp>> resp = new CommonResp<>();
List<EBookResp> list = eBookService.list(eBookReq);
resp.setMessage("执行查询成功!");
resp.setContent(list);
return resp;
}
}
4、Service层改造
示例代码如下:
package com.rongrong.wiki.service;
import com.rongrong.wiki.domain.EBook;
import com.rongrong.wiki.domain.EBookExample;
import com.rongrong.wiki.mapper.EBookMapper;
import com.rongrong.wiki.req.EBookReq;
import com.rongrong.wiki.resp.EBookResp;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
/**
* @author rongrong
* @version 1.0
* @description
* @date 2021/10/13 10:09
*/
@Service
public class EBookService {
@Resource
private EBookMapper eBookMapper;
public List<EBookResp> list(EBookReq eBookReq) {
EBookExample eBookExample = new EBookExample();
//此处代码的意思相当于,搞了一个Sql的where条件
EBookExample.Criteria criteria = eBookExample.createCriteria();
criteria.andNameLike("%"+eBookReq.getName()+"%");
List<EBook> eBookList = eBookMapper.selectByExample(eBookExample);
List<EBookResp> eBookRespList = new ArrayList<>();
for (EBook eBook: eBookList) {
EBookResp eBookResp = new EBookResp();
//spring boot 自带的BeanUtils完成对象的拷贝
BeanUtils.copyProperties(eBook, eBookResp);
eBookResp.setId(12345L);
eBookRespList.add(eBookResp);
}
return eBookRespList;
}
}
5、接口改造后测试
6、Service层再改造
CopyUtil工具类,示例代码如下:
package com.rongrong.wiki.util;
import org.springframework.beans.BeanUtils;
import org.springframework.util.CollectionUtils;
import java.util.ArrayList;
import java.util.List;
public class CopyUtil {
/**
* 单体复制
*/
public static <T> T copy(Object source, Class<T> clazz) {
if (source == null) {
return null;
}
T obj = null;
try {
obj = clazz.newInstance();
} catch (Exception e) {
e.printStackTrace();
return null;
}
BeanUtils.copyProperties(source, obj);
return obj;
}
/**
* 列表复制
*/
public static <T> List<T> copyList(List source, Class<T> clazz) {
List<T> target = new ArrayList<>();
if (!CollectionUtils.isEmpty(source)){
for (Object c: source) {
T obj = copy(c, clazz);
target.add(obj);
}
}
return target;
}
}
对Service层再改造,示例代码如下:
package com.rongrong.wiki.service;
import com.rongrong.wiki.domain.EBook;
import com.rongrong.wiki.domain.EBookExample;
import com.rongrong.wiki.mapper.EBookMapper;
import com.rongrong.wiki.req.EBookReq;
import com.rongrong.wiki.resp.EBookResp;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
import static com.rongrong.wiki.util.CopyUtil.copyList;
/**
* @author rongrong
* @version 1.0
* @description
* @date 2021/10/13 10:09
*/
@Service
public class EBookService {
@Resource
private EBookMapper eBookMapper;
public List<EBookResp> list(EBookReq eBookReq) {
EBookExample eBookExample = new EBookExample();
//此处代码的意思相当于,搞了一个Sql的where条件
EBookExample.Criteria criteria = eBookExample.createCriteria();
criteria.andNameLike("%"+eBookReq.getName()+"%");
List<EBook> eBookList = eBookMapper.selectByExample(eBookExample);
//List<EBookResp> eBookRespList = new ArrayList<>();
//for (EBook eBook: eBookList) {
// //EBookResp eBookResp = new EBookResp();
// ////spring boot 自带的BeanUtils完成对象的拷贝
// //BeanUtils.copyProperties(eBook, eBookResp);
// //eBookResp.setId(12345L);
// //单体复制
// EBookResp copy = copy(eBook, EBookResp.class);
// eBookRespList.add(copy);
//}
//列表复制
List<EBookResp> respList = copyList(eBookList, EBookResp.class);
return respList;
}
}
7、接口改造后测试
四、最后
统一是为了更好的管理和维护,写代码确实会让人很兴奋,好在吃了止痛药,要不我这老腰肯定又废了,感谢阅读,觉得好请给我点个推荐,谢谢。
优秀不够,你是否无可替代
软件测试交流QQ群:721256703,期待你的加入!!
欢迎关注我的微信公众号:软件测试君