Java日記に深く入り込む--自分でORMフレームワークを書く(2)
17905 ワード
前回のJava日記に深く入り込んだ--自分でORMフレームワーク(1)を書くと、データベースのテーブルをオブジェクトに生成するJavaBeanについて言及しました.このブログでは、JavaBeanを利用して削除して調べる方法について説明します.主な動作はsql文をつづることです.
まず、最も基本的なsql文を実行する方法を書きます.私たちが使用しているPreparedStatementは実行します.パラメータを追加することは、ツールクラスで実現できます.
sql文メソッドを実行するボディ
データベースの名前とフィールドの名前は下線分割法を採用していますが、フィールド名はアルパカを採用しているので、一度変換します
挿入時のアトリビュート値の取得は、主に反射によって行われます.
挿入方法の主なステップは、前のsql文を接合し、属性名を変換し、接合し、後のsql文を接合することです.
削除には2つの方法があります.1つ目はクラスとプライマリ・キー、もう1つはオブジェクト・インスタンスによる削除です.
変更されたsqlの接合方式は少し似ています挿入
調べると3種類のクエリーがあります.1つ目は複数行のレコードをクエリーすること、2つ目はレコードをクエリーすること、3つ目は値クエリーをクエリーするときにレコードをJavaBean対応のListに変換するにはJavaBeanのsetメソッドが必要です.反射で行うことができます
以上がコアコードです.その後、接続プールとカスタムQueryオブジェクトの工場をカスタマイズして、異なるデータベースに適応することもできます.この部分のコードは実装に残しておきます.
1.増加
まず、最も基本的なsql文を実行する方法を書きます.私たちが使用しているPreparedStatementは実行します.パラメータを追加することは、ツールクラスで実現できます.
public class JDBCUtils {
public static void handleParams(PreparedStatement ps,Object[]params){
if (params!=null){
for (int i=0;i<params.length;i++){
try {
// 1
ps.setObject(i+1,params[i]);
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}
sql文メソッドを実行するボディ
public int executeDML(String sql,Object[] params){
Connection connection=DBManager.getConn();
int count=0;
PreparedStatement ps=null;
try {
ps=connection.prepareStatement(sql);
JDBCUtils.handleParams(ps,params);
count=ps.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}finally {
DBManager.close(ps,connection);
}
return count;
}
データベースの名前とフィールドの名前は下線分割法を採用していますが、フィールド名はアルパカを採用しているので、一度変換します
public static String camel2Underline(String line){
StringBuilder result = new StringBuilder();
if (line != null && line.length() > 0) {
//
result.append(line.substring(0, 1).toLowerCase());
//
for (int i = 1; i < line.length(); i++) {
String s = line.substring(i, i + 1);
//
if (s.equals(s.toUpperCase()) && !Character.isDigit(s.charAt(0))) {
result.append("_");
}
//
result.append(s.toLowerCase());
}
}
return result.toString();
}
挿入時のアトリビュート値の取得は、主に反射によって行われます.
public static Object getFieldValue(String field,Object obj){
Class clazz=obj.getClass();
Field idField= null;
Object id=null;
try {
idField = clazz.getDeclaredField(field);
idField.setAccessible(true);
id=idField.get(obj);
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return id;
}
挿入方法の主なステップは、前のsql文を接合し、属性名を変換し、接合し、後のsql文を接合することです.
/**
* , sql insert into users(id,name) values(?,?)
* @param obj
*/
public void insert(Object obj){
Class clazz = obj.getClass();
// Class TableInfo
TableInfo tableInfo = TableContext.poClassTableMap.get(clazz);
// sql
StringBuilder stringBuilder=new StringBuilder("insert into " + tableInfo.getTname() + "(");
Field[]fields=clazz.getDeclaredFields();
Object[] fieldValue=new Object[fields.length];
// ,
for (int i=0;i",");
}
//
stringBuilder.delete(stringBuilder.length()-1,stringBuilder.length());
// sql
stringBuilder.append(")");
stringBuilder.append(" values(");
for (int i=0;i"?,");
}
stringBuilder.delete(stringBuilder.length()-1,stringBuilder.length());
stringBuilder.append(")");
String sql = stringBuilder.toString();
System.out.println(sql);
executeDML(sql, fieldValue);
}
2.削除
削除には2つの方法があります.1つ目はクラスとプライマリ・キー、もう1つはオブジェクト・インスタンスによる削除です.
クラスとプライマリ・キーによる削除
public void delete(Class clazz,Object id){
// Class TableInfo
TableInfo tableInfo = TableContext.poClassTableMap.get(clazz);
//
ColumnInfo columnInfo = tableInfo.getOnlyPriKey();
String sql = "delete from " + tableInfo.getTname() + " where " + columnInfo.getName() + " =?";
executeDML(sql, new Object[]{id});
}
オブジェクトインスタンスから削除
public void delete(Object obj){
Class clazz = obj.getClass();
// Class TableInfo
TableInfo tableInfo = TableContext.poClassTableMap.get(clazz);
//
ColumnInfo columnInfo = tableInfo.getOnlyPriKey();
String sql = "delete from " + tableInfo.getTname() + " where " + columnInfo.getName() + " =?";
//
Object id = ReflectUtils.getFieldValue(StringUtils.underlineToSmallCamel(columnInfo.getName()), obj);
executeDML(sql, new Object[]{id});
}
3.変更
変更されたsqlの接合方式は少し似ています挿入
/**
* sql update users set name = ? where id = ?
* @param obj
* @param fieldNames
* @return sql
*/
public int update(Object obj,String[] fieldNames){
Class clazz = obj.getClass();
// Class TableInfo
TableInfo tableInfo = TableContext.poClassTableMap.get(clazz);
//
ColumnInfo columnInfo = tableInfo.getOnlyPriKey();
List
4.調べる
調べると3種類のクエリーがあります.1つ目は複数行のレコードをクエリーすること、2つ目はレコードをクエリーすること、3つ目は値クエリーをクエリーするときにレコードをJavaBean対応のListに変換するにはJavaBeanのsetメソッドが必要です.反射で行うことができます
public static void invokeSet(String field,Object value,Object obj){
Class clazz=obj.getClass();
try {
Method method=clazz.getDeclaredMethod("set"+StringUtils.underlineToBigCamel(field),value.getClass());
method.invoke(obj,value);
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
複数行レコードの問合せ
/**
* ,
* @param sql
* @param clazz javabean Class
* @param params sql
* @return
*/
public List queryRow(final String sql,final Class clazz,final Object[] params){
Connection connection=DBManager.getConn();
ResultSet resultSet=null;
try {
PreparedStatement ps=connection.prepareStatement(sql);
JDBCUtils.handleParams(ps,params);
resultSet=ps.executeQuery();
List result=new ArrayList();
ResultSetMetaData resultSetMetaData= null;
try {
resultSetMetaData = resultSet.getMetaData();
while (resultSet.next()){
Object rowObj=clazz.newInstance();
// ,
for(int i=0;i//
String columnName=resultSetMetaData.getColumnLabel(i+1);
//
Object columnValue=resultSet.getObject(i+1);
//
ReflectUtils.invokeSet(columnName,columnValue,rowObj);
}
result.add(rowObj);
}
} catch (SQLException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
}finally {
DBManager.close(preparedStatement,connection);
}
return result;
} catch (SQLException e) {
e.printStackTrace();
return null;
}
}
レコードのクエリー
/**
* ,
* @param sql
* @param clazz javabean Class
* @param params sql
* @return
*/
public Object queryUniqueRow(String sql,Class clazz,Object[] params){
List result=queryRow(sql,clazz,params);
if (result!=null&&result.size()>0){
return result.get(0);
}
return null;
}
値の問合せ
/**
* ( )
* @param sql
* @param params sql
* @return
*/
public Object queryValue(String sql,Object[] params){
Connection connection=DBManager.getConn();
ResultSet resultSet=null;
try {
PreparedStatement ps=connection.prepareStatement(sql);
JDBCUtils.handleParams(ps,params);
resultSet=ps.executeQuery();
try {
while (resultSet.next()){
//
return resultSet.getObject(1);
}
} catch (SQLException e) {
e.printStackTrace();
}finally {
DBManager.close(preparedStatement,connection);
}
return null;
}
}
以上がコアコードです.その後、接続プールとカスタムQueryオブジェクトの工場をカスタマイズして、異なるデータベースに適応することもできます.この部分のコードは実装に残しておきます.