[Transferencia] desarrollo de paquete genérico springboot+mybatis

Después de que salió JDK1.5, Java comenzó a admitir el desarrollo genérico. Al declarar la clase principal como genérica, la subclase hereda la clase principal y la subclase puede tener los métodos de la clase principal sin escribir código. El desarrollo genérico puede hacer que nuestro desarrollo de código brinde una gran comodidad y simplifique nuestro código.
En el proyecto springboot (otros proyectos son iguales), a menudo necesitamos usar la interfaz de adición, eliminación, modificación y consulta.Desde la capa controlador/servicio/dao, cada capa debe escribir el código de adición, eliminación, modificación y consulta, y cada tabla de datos debe repetirse Función borrar, modificar y comprobar. Aunque es fácil de escribir, como programador, escribir código repetitivo es una pérdida de tiempo y de vida.
La energía principal del programador debe estar en cómo realizar el negocio.
Echemos un vistazo a cómo encapsular el código a través del desarrollo genérico para simplificar el desarrollo.

1. Declarar la clase principal genérica
La clase principal genérica incluye: controlador/servicio/dao tres capas.

1. Declare la clase base virtual genérica AbstractController y defina el método de interfaz:

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. Implementar la clase padre genérica BaseController y heredar AbstractController
Aquí definimos la clase padre genérica BaseController, heredar e implementar el método AbstractController y definir el RequestMapping de cada método en BaseController. De esta manera, la clase de negocio hereda directamente de BaseController y puede usar la implementación predeterminada de la interfaz de adición, eliminación, modificación y consulta.

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 inyecta IService genérico para implementar operaciones comerciales específicas

3. Declarar la clase de interfaz comercial genérica 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. Defina la clase comercial genérica BaseService, implemente la clase IService
BaseService para implementar el método de envío en la interfaz IService y escriba la implementación comercial predeterminada de las operaciones de adición, eliminación, modificación y consulta. Las subclases tienen sus métodos al heredar de 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);
    }

}

Las dos líneas de código más importantes aquí son:
ParameterizedType pt = (ParameterizedType) this.getClass().getGenericSuperclass();
modelClass = (Class<T>) pt.getActualTypeArguments()[0];
A través de la reflexión genérica, obtenga la subclase La clase real del objeto que se va a operar, a través de la clase, el servicio sabe qué objeto agregar, eliminar, modificar y verificar.
Además, inyectamos el Mapper<T, K> genérico de la capa dao, y agregamos, borramos, modificamos y revisamos la base de datos a través de Mybatis

5. Declarar mapeador genérico de capa Dao

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);
}

Aquí usamos mybatis para implementar la operación de la capa dao. El nombre del método de interfaz declarado aquí es consistente con el mapper.xml generado por la herramienta mybatis

En este punto, nuestro código de clase principal genérico ya se ha escrito. El código anterior puede convertirse en un paquete jar y colocarse en el proyecto como un paquete básico para referencia directa.
Hablemos de cómo usarlo realmente en el proyecto.

2. Aplicación del proyecto
Para referencia en el proyecto, simplemente herede la clase principal anterior en la capa de código de la subclase, y la subclase tendrá las funciones de la clase principal.

1. Controlador de subclase

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

¿Viste que no hay ningún método escrito en él, solo se declara RequestMapping y el tipo genérico se reemplaza con un tipo de objeto específico?
DataDic es el objeto que opero, e Integer es el tipo de clave principal de DataDic.
La nueva dirección de interfaz de este BaseController es /api/dic/insert, y /insert usa el RequestMapping de la clase principal.
Además, no escribí la inyección de Servicio, porque el contenedor encontrará directamente la instancia genérica correspondiente a IService de acuerdo con el Servicio genérico que se inyectará en la clase padre.

2. Servicio de subclase

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

Del mismo modo, Service no tiene ningún código, ni se inyecta en Mapper, solo hereda genéricos

3. Asignador de subclases

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

Mapper necesita heredar nuestro propio Mapper genérico para que Service pueda encontrarlo.
Explicación: El objeto Mapper que generamos a través de la herramienta contendrá el método predeterminado, no necesita eliminarlo, porque es el mismo que el nombre del método Mapper heredado, está anulando Override

En este punto, todo el trabajo ha terminado, y se ha escrito la interfaz de adición, eliminación, modificación y consulta de nuestro DataDicController, y lo probaremos a continuación.

3. Prueba de interfaz

1. Obtener interfaz de consulta

imagen.png

2. Insertar inserto de interfaz



Autor: Gu Jia Haxing
Enlace: https://www.jianshu.com/p/e1c86b3bff2f
Fuente: Jianshu
Los derechos de autor pertenecen al autor. Para reimpresión comercial, comuníquese con el autor para obtener autorización, para reimpresión no comercial, indique la fuente.

Supongo que te gusta

Origin blog.csdn.net/mao_mao37/article/details/129712069
Recomendado
Clasificación