JFinal ORACLE 의 timestamp 필드 해결 방법

8053 단어 TimestampjFinal
JFinal 은 비교적 좋 은 프레임 워 크 이지 만 JFinal 기원 시 my sql 데이터 베 이 스 를 사용 하기 때문에 데이터 베 이 스 를 지원 하 는 데 완벽 하지 못 합 니 다.
저 는 JFinal 을 사용 한 지 오래 되 었 습 니 다.프로젝트 의 데이터 베 이 스 는 Oacle 을 보편적으로 사용 하기 때문에 Oacle 을 사용 하 는 과정 에서 불편 한 점(예 를 들 어 ORACLE 의 자동 생 성 메 인 키,Oacle 에서 timestamp 필드 는 Oacle.sql.timestamp 등)을 만 났 습 니 다.다행히@JFinal 등 사람들의 도움 으로 문 제 를 해결 하 였 습 니 다.이번 에는 Oacle 에서 timestamp 필드 를 해결 하고 Oacle.sql.timestamp 로 돌아 가 는 방법 을 말 합 니 다.
  Oacle 은 항상 남 다른 점 이 있 습 니 다.예 를 들 어 필드 는 기본적으로 지원 이 증가 하지 않 았 습 니 다.더 나 쁜 것 은 필드 반환 유형 이 다른 데이터 베이스 반환 유형 과 다 릅 니 다.예 를 들 어 timestamp 필드 는 우리 에 게 Oacle.sql.Timestamp 를 되 돌려 주 었 습 니 다.Oacle 자체 에 대해 서 는 평가 하지 않 습 니 다.
    예전 에 JFinal 은 하나의 작은 프로젝트 에 만 사용 되 었 고 기본적으로 저 는 개인 적 으로 유지 하고 있 었 기 때문에 timestamp 에 부 딪 혀 수 동 으로 전환 할 수 밖 에 없 었 습 니 다.그러나 현재 JFinal 은 큰 프로젝트 에 사 용 했 고 개발 자 들 도 저 뿐만 이 아 닙 니 다.처음에 JFinal 이라는 간단 하고 효율 적 인 프레임 워 크 를 좋아 했 지만 timestamp 를 수 동 으로 처리 해 야 할 때 JFinal 에 실망 하여 수 동 으로 전환 할 수 밖 에 없 었 습 니 다.JFinal 에 대한 여러분 의 신뢰 를 높이 기 위해 저 는 JFINAL 이 필드 에 대한 처리 과정 을 진지 하 게 연구 한 결과 다음 과 같은 결론 을 얻 었 습 니 다.
1、      JFinal 은 시작 할 때 등 록 된 Model 과 데이터베이스 에 대응 하 는 table 을 일일이 연결 합 니 다.연결 하 는 과정 은 주로 TableInfoBuilder.buildTableInfo()를 통 해 TableInfo 대상 을 만 듭 니 다.이 대상 은 다음 과 같 습 니 다.
private String tableName;
	private String primaryKey;
	private String secondaryKey = null;
	
	@SuppressWarnings("unchecked")
	private Map<String, Class<?>> columnTypeMap = DbKit.containerFactory.getAttrsMap();	//	new HashMap<String, Class<?>>();

사실 가장 핵심 적 인 것 은 이 columnTypeMap 대상 입 니 다.이 MAP 는 table 각 필드 의 이름과 유형 을 기록 하고 있 습 니 다. 추적 소스 코드 를 통 해 현재 JFinal 은 기본 값 으로 Oracle 의 timestamp 를 java.lang.String 형식 으로 변환 하고 TableInfo 를 만 드 는 방법 은 다음 과 같 습 니 다.
private static TableInfo doBuildTableInfo(TableInfo tableInfo,
	    Connection conn) throws SQLException {
	TableInfo result = tableInfo;

	String sql = DbKit.getDialect().forTableInfoBuilderDoBuildTableInfo(
		tableInfo.getTableName());
	Statement stm = conn.createStatement();
	ResultSet rs = stm.executeQuery(sql);
	ResultSetMetaData rsmd = rs.getMetaData();

	for (int i = 1; i <= rsmd.getColumnCount(); i++) {
	    String colName = rsmd.getColumnName(i);
	    String colClassName = rsmd.getColumnClassName(i);
	    if ("java.lang.String".equals(colClassName)) {
		// varchar, char, enum, set, text, tinytext, mediumtext,
		// longtext
		result.addInfo(colName, java.lang.String.class);
	    } else if ("java.lang.Integer".equals(colClassName)) {
		// int, integer, tinyint, smallint, mediumint
		result.addInfo(colName, java.lang.Integer.class);
	    } else if ("java.lang.Long".equals(colClassName)) {
		// bigint
		result.addInfo(colName, java.lang.Long.class);
	    } else if ("java.sql.Date".equals(colClassName)) {
		// date, year
		result.addInfo(colName, java.sql.Date.class);
	    } else if ("java.lang.Double".equals(colClassName)) {
		// real, double
		result.addInfo(colName, java.lang.Double.class);
	    } else if ("java.lang.Float".equals(colClassName)) {
		// float
		result.addInfo(colName, java.lang.Float.class);
	    } else if ("java.lang.Boolean".equals(colClassName)) {
		// bit
		result.addInfo(colName, java.lang.Boolean.class);
	    } else if ("java.sql.Time".equals(colClassName)) {
		// time
		result.addInfo(colName, java.sql.Time.class);
	    } else if ("java.sql.Timestamp".equals(colClassName)
		    || "oracle.sql.TIMESTAMP".equals(colClassName)) {
		// timestamp, datetime
		result.addInfo(colName, java.sql.Timestamp.class);
	    } else if ("java.math.BigDecimal".equals(colClassName)) {
		// decimal, numeric
		result.addInfo(colName, java.math.BigDecimal.class);
	    } else if ("[B".equals(colClassName)) {
		// binary, varbinary, tinyblob, blob, mediumblob, longblob
		// qjd project: print_info.content varbinary(61800);
		result.addInfo(colName, byte[].class);
	    } else {
		int type = rsmd.getColumnType(i);
		if (type == Types.BLOB) {
		    result.addInfo(colName, byte[].class);
		} else if (type == Types.CLOB || type == Types.NCLOB) {
		    result.addInfo(colName, String.class);
		} else {
		    result.addInfo(colName, String.class);
		}
		// core.TypeConverter
		// throw new RuntimeException("You've got new type to mapping.
		// Please add code in " + TableInfoBuilder.class.getName() + ".
		// The ColumnClassName can't be mapped: " + colClassName);
	    }
	}

	rs.close();
	stm.close();
	return result;
    }

2、      JFinal 이 Model 에 데 이 터 를 채 울 때 주로 ModelBuilder 를 실행 합 니 다.build(ResultSets,Classmodel Class)방법 은 다음 과 같 습 니 다.사실 이 과정 에서 JFinal 은 관여 하지 않 았 습 니 다(CLOB,NCLOB,BLOB 제외).데 이 터 는 JDBC 의 기본 방식 에 따라 되 돌 아 옵 니 다.
@SuppressWarnings({"rawtypes", "unchecked"})
	public static final <T> List<T> build(ResultSet rs, Class<? extends Model> modelClass) throws SQLException, InstantiationException, IllegalAccessException {
		List<T> result = new ArrayList<T>();
		ResultSetMetaData rsmd = rs.getMetaData();
		int columnCount = rsmd.getColumnCount();
		String[] labelNames = new String[columnCount + 1];
		int[] types = new int[columnCount + 1];
		buildLabelNamesAndTypes(rsmd, labelNames, types);
		while (rs.next()) {
			Model<?> ar = modelClass.newInstance();
			Map<String, Object> attrs = ar.getAttrs();
			for (int i=1; i<=columnCount; i++) {
				Object value;
				if (types[i] < Types.BLOB)
					value = rs.getObject(i);
				else if (types[i] == Types.CLOB)
					value = handleClob(rs.getClob(i));
				else if (types[i] == Types.NCLOB)
					value = handleClob(rs.getNClob(i));
				else if (types[i] == Types.BLOB)
					value = handleBlob(rs.getBlob(i));
				else
					value = rs.getObject(i);
				
				attrs.put(labelNames[i], value);
			}
			result.add((T)ar);
		}
		return result;
	}

해결 방향:
         데이터베이스 에 대한 데이터 조작 은 2 가지 가 있 습 니 다.set/get.Oacle 의 timestamp 를 my sql 의 timestamp 와 같이 바 꾸 기 위해 서 는 set/get 시 관여 해 야 합 니 다.상기 2 시 에 각각 set/get 작업 에 대응 해 야 합 니 다.원본 코드 를 수정 한 후에 테스트 를 통 해 사고방식 이 실행 가능 하 다 는 것 을 발견 했다.
 1.doBuildTable Infoy()방법 에 서 는"java.sql.Timestamp".equals(colClassName)에||"Oacle.sql.TIMESTAMP".equals(colClassName)를 추가 하여 Oacle.sql.timestamp 를 식별 할 수 있 도록 합 니 다.
} else if ("java.sql.Timestamp".equals(colClassName)
		    || "oracle.sql.TIMESTAMP".equals(colClassName)) {
		// timestamp, datetime
		result.addInfo(colName, java.sql.Timestamp.class);

            2.ModelBuilder.build()중 for (int i = 1; i <= columnCount; i++){}순환 체 수정 은 다음 과 같 습 니 다.
for (int i = 1; i <= columnCount; i++) {
		Object value;
		if (types[i] == Types.CLOB)
		    value = handleClob(rs.getClob(i));
		else if (types[i] == Types.NCLOB)
		    value = handleClob(rs.getNClob(i));
		else if (types[i] == Types.BLOB)
		    value = handleBlob(rs.getBlob(i));
		else if (types[i] == Types.TIMESTAMP
			&& DbKit.dialect.isOracle()) {
		    // oracle.sql.timestamp --->java.sql.Timestamp
		    value = rs.getTimestamp(i);
		} else {
		    value = rs.getObject(i);
		}

		attrs.put(labelNames[i], value);
	    }

PS:본인 의 글 은 기초 가 부족 하고 손 에 익 은 편집기 가 없 으 니 여러분 이 아 쉬 운 대로 보시 면 됩 니 다.버 전 라 이브 러 리 에 코드 를 업데이트 할 수 있 는 지@JFinal 에서 고려 해 주시 기 바 랍 니 다.

좋은 웹페이지 즐겨찾기