1

CRUD template

接口抽象

  • 单表的crud操作做出如下抽象,这个接口的作用是用来找到具体的mapper.
public interface A<Id, T> {

  int deleteByPrimaryKey(Id id);

  int insert(T record);

  int insertSelective(T record);

  T selectByPrimaryKey(Id id);

  int updateByPrimaryKeySelective(T record);

  int updateByPrimaryKey(T record);
}
  • 泛型解释:

    1. Id: 主键的数据类型
    2. T: 数据库实体
  • 接入一个mapper
@Mapper
public interface ProjectIntMapper extends A<Integer, ProjectInt> {

  int deleteByPrimaryKey(Integer integer);

  int insert(ProjectInt record);

  int insertSelective(ProjectInt record);

  ProjectInt selectByPrimaryKey(Integer integer);

  int updateByPrimaryKeySelective(ProjectInt record);

  int updateByPrimaryKey(ProjectInt record);
}
  • 对外的crud模板操作接口
public interface CrudTemplate<T, I extends IdInterface> {

  boolean insert(T t);

  T byId(I i, Class c);

  boolean del(I i , Class c);

  boolean editor(I i, T t);

}

相关实现

  • mapper 的搜索. 这里希望可以通过一个类型来直接获取这个mapper对象
@Service
public class MapperRunner {

  public static Map<Class, A> om = new HashMap<>();
  public static Map<A, Class> MO = new HashMap<>();
  @Autowired
  private ApplicationContext context;
  @Autowired
  private SqlSession sqlSession;

  public static A getA(Class a) {

    return om.get(a);
  }

  @PostConstruct
  public void hh() {
    Configuration configuration = sqlSession.getConfiguration();
    MapperRegistry mapperRegistry = configuration.getMapperRegistry();
    Collection<Class<?>> mappers = mapperRegistry.getMappers();

    for (Class<?> mapper : mappers) {
      if (mapper.isInterface()) {

        Type[] genericInterfaces = mapper.getGenericInterfaces();

        if (genericInterfaces.length > 0) {

          ParameterizedType genericInterface = (ParameterizedType) genericInterfaces[0];
          Type[] r = genericInterface.getActualTypeArguments();

          if (r.length == 2) {
            Class id = (Class) r[0];
            Class type = (Class) r[1];

            Object mapper1 = sqlSession.getMapper(mapper);
            om.put(type, (A) mapper1);
            MO.put((A) mapper1, type);
            System.out.println();
          }
        }
      }
    }
    System.out.println();
  }


}
  • 这里主要通过反射获取具体的泛型类型, 放入 om 这个map对象中. 并且提供一个方法让外部可以进行直接获取A接口
  • 实现 数据库的crud.

    • 实现方式为从 om 中获取A接口,并执行CRUD的操作
@Service
public class CommonDbOperation<T, I extends com.example.demo.service.id.IdInterface> {

  Class<?> type;

  public A getA() {
    return MapperRunner.getA(type());
  }

  public boolean insert(T o) {
    this.type = o.getClass();
    return getA().insertSelective(o) > 0;
  }

  public T byId(I idInterface, Class c) {
    this.type = c;
    return (T) getA().selectByPrimaryKey(idInterface.id());
  }

  public boolean del(I id, Class c) {
    this.type = c;
    return getA().deleteByPrimaryKey(id.id()) > 0;
  }

  public boolean update(T t) {
    this.type = t.getClass();
    return getA().updateByPrimaryKeySelective(t) > 0;
  }

  public Class type() {
    return this.type;
  }
}


@Service("crudTemplateImpl")
public class CrudTemplateForMysql<T, I extends IdInterface>
    extends CommonDbOperation<T, I>
    implements CrudTemplate<T, I> {

  Class<?> type;

  @Override
  public Class type() {
    return this.type;
  }

  @Override
  public boolean insert(T t) {
    type = t.getClass();
    return super.insert(t);
  }

  @Override
  public T byId(I i, Class c) {
    this.type = c;
    return super.byId(i, c);
  }

  @Override
  public boolean del(I i, Class c) {

    return super.del(i, c);
  }

  @Override
  public boolean editor(I i, T t) {
    return super.update(t);
  }


}
  • redis 和 数据库操作的整合
  • 在操作 redis 的时候还需要一个 key . 在这里使用了一个枚举进行获取
public enum CacheTable {
  PROJECT_STR("project_str", ProjectStr.class),
  PROJECT_INT("test:redis:project:int", ProjectInt.class),
  ;
  private final String key;
  private Class<?> clazz;

  CacheTable(String key, Class clazz) {
    this.key = key;
    this.clazz = clazz;
  }

  CacheTable(String key) {
    this.key = key;
  }

  public static String key(Class clazz) {
    String res = null;
    for (CacheTable value : CacheTable.values()) {
      if (value.clazz.equals(clazz)) {
        res = value.key;

      }
    }
    return res;
  }

  public String getKey() {
    return key;
  }
}
  • 关于 redis 操作的确认

    1. 如果存在 key 值就会进行redis操作,
  • 这里使用hash进行操作, field 的值使用实体对象的id进行设置.
@Service("crudHashTemplate")
public class CrudHashTemplate<T extends BaseEntity, I extends IdInterface>
    extends CrudTemplateForMysql<T, I>
    implements CrudTemplate<T, I> {


  Gson gson = new Gson();
  @Autowired
  private StringRedisTemplate redisTemplate;


  @Override
  public boolean insert(T t) {

    boolean insert = super.insert(t);
    if (insert) {
      this.insert(String.valueOf(t.getId()), t);
    }
    return insert;
  }

  @Override
  public T byId(I i, Class c) {
    this.type = c;
    T tre = this.byIdForRedis(String.valueOf(i.id()));
    if (tre != null) {
      return tre;
    }
    else {
      return super.byId(i, c);
    }
  }

  @Override
  public boolean del(I i, Class c) {
    this.type = c;
    boolean del = super.del(i, c);
    this.delete(String.valueOf(i.id()));
    return del;
  }

  @Override
  public boolean editor(I i, T t) {
    this.type = t.getClass();

    this.delete(String.valueOf(i.id()));

    boolean editor = super.editor(i, t);

    if (editor) {

      this.insert(String.valueOf(i.id()), t);
    }

    return editor;
  }


  private void insert(String id, T t) {
    String key = key();
    if (StringUtils.isEmpty(key)) {
      return;
    }

    redisTemplate.opsForHash().put(key, id, gson.toJson(t));
  }

  private T byIdForRedis(String id) {
    String key = key();
    if (StringUtils.isEmpty(key)) {
      return null;
    }

    String o = (String) redisTemplate.opsForHash().get(key(), id);
    return (T) gson.fromJson(o, type());
  }

  private void delete(String id) {
    String key = key();
    if (StringUtils.isEmpty(key)) {
      return;
    }
    this.redisTemplate.opsForHash().delete(key(), id);
  }


  public String key() {
    return CacheTable.key(type());
  }

  @Override
  public Class type() {
    return super.type();
  }
}
  • 详细测试就请读者自行实现咯.
  • 相关代码详见: crud

huifer
483 声望4 粉丝