boolean insert(Object o); Object byId(Integer id); boolean del(Integer id); boolean editor(Integer interfaces, Object o;
一般咱們的建立流程是這樣子的.java
boolean b = mapper.save(s) if (b){ redis.save(s) }
一般操做git
Object o =null o = redis.read(id) if (o ==null) { o = mapper.read(id) }
一般操做github
redis.del() mapper.update(o) redis.save(o)
一般操做redis
redis.del() mapper.del(o)
在抽象 crud 基本操做前須要在提出一個問題.sql
IdInterface
它用來標識這是一個 id 接口public interface IdInterface { }
根據經常使用 int 和 varchar 設計出以下兩個子接口. 他們的做用會在後續獲得進一步的體現. 當前階段僅須要知道他們是 id 接口的繼承便可.數據庫
id()
用來返回具體的 id 值public interface IntIdInterface extends IdInterface { int id(); } public interface StrIdInterface extends IdInterface { String id(); }
public interface DbOperation<T, I extends IdInterface> { boolean insert(T t); T byId(I interfaces); boolean del(I interfaces); boolean editor(I interfaces, T t); }
T
來標識接受的類型, I 來標識接收的接口, 這裏存在2中狀況. 第一種 I = IntIdInterface , 第二種 I = StrIdInterfacepublic interface RedisOperation<T, I extends IdInterface> { void insert(T t); void update(I i, T t); void del(I i); T byId(I i); }
public abstract class RedisHashKeyOperation<T> { Gson gson = new Gson(); @Autowired private StringRedisTemplate redisTemplate; protected void update(String key, String id, T t) { T redisObj = this.byId(key, id, t.getClass()); if (!Objects.isNull(redisObj)) { // 若是是redis中的類型和當前傳入的類型相同 if (redisObj.getClass().equals(t.getClass())) { this.insert(key, id, t); } } } protected void insert(String key, String id, T t) { redisTemplate.opsForHash().put(key, id, gson.toJson(t)); } protected T byId(String key, String id, Class<?> clazz) { String o = (String) redisTemplate.opsForHash().get(key, id); return (T) gson.fromJson(o, clazz); } protected void delete(String key, String id) { this.redisTemplate.opsForHash().delete(key, id); } }
CREATE TABLE `project_int` ( `id` int(32) NOT NULL AUTO_INCREMENT, `name` varchar(20) COLLATE utf8mb4_bin DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin; CREATE TABLE `project_str` ( `id` varchar(50) COLLATE utf8mb4_bin NOT NULL, `name` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
@Service("ProjectIntDbOperationImpl") public class ProjectIntDbOperationImpl implements DbOperation<ProjectInt, IntIdInterface> { @Autowired private ProjectIntMapper projectIntMapper; @Override public boolean insert(ProjectInt projectInt) { return projectIntMapper.insert(projectInt) > 0; } @Override public ProjectInt byId(IntIdInterface interfaces) { return projectIntMapper.selectByPrimaryKey(interfaces.id()); } @Override public boolean del(IntIdInterface interfaces) { return projectIntMapper.deleteByPrimaryKey(interfaces.id()) > 0; } @Override public boolean editor(IntIdInterface interfaces, ProjectInt projectInt) { // 更新存在策略 ProjectInt projectInt1 = this.byId(interfaces); projectInt1.setName(projectInt.getName()); return this.projectIntMapper.updateByPrimaryKey(projectInt1) > 0; } } @Service("ProjectIntRedisOperationImpl") public class ProjectIntRedisOperationImpl extends RedisHashKeyOperation<ProjectInt> implements RedisOperation<ProjectInt, IntIdInterface> { public static final String CACHE_PROJECT_INT = "cache:project_int"; public void insert(ProjectInt projectInt) { super.insert(CACHE_PROJECT_INT, String.valueOf(projectInt.getId()), projectInt); } public void update(IntIdInterface strIdInterface, ProjectInt projectInt) { super.update(CACHE_PROJECT_INT, String.valueOf(strIdInterface.id()), projectInt); } public void del(IntIdInterface strIdInterface) { super.delete(CACHE_PROJECT_INT, String.valueOf(strIdInterface.id())); } public ProjectInt byId(IntIdInterface intIdInterface) { return super.byId(CACHE_PROJECT_INT, String.valueOf(intIdInterface.id()), ProjectInt.class); } }
@Service("ProjectStrDbOperationImpl") public class ProjectStrDbOperationImpl implements DbOperation<ProjectStr, StrIdInterface> { @Autowired private ProjectStrMapper projectStrMapper; @Override public boolean insert(ProjectStr projectInt) { return projectStrMapper.insert(projectInt) > 0; } @Override public ProjectStr byId(StrIdInterface interfaces) { return projectStrMapper.selectByPrimaryKey(interfaces.id()); } @Override public boolean del(StrIdInterface interfaces) { return projectStrMapper.deleteByPrimaryKey(interfaces.id()) > 0; } @Override public boolean editor(StrIdInterface interfaces, ProjectStr projectInt) { // 更新存在策略 ProjectStr projectInt1 = this.byId(interfaces); projectInt1.setName(projectInt.getName()); return this.projectStrMapper.updateByPrimaryKey(projectInt1) > 0; } } @Service("ProjectStrRedisOperationImpl") public class ProjectStrRedisOperationImpl extends RedisHashKeyOperation<ProjectStr> implements RedisOperation<ProjectStr, StrIdInterface> { public static final String CACHE_PROJECT_INT = "cache:project_int"; public void insert(ProjectStr projectStr) { super.insert(CACHE_PROJECT_INT, String.valueOf(projectStr.getId()), projectStr); } public void update(StrIdInterface strIdInterface, ProjectStr projectStr) { super.update(CACHE_PROJECT_INT, String.valueOf(strIdInterface.id()), projectStr); } public void del(StrIdInterface strIdInterface) { super.delete(CACHE_PROJECT_INT, String.valueOf(strIdInterface.id())); } public ProjectStr byId(StrIdInterface intIdInterface) { return super.byId(CACHE_PROJECT_INT, String.valueOf(intIdInterface.id()), ProjectStr.class); } }
public interface ByIdOperationFacade<T, I extends IdInterface> { boolean insert(T t); T byId(I i); boolean del(I i); boolean editor(I i, T t); DbOperation getDbOperation(); }
public class OperationCollections { private DbOperation dbOperation; private RedisOperation redisOperation; }
public interface ByIdOperationFactory { OperationCollections factory(Class<?> clazz); }
實現以下. 注意:此處爲了讓泛型更好的使用, 這裏採用的是類型對應一個操做對象(DbOperation,RedisOperation).設計模式
DbOperation
和 RedisOperation
添加一個函數用來獲取類型@Service("ByIdOperationFactoryImpl") public class ByIdOperationFactoryImpl implements ByIdOperationFactory { static Map<Class, DbOperation> dbOperationMap = new HashMap<>(); static Map<Class, RedisOperation> redisOperationHashMap = new HashMap<>(); @Autowired private ApplicationContext context; @PostConstruct public void init() { Map<String, DbOperation> beansOfType = context.getBeansOfType(DbOperation.class); beansOfType.forEach( (k, v) -> { Class type = v.type(); dbOperationMap.put(type, v); } ); Map<String, RedisOperation> beansOfType1 = context.getBeansOfType(RedisOperation.class); beansOfType1.forEach((k, v) -> { Class type = v.type(); redisOperationHashMap.put(type, v); }); } @Override public OperationCollections factory(Class<?> clazz) { OperationCollections operationCollections = new OperationCollections(); DbOperation dbOperation = dbOperationMap.get(clazz); RedisOperation redisOperation = redisOperationHashMap.get(clazz); operationCollections.setDbOperation(dbOperation); operationCollections.setRedisOperation(redisOperation); return operationCollections; } }
public abstract class CommonByIdOperation<T, I extends IdInterface> implements ByIdOperationFacade<T, I> { @Autowired @Qualifier("ByIdOperationFactoryImpl") ByIdOperationFactory byIdOperationFactory; @Override public boolean insert(T t) { throw new RuntimeException("沒有實現"); } @Override public DbOperation getDbOperation() { throw new RuntimeException("沒有實現"); } public boolean editor(I i, T t) { boolean editor = false; OperationCollections operationCollections = this.operationCollection(); RedisOperation redisOperation = operationCollections.getRedisOperation(); if (redisOperation != null) { redisOperation.del(i); } DbOperation dbOperation = operationCollections.getDbOperation(); if (dbOperation != null) { editor = dbOperation.editor(i, t); } if (redisOperation != null) { redisOperation.insert(t); } return editor; } public boolean del(I i) { boolean del = false; OperationCollections operationCollections = this.operationCollection(); RedisOperation redisOperation = operationCollections.getRedisOperation(); if (redisOperation != null) { redisOperation.del(i); } DbOperation dbOperation = operationCollections.getDbOperation(); if (dbOperation != null) { del = dbOperation.del(i); } return del; } public T byId(I i) { T result = null; RedisOperation redisOperation = this.operationCollection().getRedisOperation(); if (redisOperation != null) { result = (T) redisOperation.byId(i); } DbOperation dbOperation = this.operationCollection().getDbOperation(); if (dbOperation != null) { if (result == null) { System.out.println("從數據庫獲取"); result = (T) dbOperation.byId(i); } } return result; } public OperationCollections operationCollection() { return byIdOperationFactory.factory(clazz()); } protected Class<?> clazz() { throw new IllegalArgumentException("類型異常"); } }
public class BeanCopy { public static void main(String[] args) { StrId strId = new StrId(); strId.setId("str_id"); CpId cpId = new CpId(); BeanUtils.copyProperties(strId, cpId); System.out.println(cpId.getId()); } @Data static class CpId { private Object id; } @Data static class StrId { private String id; } }
@Service("ProjectIntDbOperationImpl") public class ProjectIntDbOperationImpl implements DbOperation<ProjectInt, IntIdInterface> { @Autowired private ProjectIntMapper projectIntMapper; @Override public boolean insert(ProjectInt projectInt) { return projectIntMapper.insert(projectInt) > 0; } @Override public ProjectInt byId(IntIdInterface interfaces) { return projectIntMapper.selectByPrimaryKey(interfaces.id()); } @Override public boolean del(IntIdInterface interfaces) { return projectIntMapper.deleteByPrimaryKey(interfaces.id()) > 0; } @Override public boolean editor(IntIdInterface interfaces, ProjectInt projectInt) { // 更新存在策略 ProjectInt projectInt1 = this.byId(interfaces); projectInt1.setName(projectInt.getName()); return this.projectIntMapper.updateByPrimaryKey(projectInt1) > 0; } @Override public Class<?> type() { return ProjectInt.class; } }
@Service("ProjectStrFacade") public class ProjectStrFacade extends CommonByIdOperation<ProjectStr, StrIdInterface> implements ByIdOperationFacade<ProjectStr, StrIdInterface> { @Override public boolean insert(ProjectStr projectInt) { DbOperation dbOperation = this.getDbOperation(); boolean insert = false; if (dbOperation != null) { insert = dbOperation.insert(projectInt); } RedisOperation redisOperation = this.operationCollection().getRedisOperation(); if (redisOperation != null) { redisOperation.insert(projectInt); } return insert; } @Override public ProjectStr byId(StrIdInterface strIdInterface) { return super.byId(strIdInterface); } @Override public boolean del(StrIdInterface strIdInterface) { return super.del(strIdInterface); } public boolean editor(StrIdInterface strIdInterface, ProjectStr projectInt) { return super.editor(strIdInterface, projectInt); } @Override public DbOperation getDbOperation() { return this.operationCollection().getDbOperation(); } @Override protected Class<?> clazz() { return ProjectStr.class; } }
@SpringBootTest class DemoApplicationTests { Gson gson = new Gson(); @Autowired private ProjectStrMapper projectStrMapper; @Autowired @Qualifier("projectIntFacade") private ByIdOperationFacade<ProjectInt, IntIdInterface> byIdOperationFacade; @Autowired private StringRedisTemplate stringRedisTemplate; @Test void testInsert() { ProjectInt projectInt = new ProjectInt(); projectInt.setName("JJJ"); this.byIdOperationFacade.insert(projectInt); } @Test void testUpdate() { ProjectInt projectInt = this.byIdOperationFacade.byId(new IntIdInterface() { @Override public int id() { return 1; } }); projectInt.setName("update"); this.byIdOperationFacade.editor(new IntIdInterface() { @Override public int id() { return projectInt.getId(); } }, projectInt); } @Test void testDel() { this.byIdOperationFacade.del(new IntIdInterface() { @Override public int id() { return 1; } }); } @Test void testById() { ProjectInt projectInt = this.byIdOperationFacade.byId(new IntIdInterface() { @Override public int id() { return 1; } }); System.out.println(); } }
@Autowired @Qualifier("projectIntFacade") private ByIdOperationFacade<ProjectInt, IntIdInterface> byIdOperationFacade;
本文使用了緩存