共计 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);
}
-
泛型解释:
- Id: 主键的数据类型
- 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 操作的确认
- 如果存在 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
正文完