关于java:从-crud-认识设计模式-模板模式

49次阅读

共计 4727 个字符,预计需要花费 12 分钟才能阅读完成。

CRUD template

  • 在浏览该文章之前请浏览:从 crud 意识设计模式

接口形象

  • 单表的 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

正文完
 0