[Transfer] springboot+mybatis generic package development

After JDK1.5 came out, Java began to support generic development. By declaring the parent class as generic, the subclass inherits the parent class, and the subclass can have the methods of the parent class without writing code. Generic development can make our code development provide great convenience and simplify our code.
In the springboot project (other projects are the same), we often need to use the addition, deletion, modification and query interface. From the controller/service/dao layer, each layer must write the addition, deletion, modification and query code, and each data table must be repeated. Delete, modify and check function. Although it is easy to write, as a programmer, writing repetitive code is a waste of time and life.
The programmer's main energy should be on how to realize the business.
Let's take a look at how to encapsulate code through generic development to simplify development.

1. Declare the generic parent class
The generic parent class includes: controller/service/dao three layers.

1. Declare the generic virtual base class AbstractController and define the interface method:

public abstract class AbstractController<T, K>{

    /**
     * 新增
     * @param t
     * @return
     */
    public abstract RtnData insert(T t);

    /**
     * 修改
     * @param t
     * @return
     */
    public abstract RtnData update(T t);

    /**
     * 删除
     * @param
     * @return
     */
    public abstract RtnData delete(K id);

    /**
     * 按主键查询
     * @param
     * @return
     */
    public abstract RtnData get(K Id);

    /**
     * 分页查询
     * @return
     */
    public abstract RtnData queryPageList(int pageSize, int pageIndex, Map<String,Object> params);

    /**
     * 多条件查询
     * @return
     */
    public abstract RtnData queryList(Map<String,Object> params);

}

2. Implement the generic parent class BaseController and inherit AbstractController
Here we define the generic parent class BaseController, inherit and implement the AbstractController method, and define the RequestMapping of each method in BaseController. In this way, the business class directly inherits from BaseController and can use the default implementation of the addition, deletion, modification and query interface.

public class BaseController<T, K> extends AbstractController<T, K> {

    @Autowired
    private IService<T, K> service;

    @PostMapping("/insert")
    @Override
    public RtnData insert(@RequestBody T t) {
        return RtnData.ok(service.insert(t));
    }

    @PostMapping("/update")
    @Override
    public RtnData update(@RequestBody T t) {
        return RtnData.ok(service.update(t));
    }

    @GetMapping("/delete")
    @Override
    public RtnData delete(K id) {
        return RtnData.ok(service.delete(id));
    }

    @GetMapping("/get")
    @Override
    public RtnData get(K id) {
        return RtnData.ok(service.get(id));
    }

    @GetMapping("/page-list")
    @Override
    public RtnData queryPageList(@RequestParam(required = false, defaultValue = "20") int pageSize,
                                 @RequestParam(required = false, defaultValue = "1") int pageIndex,
                                 @RequestParam Map<String,Object> params) {
        return RtnData.ok(service.queryPageList(pageSize, pageIndex, params));
    }

    @GetMapping("/list")
    @Override
    public RtnData queryList(@RequestParam Map<String, Object> params) {
        return RtnData.ok(service.queryList(params));
    }
}

BaseController injects generic IService to implement specific business operations

3. Declare the generic business interface class IService

public interface IService<T,K>{

    /**
     * 新增
     * @param t
     * @return
     */
    public Object insert(T t);

    /**
     * 修改
     * @param t
     * @return
     */
    public Object update(T t);

    /**
     * 删除
     * @param
     * @return
     */
    public Object delete(K id);

    /**
     * 按主键查询
     * @param
     * @return
     */
    public T get(K id);

    /**
     * 分页查询
     * @param pageSize
     * @param pageIndex
     * @param params
     * @return
     */
    Object queryPageList(int pageSize, int pageIndex, Map<String, Object> params);

    /**
     * 条件查询
     * @param params
     * @return
     */
    Object queryList(Map<String, Object> params);
}

4. Define the generic business class BaseService, implement the IService class
BaseService to implement the method of sending in the IService interface, and write the default business implementation of the addition, deletion, modification, and query operations. Subclasses have its methods by inheriting from BaseService.

public class BaseService<T,K> implements IService<T,K> {

    @Autowired
    protected Mapper<T, K> mapper;

    private Class<T> modelClass;//当前泛型的真实类型Class

    public BaseService() {
        ParameterizedType pt = (ParameterizedType) this.getClass().getGenericSuperclass();
        modelClass = (Class<T>) pt.getActualTypeArguments()[0];
    }

    @Override
    public Object insert(T t) {
        return mapper.insert(t);
    }

    @Override
    public Object update(T t) {
        return mapper.updateByPrimaryKey(t);
    }

    @Override
    public Object delete(K id) {
        return mapper.deleteByPrimaryKey(id);
    }

    @Override
    public T get(K id) {
        return mapper.selectByPrimaryKey(id);
    }

    @Override
    public Object queryPageList(int pageSize, int pageIndex, Map<String, Object> params) {
        PageHelper.startPage(pageIndex, pageSize);
        Page page = mapper.queryPageList(params);//Page本身是一个ArrayList对象,转换为json时不会保留分页信息
        PageInfo pageInfo = page.toPageInfo();//将page转换成pageInfo会保存分页信息返回
        return new PageModel(pageInfo);
    }

    @Override
    public Object queryList(Map<String, Object> params) {
        return mapper.queryList(params);
    }

}

The most important two lines of code here are:
ParameterizedType pt = (ParameterizedType) this.getClass().getGenericSuperclass();
modelClass = (Class<T>) pt.getActualTypeArguments()[0];
Through generic reflection, get the subclass The actual class of the object to be operated, through the class, the service knows which object to add, delete, modify, and check.
In addition, we injected the generic Mapper<T, K> of the dao layer, and added, deleted, modified and checked the database through Mybatis

5. Declare Dao layer generic Mapper

public interface Mapper<T, K> {

    int deleteByPrimaryKey(K id);

    int insert(T record);

    int insertSelective(T record);

    T selectByPrimaryKey(K id);

    int updateByPrimaryKeySelective(T record);

    int updateByPrimaryKey(T record);

    /**
     * 分页查询(由子类实现)
     * @param params
     * @return
     */
    Page queryPageList(Map<String, Object> params);

    /**
     * 多条件查询(由子类实现)
     * @param params
     * @return
     */
    List<Map<String,Object>> queryList(Map<String, Object> params);
}

Here we use mybatis to implement the operation of the dao layer. The declared interface method name here is consistent with the mapper.xml generated by the mybatis tool

At this point, our generic parent class code has all been written. The above code can be made into a jar package and put into the project as a basic package for direct reference.
Let's talk about how to actually use it in the project.

2. Project application
For reference in the project, just inherit the above parent class in the subclass code layer, and the subclass will have the functions in the parent class.

1. Subclass Controller

@RestController
@RequestMapping("/api/dic")
public class DataDicController extends BaseController<DataDic, Integer> {
}

Did you see that there is no method written in it, only RequestMapping is declared, and the generic type is replaced with a specific object type.
DataDic is the object I operate, and Integer is the primary key type of DataDic.
The new interface address of this BaseController is /api/dic/insert, and /insert uses the RequestMapping of the parent class.
In addition, I did not write the injection of Service, because the container will directly find the generic instance corresponding to IService according to the generic Service to be injected in the parent class

2. Subclass Service

@Service
public class DataDicService extends BaseService<DataDic, Integer> {
}

Similarly, Service does not have any code, nor is it injected into Mapper, it only inherits generics

3. Subclass Mapper

@Mapper
public interface DataDicMapper extends com.cc.app.base.dao.Mapper<DataDic, Integer> {
}

Mapper needs to inherit our own generic Mapper so that it can be found by Service.
Explanation: The Mapper object we generated through the tool will contain the default method, you don’t need to delete it, because it is the same as the inherited Mapper method name, it is overriding Override

At this point, all the work is over, and the addition, deletion, modification and query interface of our DataDicController has been written, and we will test it next.

3. Interface test

1. Query interface get

image.png

2. Insert interface insert



Author: Gu Jia Haxing
Link: https://www.jianshu.com/p/e1c86b3bff2f
Source: Jianshu
The copyright belongs to the author. For commercial reprint, please contact the author for authorization, for non-commercial reprint, please indicate the source.

Guess you like

Origin blog.csdn.net/mao_mao37/article/details/129712069