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
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。