• Java纯POJO类反射到Redis,反射到MySQL


    这个是类定义,都是POJO类,纯数据

    以下代码将POJO类反射到REDIS中,采用JSON序列化类数据。

        public static <T> T save(T model, String indexName) throws Exception {
            String modelName = model.getClass().getSimpleName();
            Jedis jedis = jPool().getResource();
            Long id = null;
            try {
                id = (Long) PropertyUtils.getSimpleProperty(model, "id");
                if (null == id) {
                    // Key = "User:id"
                    id = getModelIdValueNext(jedis, modelName);
                    //TODO: Will must check this id data is not exists
                    PropertyUtils.setSimpleProperty(model, "id", id);
                    //insert id to all list, we can list all id's for get all
                    jedis.sadd(modelName+":all", id.toString());
                }
                //convert object to json string
                String valueJson = PojoMapper.toJson(model, false);
                //save data to redis
                jedis.set(modelName+":"+id, valueJson);
                //check if index
                if(null != indexName)
                {
                    //Key: User:name mapKey:hujianjun@baolemon.com mapValue:1002, will use name value to index id
                    Object indexValue = PropertyUtils.getSimpleProperty(model, indexName);
                    if (null != indexValue)
                        jedis.hset(modelName+":"+indexName, indexValue.toString(), id.toString());
                }
                //notify Database to update this change to DB
                appendToUpdateList(jedis, model.getClass(), "U", id);
                
            } catch (Exception e) {
                e.printStackTrace();
                throw e;
            }
            finally {
                jPool().returnResource(jedis);
            }
            return model;
        }

    以下代码将数据从Redis中读取出来,再反射写入到DB(后台线程做)

    1、读取数据,并调用jdbc来写入

    public class DbWriterTimerTask extends TimerTask {
        private static final Logger LOG = LoggerFactory.getLogger(DbWriterTimerTask.class);
        public static boolean isRunning = false;
    
        @Override
        public void run() {
            if (!isRunning) { 
                isRunning = true;
                Date begin = new Date();
                LOG.info("DbWriterTimerTask begin at {} ...", begin);
                executeTask();
                isRunning = false;
                Date end = new Date();
                LOG.info("DbWriterTimerTask finish at {}, till for {} millseconds.", end, (end.getTime() -begin.getTime()));
            }
            else {
                LOG.error("DbWriterTimerTask is executing now ...");
            }
        }
        
        public void executeTask() {
            int total=0;
            int inserted=0;
            int updated=0;
            int duplicated=0;
            int errored=0;
            Set<String> setModels = new HashSet<String>();
            
            try {
                //Thread.sleep(3000);
                long doCount = Configure.getPropertyLong("dbWriter.docount", 20); 
                int timeExpire = Configure.getPropertyInt("dbWriter.timeexpire", 60*60);
                List<DbUpdateItem> list = RedisDAO.retrieveUpdateList(doCount);
                if(list==null)
                    return;
                total = list.size();
                while (list.size() > 0) {
                    DbUpdateItem item = list.remove(0);
                    try {
                        //save ids firstly
                        if(!setModels.contains(item.m)) {
                            if(writeBackIdValueFromModel(item.m))
                                setModels.add(item.m);
                        }
                        //find item from redis
                        //找到class的类定义
                        Class<?> clazz = MySqlDAO.simpleDb().getClassByName(item.m);
                        //从Redis加载类实体数据,不同的对象,加载方式会不同,因为有些对象是类自己控制序列化
                        Object object=null;
                        if(clazz.getSimpleName().equals("CharaValues")) {
                            object = CharaValues.find(item.id);
                        }else if(clazz.getSimpleName().equals("CharaBox")) {
                            object = CharaBox.find(item.id);
                        }else if(clazz.getSimpleName().equals("CharaTask")) {
                            object = CharaTask.find(item.id);
                        }
                        else {
                            object = RedisDAO.find(clazz, item.id);
                        }
                        //save to db
                        if(object==null) {
                            LOG.error("can not find {} with {}.", item.m, item.id);
                            errored++;
                        } else {
                            //find it in db
                            Object o = MySqlDAO.simpleDb().getById(clazz, item.id);
                            if(o==null) {
                                MySqlDAO.simpleDb().create(object);
                                inserted++;
                            }else {
                                MySqlDAO.simpleDb().updateEntity(object);
                                updated++;
                            }
                        }
                        //设置过期标志
                        RedisDAO.expireObject(item.m, item.id.longValue(), timeExpire);
                    }
                    catch(Exception e) {
                        LOG.error("writeDb error.", e);
                    }
                    finally {
                        //find all same object and pop it
                        Iterator<DbUpdateItem> iter = list.iterator();
                        while(iter.hasNext()) {
                            DbUpdateItem it = iter.next();
                            //if(it.m.equals(item.m) && it.o.equals(item.o) && it.id.equals(item.id)) {
                            if(it.m.equals(item.m) && it.id.equals(item.id)) {
                                iter.remove();    //pop it
                                duplicated++;
                            }
                        }
                    }
                }
                LOG.info("Total {} been processed, Inserted {} records, Updated {} records, skip duplicated {} records, errrors {} records.", total, inserted, updated, duplicated, errored);
            }
            catch(Exception e) {
                LOG.error("executeTask error.", e);
            }
            return ;
        }
        
        public boolean writeBackIdValueFromModel(String modelName) {
            boolean result = false;
            Jedis jedis = RedisDAO.getResource();
            try {
                String idString = jedis.get(modelName+":id");
                if(idString==null)
                    return true;
                Long idValue = Long.parseLong(idString);
                result = writeBackIdValue(modelName, idValue);
            }
            catch(Exception e) {
                LOG.error("writeBackIdValueFromModel error.", e);
            }
            finally {
                RedisDAO.returnResource(jedis);
            }
            return result;
        }
        
        public boolean writeBackIdValue(String modelName, Long idValue) {
            String sqlCount = "select count(*) from sangame_ids where model=?";
            String sqlInsert = "insert sangame_ids(model, idvalue, time_insert) values(?, ?, CURRENT_TIMESTAMP)";
            String sqlUpdate = "update sangame_ids set idvalue=? where model=? and idvalue<?";
            if(MySqlDAO.simpleDb().queryForLong(sqlCount, modelName) > 0) {
                MySqlDAO.simpleDb().executeUpdate(sqlUpdate, idValue, modelName, idValue);
            }else{
                MySqlDAO.simpleDb().executeUpdate(sqlInsert, modelName, idValue);
                LOG.info("Initial ids fro model {} with {}.", modelName, idValue);;
            }
            return true;
        }
    }

    2、反射写入DB的核心代码

        String SQL_INSERT = null;
        String[] INSERT_PROPERTIES = null;
    
        SQLOperation insertEntity(Object entity) throws Exception {
            if (SQL_INSERT==null) {
                StringBuilder sb = new StringBuilder(128);
                sb.append("insert into ").append(this.tableName).append(" (");
                String[] properties = this.mappings.keySet().toArray(new String[0]);
                //Arrays.sort(properties);
                List<String> insertableProperties = new LinkedList<String>();
                for (String property : properties) {
                    PropertyMapping pm = mappings.get(property);
                    if (pm.insertable) {
                        insertableProperties.add(property);
                        sb.append(pm.columnName).append(',');
                    }
                }
                //append fixed column 
                sb.append("time_insert,");
                // set last ',' to ')':
                sb.setCharAt(sb.length()-1, ')');
                sb.append(" values (");
                for (int i=0; i<insertableProperties.size(); i++) {
                    sb.append("?,");
                }
                //append fixed column time_insert
                sb.append("CURRENT_TIMESTAMP,");
                // set last ',' to ')':
                sb.setCharAt(sb.length()-1, ')');
                SQL_INSERT = sb.toString();
                INSERT_PROPERTIES = insertableProperties.toArray(new String[insertableProperties.size()]);
            }
            Object[] params = new Object[INSERT_PROPERTIES.length];
            for (int i=0; i<INSERT_PROPERTIES.length; i++) {
                params[i] = mappings.get(INSERT_PROPERTIES[i]).get(entity);
            }
            return new SQLOperation(SQL_INSERT, params);
        }
    class PropertyMapping {
    
        final String property;
        final Field field;
        final boolean insertable;
        final boolean updatable;
        final String columnName;
        final String columnDefinition;
        final boolean nullable;
        final boolean id;
        final Method getter;
        final Method setter;
        @SuppressWarnings("rawtypes")
        final Class enumClass;
    
    //    public PropertyMapping(Method getter, Method setter) {
    //        this.field = null;
    //        this.property = Utils.getGetterName(getter);
    //        this.getter = getter;
    //        this.setter = setter;
    //        this.enumClass = getter.getReturnType().isEnum() ? getter.getReturnType() : null;
    //        Column column = getter.getAnnotation(Column.class);
    //        this.insertable = column==null ? true : column.insertable();
    //        this.updatable = column==null ? true : column.updatable();
    //        this.columnName = column==null ? Utils.getGetterName(getter) : ("".equals(column.name()) ? Utils.getGetterName(getter) : column.name());
    //        this.columnDefinition = column==null ? "" : column.columnDefinition();
    //        this.nullable = column==null ? true : column.nullable();
    //        this.id = getter.isAnnotationPresent(Id.class);
    //    }
        
        public PropertyMapping(Field field, Method getter, Method setter) {
            this.field = field;
            this.getter = getter;
            this.setter = setter;
            this.enumClass = field.getType().isEnum() ? field.getType() : null;
            Column column = field.getAnnotation(Column.class);
            this.insertable = column==null ? true : column.insertable();
            this.updatable = column==null ? true : column.updatable();
            this.columnName = column==null ? field.getName() : ("".equals(column.name()) ? field.getName() : column.name());
            this.columnDefinition = column==null ? Utils.getColumnDefinition(field.getType()) : column.columnDefinition().isEmpty()?Utils.getColumnDefinition(field.getType()):column.columnDefinition(); 
            this.nullable = column==null ? true : column.nullable();
            this.id = field.isAnnotationPresent(Id.class);
            this.property = field.getName();
        }
    
        @SuppressWarnings("unchecked")
        Object get(Object target) throws Exception {
            Object r;
            if(getter==null) {
                r = field.get(target);
            } else {
                r = getter.invoke(target);
            }
            
            if(enumClass!=null)
                r = Enum.valueOf(enumClass, (String) r);
            else if(!Utils.isSupportedSQLObject(field.getType())) {
                r = PojoMapper.toJson(r, false);
            }
            return r;
        }
    
        @SuppressWarnings("unchecked")
        void set(Object target, Object value) throws Exception {
            if (enumClass!=null && value!=null) {
                value = Enum.valueOf(enumClass, (String) value);
            } else if(!Utils.isSupportedSQLObject(field.getType())) {
                value = PojoMapper.fromJson(value.toString(), field.getType());
                //value = PojoMapper.fromJson(value.toString(), field.getDeclaringClass());
            }
            
            if(setter==null) {
                field.set(target, value);
            } else {
                setter.invoke(target, value);
            }
        }
    }
        /**
         * Create an entity in database, writing all insertable properties.
         * 
         * @param entity Entity object instance.
         */
        public void create(Object entity) {
            EntityOperation<?> op = getEntityOperation(entity.getClass());
            SQLOperation sqlo = null;
            try {
                sqlo = op.insertEntity(entity);
            }
            catch (Exception e) {
                throw new RuntimeException(e);
            }
            jdbcTemplate.update(sqlo.sql, sqlo.params);
        }

  • 相关阅读:
    IList扩展
    WPF 路由事件
    WPF 属性值绑定、转换
    WPF 生命周期
    App.config 动态编辑
    Oracle Package的全局变量与Session
    AES对数据进行加密与解密
    OracleAES加密
    AES加解密程序的实现
    Oracle的AES加密与解密用法
  • 原文地址:https://www.cnblogs.com/jdragonhu/p/2876875.html
Copyright © 2020-2023  润新知