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);}
泛型解释:
- Id: 主键的数据类型
- T: 数据库实体
- 接入一个mapper
@Mapperpublic 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对象
@Servicepublic 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的操作
- 实现形式为从
@Servicepublic 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 操作的确认
- 如果存在 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