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]);
//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);
}
Object[] params = new Object;
for (int i=0; i<INSERT_PROPERTIES.length; i++) {
params = mappings.get(INSERT_PROPERTIES).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);
}
页:
[1]