Custom Annotation + Policy Mode to write different tables!

Keywords: Programming Java Database Spring

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);
    }

}

Posted by besbajah on Wed, 09 Oct 2019 11:43:32 -0700