package com.jqmobile.core.server.db.orm; import java.lang.reflect.Field; import java.math.BigInteger; import java.sql.ResultSet; import java.util.Collection; import java.util.HashMap; import java.util.Map; import java.util.UUID; import com.jqmobile.core.orm.DBColumn; import com.jqmobile.core.orm.RsAccessor; import com.jqmobile.core.orm.exception.ORMNotDBColumnException; import com.jqmobile.core.orm.exception.ORMParamNotRecognitionException; import com.jqmobile.core.utils.plain.GUIDUtils; import com.jqmobile.core.utils.plain.UUIDUtils; public class BaseDBColumn { private final Field field; private DBColumn dbLable; private final static Map<Field, BaseDBColumn> map = new HashMap<Field, BaseDBColumn>(); public static BaseDBColumn getInstance(Field f) { synchronized (map) { if(!map.containsKey(f)){ map.put(f, new BaseDBColumn(f)); } } return map.get(f); } public BaseDBColumn(Field f){ this.field = f; this.dbLable = f.getAnnotation(DBColumn.class); } public Field getField() { return field; } public boolean isCascadeAll(){ return null==dbLable||dbLable.cascadeAll(); } public boolean isCascadeDelete(){ if(!isCascadeAll()){ return false; } return null==dbLable||dbLable.cascadeDelete(); } public boolean isCascadeFind(){ if(!isCascadeAll()){ return false; } return null==dbLable||dbLable.cascadeFind(); } public boolean isCascadeInsert(){ if(!isCascadeAll()){ return false; } return null==dbLable||dbLable.cascadeInsert(); } public boolean isCascadeUpdate(){ if(!isCascadeAll()){ return false; } return null==dbLable||dbLable.cascadeUpdate(); } public boolean isMapping(){ if(!isCascadeAll()){ return false; } return null == dbLable || dbLable.mapping(); } public String getColumnName(){ valiColumn(); String fieldType=field.getType().toString(); String[] temp=fieldType.split(" "); if(temp.length>1){ if(!temp[1].startsWith("java")||Collection.class.isAssignableFrom(field.getType())) return ""; } if(null == dbLable || DBColumn.DefaultValue.equals(dbLable.name())) return field.getName(); return dbLable.name(); } public DBColumn getDBColumn(){ return dbLable; } public boolean isPaimaryId() { valiColumn(); return null != dbLable && dbLable.primaryId(); } public String getColumnType() { valiColumn(); //主键或者id为二进制 if(null != dbLable && (dbLable.primaryId() || dbLable.id())){ return "binary(16)"; }else if(null == dbLable || DBColumn.DefaultValue.equals(dbLable.type())){ Class<?> fieldType = field.getType(); if (isIn(fieldType.getName(),"java.lang.Long","long")&&field.getAnnotation(DBColumn.class)!=null&&field.getAnnotation(DBColumn.class).date()) { return "timestamp"; }else if(isIn(fieldType.getName(),"java.lang.Long","long")){ return "bigint(20)"; } else if (isIn(fieldType.getName(),"java.lang.Double","double")) { return "decimal(17,5)"; } else if (isIn(fieldType.getName(),"java.lang.Integer","int")) { return "int"; } else if (isIn(fieldType.getName(),"java.lang.Float","float")) { return "float"; }else if(isIn(fieldType.getName(), "java.util.Date","Date")){ return "timestamp"; } else if(isIn(fieldType.getName(), "java.sql.Date","Date")){ return "timestamp"; }else { int length = null==dbLable?DBColumn.DefaultLength:dbLable.length(); if (isIn(fieldType.getName(),"java.lang.Byte","byte")) { return "binary("+length+")"; } else if (isIn(fieldType.getName(),"java.lang.Short", "short")) { return "smallint"; } else if (isIn(fieldType.getName(),"java.lang.Boolean", "boolean")) { return "boolean"; } else if (isIn(fieldType.getName(),"java.util.UUID")) { return "binary(16)"; } else if (isIn(fieldType.getName(),"java.lang.String")) { return "varchar("+length+")"; } else{ if(!String.class.isAssignableFrom(field.getType())&&!UUID.class.isAssignableFrom(field.getType())&&!field.getType().isPrimitive()){ return ""; } } } } return dbLable.type()+getColumnOther(field, dbLable, getColumnType(), getColumnName()); } private String getColumnOther(Field f, DBColumn lable, String columnType, String columnName) { String str; if(columnType.contains("varchar")){ str = "CHARACTER SET utf8 DEFAULT "+getColumnDefault(lable); }else if(columnName.toUpperCase().equals("RECID")){ str = "NOT NULL"; }else if(!lable.canNull()){ str = "NOT Null"; }else{ str = ""; } if(null != lable.comment() && !"".equals(lable.comment().trim())){ str = str + " COMMENT '"+ lable.comment()+"'"; } return str; } private static String getColumnDefault(DBColumn lable) { return "NULL"; } /** * * @param obj * @return 返回byte数组 */ @SuppressWarnings("deprecation") public Object getFormatObj(Object obj){ if(null == obj){ return null; } if(null != dbLable && (dbLable.primaryId() || dbLable.id())){ if(obj instanceof UUID){ return GUIDUtils.getBytes((UUID)obj); }else if(obj instanceof String){ return GUIDUtils.getBytes((String)obj); }else{ throw new ORMParamNotRecognitionException("guid类型:"+obj); } } return obj; } /** * 设置属性值 * @param obj 对象 * @param value 值 * @throws IllegalArgumentException * @throws IllegalAccessException */ public void set(Object obj, Object value) throws IllegalArgumentException, IllegalAccessException{ field.set(obj, value); } // private void valiColumn() throws ORMNotDBColumnException{ if(!isMapping()) throw new ORMNotDBColumnException(); } // @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((field == null) ? 0 : field.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; BaseDBColumn other = (BaseDBColumn) obj; if (field == null) { if (other.field != null) return false; } else if (!field.equals(other.field)) return false; return true; } /** * 从结果集中获取当前属性的值 * @param rs * @return */ public Object getValue(ResultSet rs) { return getFieldValue(this, rs); } private static Object getFieldValue(BaseDBColumn field, ResultSet rs) { Object obj = null; String name = field.getColumnName(); Class<?> fieldType = field.getField().getType(); DBColumn lable = field.getDBColumn(); if(null != lable && (lable.id() || lable.primaryId()) && isIn(fieldType.getName(),"java.lang.String")){ try { obj = UUIDUtils.getUUID(rs.getBytes(name)).toString(); } catch (Throwable e) { return null; } } else if (isIn(fieldType.getName(),"java.lang.Long","long")) { if(null != lable && field.getField().getAnnotation(DBColumn.class).date()){ try { obj = rs.getTimestamp(name).getTime(); } catch (Exception e) { obj = getLong(rs, obj, name, fieldType); } }else{ obj = getLong(rs, obj, name, fieldType); } } else if (isIn(fieldType.getName(),"java.lang.Double","double")) { try { obj = rs.getDouble(name); } catch (Throwable e) { if(fieldType.getName().equals("double")) obj = 0d; else return null; } } else if (isIn(fieldType.getName(),"java.lang.Integer","int")) { try { obj = rs.getInt(name); } catch (Throwable e) { if(fieldType.getName().equals("int")) obj = 0; else return null; } } else if (isIn(fieldType.getName(),"java.lang.Float","float")) { try { obj = rs.getFloat(name); } catch (Throwable e) { if(fieldType.getName().equals("float")) obj = 0f; else return null; } } else if (isIn(fieldType.getName(),"java.lang.Byte","byte")) { try { obj = rs.getByte(name); } catch (Throwable e) { return null; } } else if (isIn(fieldType.getName(),"java.lang.Short", "short")) { try { obj = rs.getShort(name); } catch (Throwable e) { if(fieldType.getName().equals("short")) obj = (short)0; else return null; } } else if (isIn(fieldType.getName(),"java.lang.Boolean", "boolean")) { try { obj = rs.getBoolean(name); } catch (Throwable e) { if(fieldType.getName().equals("boolean")) obj = false; else return null; } } else if (isIn(fieldType.getName(),"java.util.UUID")) { try { obj = UUIDUtils.getUUID(rs.getBytes(name)); } catch (Throwable e) { return null; } } else if (isIn(fieldType.getName(),"java.lang.String")) { try { obj = rs.getString(name); } catch (Throwable e) { return null; } }else if(fieldType.isArray() && isIn(fieldType.getName(), "[B", "[Ljava.lang.Byte;")){ try{ obj = rs.getBytes(name); }catch(Throwable e){ return null; } }else if(isIn(fieldType.getName(),"java.math.BigInteger")){ try { obj = new BigInteger(rs.getString(name)); } catch (Throwable e) { return null; } } else{ try { obj = rs.getObject(name); } catch (Throwable e) { obj = null; } } return obj; } private static Object getLong(ResultSet rs, Object obj, String name, Class<?> fieldType) { try { obj = rs.getLong(name); } catch (Throwable e) { if(fieldType.getName().equals("long")) obj = 0l; else return null; } return obj; } @SuppressWarnings("unused") private static Object getLong(RsAccessor rs, Object obj, int i, Class<?> fieldType) { try { obj = rs.getLong(i); } catch (Throwable e) { if(fieldType.getName().equals("long")) obj = 0l; else return null; } return obj; } public static boolean isIn(String str, String...ins){ for(String s : ins){ if(s.equals(str)){ return true; } } return false; } @Override public String toString() { return getColumnName(); } }