zoukankan      html  css  js  c++  java
  • 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);
        }

  • 相关阅读:
    【java】对象赋值给另一个对象
    spring boot系列(五)spring boot 配置spring data jpa (查询方法)
    Spring Data JPA 查询
    Spring Data JPA 介绍
    OpenID简介
    OAUTH协议介绍
    URL encoding(URL编码)
    RESTful 介绍
    spring boot系列(四)spring boot 配置spring data jpa (保存修改删除方法)
    spring boot 启动报 java.lang.NoClassDefFoundError: ch/qos/logback/core/spi/LifeCycle 错误
  • 原文地址:https://www.cnblogs.com/jdragonhu/p/2876875.html
Copyright © 2011-2022 走看看