第五步:单元测试类SysLogDaoTests,对数据层方法进行测试。
package com.cy.pj.sys.dao;
import java.util.List;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import com.cy.pj.sys.entity.SysLog;
@SpringBootTest
public class SysLogDaoTests {
@Autowired
private SysLogDao sysLogDao;
@Test
public void testGetRowCount() {
int rows=sysLogDao.getRowCount("admin");
System.out.println("rows="+rows);
}
@Test
public void testFindPageObjects() {
List<SysLog> list = sysLogDao.findPageObjects("admin", 0, 3);
for(SysLog log:list) {
System.out.println(log);
}
}
}
3.3.2 Service接口及实现类
业务层主要是实现模块中业务逻辑的处理。在日志分页查询中,业务层对象首先要通过业务方法中的参数接收控制层数据(例如username,pageCurrent)并校验。然后基于用户名进行总记录数的查询并校验,再基于起始位置及页面大小进行当前页记录的查询,最后对查询结果进行封装并返回。
业务值对象定义,基于此对象封装数据层返回的数据以及计算的分页信息,具体代码参考如下:
package com.cy.pj.common.vo;
@Data
@NoArgsConstructor
public class PageObject<T> implements Serializable {
private static final long serialVersionUID = 6780580291247550747L;
private Integer pageCurrent=1;
private Integer pageSize=3;
private Integer rowCount=0;
private Integer pageCount=0;
private List<T> records;
public PageObject(){}
public PageObject(Integer pageCurrent, Integer pageSize, Integer rowCount, List<T> records) {
super();
this.pageCurrent = pageCurrent;
this.pageSize = pageSize;
this.rowCount = rowCount;
this.records = records;
this.pageCount=(rowCount-1)/pageSize+1;
}
定义日志业务接口及方法,暴露外界对日志业务数据的访问,其代码参考如下:
package com.cy.pj.sys.service;
public interface SysLogService {
PageObject<SysLog> findPageObjects(
String username,
Long pageCurrent);
}
测试Long 类型是否有整数池的概念:
package com.cy.pj.sys.service;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
public class IntegerPoolTests {
@Test
public void testIntegerCache() {
Integer t1 = 100;
Integer t2 = 100;
System.out.println(t1 == t2);
Integer t3 = 200;
Integer t4 = 200;
System.out.println(t3 == t4);
}
@Test
public void testLongCache() {
Long t1 = 100L;
Long t2 = 100L;
System.out.println(t1 == t2);
Long t3 = 200L;
Long t4 = 200L;
System.out.println(t3 == t4);
}
}
日志业务接口及实现类,用于具体执行日志业务数据的分页查询操作,其代码如下:
package com.cy.pj.sys.service.impl;
@Service
public class SysLogServiceImpl implements SysLogService{
@Autowired
private SysLogDao sysLogDao;
@Override
public PageObject<SysLog> findPageObjects(String name, Integer pageCurrent) {
if(pageCurrent==null||pageCurrent<1)
throw new IllegalArgumentException("当前页码不正确");
int rowCount=sysLogDao.getRowCount(name);
if(rowCount==0)
throw new ServiceException("系统没有查到对应记录");
int pageSize=2;
int startIndex=(pageCurrent-1)*pageSize;
List<SysLog> records=
sysLogDao.findPageObjects(name, startIndex, pageSize);
PageObject<SysLog> pageObject=new PageObject<>();
return new PageObject<>(pageCurrent, pageSize,rowCount, records);
}
}
在当前方法中需要的ServiceException是一个自己定义的异常, 通过自定义异常可更好的实现对业务问题的描述,同时可以更好的提高用户体验。参考代码如下:
package com.cy.pj.common.exception;
public class ServiceException extends RuntimeException {
private static final long serialVersionUID = 7793296502722655579L;
public ServiceException() {
super();
}
public ServiceException(String message) {
super(message);
}
public ServiceException(Throwable cause) {
super(cause);
}
}
说明:几乎在所有的框架中都提供了自定义异常,例如MyBatis中的BindingException等。
定义Service对象的单元测试类,代码如下:
package com.cy.pj.sys.service;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import com.cy.pj.common.vo.PageObject;
import com.cy.pj.sys.entity.SysLog;
@SpringBootTest
public class SysLogServiceTests {
@Autowired
private SysLogService sysLogService;
@Test
public void testFindPageObjects() {
PageObject<SysLog> pageObject = sysLogService.findPageObjects("admin", 3L);
System.out.println(pageObject);
}
}
Controller类实现
控制层对象主要负责请求和响应数据的处理,例如,本模块首先要通过控制层对象处理请求参数,然后通过业务层对象执行业务逻辑,再通过VO对象封装响应结果(主要对业务层数据添加状态信息),最后将响应结果转换为JSON格式的字符串响应到客户端。
定义控制层值对象(VO),目的是基于此对象封装控制层响应结果(在此对象中主要是为业务层执行结果添加状态信息)。Spring MVC框架在响应时可以调用相关API(例如jackson)将其对象转换为JSON格式字符串。
package com.cy.pj.common.vo;
@Data
public class JsonResult implements Serializable {
private static final long serialVersionUID = -856924038217431339L;
private int state=1;
private String message="ok";
private Object data;
public JsonResult() {}
public JsonResult(String message){
this.message=message;
}
public JsonResult(Object data) {
this.data=data;
}
public JsonResult(Throwable t){
this.state=0;
this.message=t.getMessage();
}
}
定义Controller类,并将此类对象使用Spring框架中的@Controller注解进行标识,表示此类对象要交给Spring管理。然后基于@RequestMapping注解为此类定义根路径映射。代码参考如下:
package com.cy.pj.sys.controller;
@Controller
@RequestMapping("/log/")
public class SysLogController {
@Autowired
private SysLogService sysLogService;
}
在Controller类中添加分页请求处理方法,代码参考如下:
@RequestMapping("doFindPageObjects")
@ResponseBody
public JsonResult doFindPageObjects(String username,Integer pageCurrent){
PageObject<SysLog> pageObject = sysLogService.findPageObjects(username,pageCurrent);
return new JsonResult(pageObject);
}
定义全局异常处理类,对控制层可能出现的异常,进行统一异常处理,代码如下:
package com.cy.pj.common.web;
import java.util.logging.Logger;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import com.cy.pj.common.vo.JsonResult;
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(RuntimeException.class)
@ResponseBody
public JsonResult doHandleRuntimeException(RuntimeException e){
e.printStackTrace();
}
return new JsonResult(e);
}
|