Case:
1. Using Ali's open source database synchronization tool - canal to parse different database tables binlog logs, parse the completed data, we need to enter different databases, different tables.
2. Each table corresponds to a Mapper class and inserts different tables. We need to select different Mappers to perform the same function: insertSelective
3. Ordinary way of completion, we need to use "if" condition to judge according to different table names and choose different Mapper. Such code is redundant.
How to use custom annotations?
1. Define an interface: IProcessor
package com.jane.binlog.dao; public interface IProcessor<T> { int insertSelective(T record); int updateSelective(T record); }
2. Define a note: Processor Mapper
package com.jane.binlog.dao; import java.lang.annotation.*; @Target({ ElementType.METHOD, ElementType.TYPE }) @Retention(RetentionPolicy.RUNTIME) @Inherited public @interface ProcessorMapper { String value() default ""; }
3. Add comments for each Mapper: @Processor Mapper
1. The value of the annotation is the name of the table.
2. Mapper implements the interface IProcessor, passing in the type of operation object
import java.util.Date; @Repository @ProcessorMapper("pos_sale") public interface PosSaleMapper extends IProcessor<PosSale> { int insert(PosSale record); }
4. Call file
package com.jane.binlog.service; import com.alibaba.fastjson.JSONObject; import com.jane.binlog.dao.IProcessor; import com.jane.binlog.dao.ProcessorMapper; import com.jane.binlog.entity.PosSale; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.stereotype.Service; import javax.annotation.PostConstruct; import java.util.HashMap; import java.util.Map; @Service public class PosSaleService { private static Logger LOG = LoggerFactory.getLogger(PosSaleService.class); public static Map<String, Class> map = new HashMap<>(); //Define the relationship between tables and objects static { map.put("pos_sale", PosSale.class); } private Map<String, IProcessor> mapperMap = new HashMap<String, IProcessor>(); @Autowired private ApplicationContext applicationContext; //With spring context, all mapper s with custom annotations are injected into a hashmap. @PostConstruct public void init() { String[] classNames = applicationContext.getBeanNamesForAnnotation(ProcessorMapper.class); for (String name: classNames) { Class<?> type = applicationContext.getType(name); boolean posSaleMapper = type.isAnnotationPresent(ProcessorMapper.class); if (posSaleMapper) { String value = type.getAnnotation(ProcessorMapper.class).value(); mapperMap.put(value, (IProcessor) applicationContext.getBean(name)); } } } /** * Data write operation * @param table * @param data * @param op */ public void binlogInsert(String table, Map<String, Object> data, String op) { try { //Get the object class corresponding to the table Class clazz = map.get(table); //Assemble object data Object obj = this.assumePosSale(data, clazz); //Implementing Write Operations IProcessor processor = mapperMap.get(table); processor.insertSelective(obj); } catch(Exception e) { throw e; } } /** * Converting data map into corresponding table objects * @param data * @param clazz * @return */ private Object assumePosSale(Map<String, Object> data, Class clazz) { return JSONObject.parseObject(JSONObject.toJSONString(data), clazz); } }