模仿mybatisplus的模板方法的设计模式

93 阅读1分钟

思路

通过反射获得实体类的各种sql的参数 然后生成对应的sql语句进行查询

默认的实现使用简单的泛型配合反射+维护一个mapper 就可以实现默认的查询

代码

public class Service extends MyGetImpl<ImplMyDataAccessor, User>{

    public void getUser(){
        User byId = getById(1);
        // 资源的获取
        System.out.println(byId);
    }

    public static void main(String[] args) {
        Service service = new Service();
        service.getUser();
    }
}
public interface MyGet <T> {
    T getById(int id);
}
public class MyGetImpl<M extends MyDataAccessor<T>, T> implements MyGet<T> {
    private Class<M> clazz;
    private M dataAccessor; // 存储 MyDataAccessor 实例

    public MyGetImpl() {
        // 1. 获取泛型参数 M 的类型
        Type genericSuperclass = this.getClass().getGenericSuperclass();
        if (genericSuperclass instanceof ParameterizedType) {
            ParameterizedType parameterizedType = (ParameterizedType) genericSuperclass;
            Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
            if (actualTypeArguments.length > 0) {
                this.clazz = (Class<M>) actualTypeArguments[0];
            }
        }

        // 2. 反射创建 MyDataAccessor 实例
        try {
            if (clazz != null) {
                this.dataAccessor = clazz.getDeclaredConstructor().newInstance();
            }
        } catch (Exception e) {
            throw new RuntimeException("Failed to create MyDataAccessor instance", e);
        }
    }

    @Override
    public T getById(int id) {
        if (dataAccessor == null) {
            throw new IllegalStateException("MyDataAccessor not initialized");
        }
        // 调用 MyDataAccessor 的 getById 方法
        return dataAccessor.getById(String.valueOf(id));
    }
}
@Data
@Group("注释")
public class User {

    private String id ;
    private String name ;
}
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.ANNOTATION_TYPE})
public @interface Group
{
    String value() default "";
}
@Data
public  class ImplMyDataAccessor implements MyDataAccessor<User> {

   Map<String,User> map =  new ConcurrentHashMap<>();

    public ImplMyDataAccessor() {
        // 模拟数据库数据
        User user1 = new User();
        user1.setId("1");
        user1.setName("Alice");
        map.put("1", user1);

        User user2 = new User();
        user2.setId("2");
        user2.setName("Bob");
        map.put("2", user2);



    }

    @Override
    public User getById(String id) {
        // 具体是使用对对象的反射 获得字段上面的属性值 然后拼接模板sql
        Annotation[] annotations = User.class.getAnnotations();
        for (Annotation annotation : annotations) {
            if (annotation instanceof Group group) {
                System.out.println("Found @Group with value: " + group.value());
            }
        }
        return map.get(id);
    }

}
public interface MyDataAccessor<T> {
     T getById(String id);
}

最后效果

image.png