当前位置: 首页>编程语言>正文

Test中调用Service service如何调用dao接口

tk.mybatis提供了针对单表的一些常规增删改查以及Example相关的操作,我们能够简单方便的使用其提供的接口方法进行开发,下面我们将结合tk.mybatis提供的通用方法抽取dao和service层base接口。

首先需要导入tk.mybatis依赖,版本视springboot版本而定

<dependency>
    <groupId>tk.mybatis</groupId>
    <artifactId>mapper-spring-boot-starter</artifactId>
    <version>${tk.mybatis.version}</version>
</dependency>
1、对dao层进行基类抽取
/**
 * @param <T>
 * @description Dao层基类
 */
public interface MyMapper<T> extends Mapper<T>, InsertListMapper<T> {

}

抽取MyMapper接口继承通用Mapper和通用InsertListMapper接口,Mapper接口中提供了对象映射增删查改方法,InsertListMapper接口提供批量插入方法,这里可以根据需要继承其他通用Mapper。

2、对service层进行基类抽取
/**
 * @Description: 服务层基类
 */
public interface BaseService<T, ID, EXAMPLE> {

    /**
     * 单个实体对象全量字段保存
     *
     * @param record
     * @return
     */
    int save(T record);

    /**
     * 单个实体对象非空字段保存
     *
     * @param record
     * @return
     */
    int saveSelective(T record);

    /**
     * 多个实体对象保存
     *
     * @param list
     * @return
     */
    int saveList(java.util.List<? extends T> list);

    /**
     * 单个实体对象删除
     *
     * @param record
     * @return
     */
    int delete(T record);

    /**
     * 单个实体对象条件删除
     *
     * @param record
     * @param example
     * @return
     */
    int deleteByExample(T record, EXAMPLE example);

    /**
     * 单个实体对象主键删除
     *
     * @param record
     * @param key
     * @return
     */
    int deleteByPrimaryKey(T record, ID key);

    /**
     * 单个实体对象条件全量字段更新
     *
     * @param record
     * @param example
     * @return
     */
    int updateByExample(T record, EXAMPLE example);

    /**
     * 单个实体对象条件非空字段更新
     *
     * @param record
     * @param example
     * @return
     */
    int updateByExampleSelective(T record, EXAMPLE example);

    /**
     * 单个实体对象主键全量字段更新
     *
     * @param record
     * @return
     */
    int updateByPrimaryKey(T record);

    /**
     * 单个实体对象主键非空字段更新
     *
     * @param record
     * @return
     */
    int updateByPrimaryKeySelective(T record);
}
/**
 * @Description: 服务层基类实现类
 * 注:自定义需要保存对象日志的操作方法(insert,update,delete操作必须记录日志!)
 */
public abstract class BaseServiceImpl<T, ID, EXAMPLE> implements BaseService<T, ID, EXAMPLE> {

    @Autowired
    private ILogService logService;
    
	// 定义抽象方法getMyMapper获取当前实体Mapper对象
    protected abstract MyMapper<T> getMyMapper();

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int save(T record) {
        int res = getMyMapper().insert(record);
        logService.saveLogEntity(record, "insert", record.getClass(), null);
        return res;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int saveSelective(T record) {
        int res = getMyMapper().insertSelective(record);
        logService.saveLogEntity(record, "insert", record.getClass(), null);
        return res;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int saveList(java.util.List<? extends T> list) {
        int res = getMyMapper().insertList(list);
        list.forEach(record -> logService.saveLogEntity(record, "insert", record.getClass(), null));
        return res;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int delete(T record) {
        int res = getMyMapper().delete(record);
        logService.saveLogEntity(record, "delete", record.getClass(), null);
        return res;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteByExample(T record, EXAMPLE example) {
        int res = getMyMapper().deleteByExample(example);
        logService.saveLogEntity(record, "delete", record.getClass(), null);
        return res;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteByPrimaryKey(T record, ID key) {
        int res = getMyMapper().deleteByPrimaryKey(key);
        logService.saveLogEntity(record, "delete", record.getClass(), null);
        return res;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateByExample(T record, EXAMPLE example) {
        int res = getMyMapper().updateByExample(record, example);
        logService.saveLogEntity(record, "update", record.getClass(), null);
        return res;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateByExampleSelective(T record, EXAMPLE example) {
        int res = getMyMapper().updateByExampleSelective(record, example);
        logService.saveLogEntity(record, "update", record.getClass(), null);
        return res;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateByPrimaryKey(T record) {
        int res = getMyMapper().updateByPrimaryKey(record);
        logService.saveLogEntity(record, "update", record.getClass(), null);
        return res;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateByPrimaryKeySelective(T record) {
        int res = getMyMapper().updateByPrimaryKeySelective(record);
        logService.saveLogEntity(record, "update", record.getClass(), null);
        return res;
    }
}

BaseService接口定义了一些增删改的统一方法,BaseServiceImpl实现BaseService接口接收三个泛型参数T(实体对象), ID(主键id), EXAMPLE(Example条件)。这里有一个特殊的业务逻辑,logService.saveLogEntity方法作用时当对象进行增、删、改时,记录对象字段信息,如下:

@Mapper
public interface LogEntityMapper extends MyMapper<LoggerEntity> {

}
/**
 * @Description: 实体对象操作日志service接口
 */
public interface ILogService extends BaseService<LoggerEntity, String, Object> {

    int saveLogEntity(Object entity, String loggerType, Class<?> entityClass, String info);

}
@Service
@Slf4j
public class LogServiceImpl extends BaseServiceImpl<LoggerEntity, String, Object> implements ILogService {

    @Autowired
    private LogEntityMapper logMapper;

	    @Override
    public int saveLogEntity(Object entity, String loggerType, Class<?> entityClass, String info) {
    	// 组装LoggerEntity对象信息
    	LoggerEntity logger = new LoggerEntity();
		...
		logMapper.insert(logger);
    }
}
3、举例使用说明实现以上抽取的MyMapper dao接口和BaseService service接口

其实上面记录对象日志的操作已经举例了用法,但是还是想举个完整的例子0_0
首先定义一个Book实体类对象:

@Data
@Builder(toBuilder = true)
@Table(name = "TEST_BOOK")
public class BookEntity {
    @Id
    @Column(name = "BOOK_ID")
    private Integer bookId;
    @Column(name = "BOOK_NAME")
    private String bookName;
    @Column(name = "CREATE_TIME")
    private Date createTime;
    @Column(name = "BOOK_CONTENT")
    private String bookContent;
}
@Mapper
public interface BookEntityMapper extends MyMapper<BookEntity> {

}
public interface IBookService extends BaseService<BookEntity, Integer, Object> {

}
@Slf4j
@Service
public class BookServiceImpl extends BaseServiceImpl<BookEntity, Integer, Object> implements IBookService {

    @Autowired
    private BookEntityMapper bookMapper;

	// 重写BaseServiceImpl抽象方法,将当前bookMapper返回
    @Override
    protected MyMapper<BookEntity> getMyMapper() { return bookMapper; }
}
@Api(value = "书籍管理相关API")
@RestController
@RequestMapping("/book")
@Slf4j
public class BookController {

    @Autowired
    private IBookService bookService;

	@ApiOperation(value = "新增书籍接口", notes = "新增书籍接口", httpMethod = "POST")
    @ApiImplicitParams({@ApiImplicitParam(name = "request", value = "Book参数实体", required = true, dataType = "BookRequest")})
	@PostMapping(path = "/addBook")
	public Object addNewBook(@RequestBody @Validated BookRequest request) {
		BookEntity entity = BookEntity.builder()
							.bookId(1)
							.bookName(request.getBookName())
							.createTime(new Date())
							.bookContent(request.getBookContent())
							.build();
		return bookService.save(entity);
	}
}
#配置mybatis实体类扫描包路径
mybatis:
  mapper-locations: classpath:mapper/*.xml
  type-aliases-package: com.web.entity

启动项目调用接口即可测试,这里解释一下为什么要自己重新封装对象操作方法,实际上直接注入对象Mapper也可以直接进行增删改查操作(就如saveLogEntity方法的具体实现)。
实际项目中一定会涉及到日志的记录,上例这种结构实际上是把通用Mapper中的对象操作方法再封装了一层,在这一层可以自己加入另外的业务逻辑,在例子中,BaseServiceImpl封装的增删改方法中均用到saveLogEntity方法来记录对象日志,而saveLogEntity方法的具体实现中直接使用未进行封装的logMapper.insert();方法,控制层增删改操作使用继承BaseServiceImpl的实体service方法,这样就达到了在增删改操作下记录日志的要求。


https://www.xamrdz.com/lan/5i51934190.html

相关文章: