|
|
|
@ -0,0 +1,323 @@
|
|
|
|
|
package xyz.wbsite.jmacro.db;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import xyz.wbsite.jmacro.db.anonation.TableField;
|
|
|
|
|
|
|
|
|
|
import java.io.File;
|
|
|
|
|
import java.lang.reflect.Field;
|
|
|
|
|
import java.sql.SQLException;
|
|
|
|
|
import java.util.ArrayList;
|
|
|
|
|
import java.util.Arrays;
|
|
|
|
|
import java.util.Date;
|
|
|
|
|
import java.util.HashMap;
|
|
|
|
|
import java.util.List;
|
|
|
|
|
import java.util.Map;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* xyz.wbsite.wsqlite.Client
|
|
|
|
|
*
|
|
|
|
|
* @author wangbing
|
|
|
|
|
*/
|
|
|
|
|
public class ObjectClient extends Client {
|
|
|
|
|
|
|
|
|
|
private Map<String, Class> classMap = new HashMap<>();
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 构造函数
|
|
|
|
|
*
|
|
|
|
|
* @param dbFile 文件
|
|
|
|
|
* @param classList 注册对象
|
|
|
|
|
* @throws ClassNotFoundException
|
|
|
|
|
* @throws SQLException
|
|
|
|
|
*/
|
|
|
|
|
public ObjectClient(File dbFile, List<Class> classList) throws ClassNotFoundException, SQLException {
|
|
|
|
|
super(dbFile);
|
|
|
|
|
for (Class aClass : classList) {
|
|
|
|
|
classMap.put(aClass.getName(), aClass);
|
|
|
|
|
}
|
|
|
|
|
for (String key : classMap.keySet()) {
|
|
|
|
|
Class object = classMap.get(key);
|
|
|
|
|
StringBuffer sql = new StringBuffer();
|
|
|
|
|
String name = object.getSimpleName();
|
|
|
|
|
|
|
|
|
|
sql.append("CREATE TABLE IF NOT EXISTS ");
|
|
|
|
|
sql.append(name);
|
|
|
|
|
sql.append(" (");
|
|
|
|
|
|
|
|
|
|
Field[] fields = object.getDeclaredFields();
|
|
|
|
|
for (Field f : fields) {
|
|
|
|
|
if (f.isAnnotationPresent(TableField.class)) {
|
|
|
|
|
TableField bind = f.getAnnotation(TableField.class);
|
|
|
|
|
int length = bind.value();
|
|
|
|
|
|
|
|
|
|
if (f.getType() == String.class) {
|
|
|
|
|
sql.append(f.getName().toUpperCase());
|
|
|
|
|
sql.append(" VARCHAR(" + length + "),");
|
|
|
|
|
} else if (f.getType() == Boolean.class || f.getType() == boolean.class) {
|
|
|
|
|
sql.append(f.getName().toUpperCase());
|
|
|
|
|
sql.append(" BOOLEAN,");
|
|
|
|
|
} else if (f.getType() == Byte.class || f.getType() == byte.class ||
|
|
|
|
|
f.getType() == Short.class || f.getType() == short.class ||
|
|
|
|
|
f.getType() == Character.class || f.getType() == char.class ||
|
|
|
|
|
f.getType() == Integer.class || f.getType() == int.class ||
|
|
|
|
|
f.getType() == Long.class || f.getType() == long.class) {
|
|
|
|
|
sql.append(f.getName().toUpperCase());
|
|
|
|
|
sql.append(" INTEGER,");
|
|
|
|
|
} else if (f.getType() == Float.class || f.getType() == float.class ||
|
|
|
|
|
f.getType() == Double.class || f.getType() == double.class) {
|
|
|
|
|
sql.append(f.getName().toUpperCase());
|
|
|
|
|
sql.append(" REAL,");
|
|
|
|
|
} else if (f.getType() == Byte[].class || f.getType() == byte[].class) {
|
|
|
|
|
sql.append(f.getName().toUpperCase());
|
|
|
|
|
sql.append(" BLOB,");
|
|
|
|
|
} else if (f.getType() == Date.class) {
|
|
|
|
|
sql.append(f.getName().toUpperCase());
|
|
|
|
|
sql.append(" TIMESTAMP,");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sql.replace(sql.length() - 1, sql.length(), "");
|
|
|
|
|
sql.append(")");
|
|
|
|
|
System.out.println("SQL ==> " + sql.toString());
|
|
|
|
|
execute(sql.toString());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public <T> int insert(Class<T> poClass, T po) throws SQLException, ClassNotFoundException {
|
|
|
|
|
try {
|
|
|
|
|
Class aClass = classMap.get(poClass.getName());
|
|
|
|
|
if (aClass == null) {
|
|
|
|
|
System.err.println(poClass.getName() + " not found.");
|
|
|
|
|
} else {
|
|
|
|
|
StringBuffer sql = new StringBuffer();
|
|
|
|
|
sql.append("INSERT INTO ");
|
|
|
|
|
sql.append(aClass.getSimpleName());
|
|
|
|
|
sql.append("(");
|
|
|
|
|
|
|
|
|
|
//获取字段列表
|
|
|
|
|
List<Field> fs = getFields(poClass);
|
|
|
|
|
|
|
|
|
|
StringBuffer fieldsSql = new StringBuffer();
|
|
|
|
|
StringBuffer valueSql = new StringBuffer();
|
|
|
|
|
Object[] values = new Object[fs.size()];
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < fs.size(); i++) {
|
|
|
|
|
Field f = fs.get(i);
|
|
|
|
|
f.setAccessible(true);
|
|
|
|
|
fieldsSql.append(f.getName().toUpperCase());
|
|
|
|
|
valueSql.append("?");
|
|
|
|
|
values[i] = f.get(po);
|
|
|
|
|
if (i != fs.size() - 1) {
|
|
|
|
|
fieldsSql.append(",");
|
|
|
|
|
valueSql.append(",");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sql.append(fieldsSql);
|
|
|
|
|
sql.append(") VALUES (");
|
|
|
|
|
sql.append(valueSql);
|
|
|
|
|
sql.append(")");
|
|
|
|
|
System.out.println("SQL ==> " + sql.toString());
|
|
|
|
|
return executeUpdate(sql.toString(), values);
|
|
|
|
|
}
|
|
|
|
|
} catch (IllegalAccessException e) {
|
|
|
|
|
e.printStackTrace();
|
|
|
|
|
} finally {
|
|
|
|
|
destroyed();
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public <T> int delete(Class<T> poClass, Where where) throws SQLException, ClassNotFoundException {
|
|
|
|
|
try {
|
|
|
|
|
Class aClass = classMap.get(poClass.getName());
|
|
|
|
|
if (aClass == null) {
|
|
|
|
|
System.err.println(poClass.getName() + " not found.");
|
|
|
|
|
} else {
|
|
|
|
|
StringBuffer sql = new StringBuffer();
|
|
|
|
|
sql.append("DELETE FROM ");
|
|
|
|
|
sql.append(aClass.getSimpleName());
|
|
|
|
|
sql.append(where.getSql());
|
|
|
|
|
System.out.println("SQL ==> " + sql.toString());
|
|
|
|
|
return executeUpdate(sql.toString(), where.getArgs());
|
|
|
|
|
}
|
|
|
|
|
} finally {
|
|
|
|
|
destroyed();
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public <T> int update(Class<T> poClass, T po, Where where) throws SQLException, ClassNotFoundException {
|
|
|
|
|
try {
|
|
|
|
|
Class aClass = classMap.get(poClass.getName());
|
|
|
|
|
if (aClass == null) {
|
|
|
|
|
System.err.println(poClass.getName() + " not found.");
|
|
|
|
|
} else {
|
|
|
|
|
//获取字段列表
|
|
|
|
|
List<Field> fs = getFields(poClass);
|
|
|
|
|
|
|
|
|
|
StringBuffer sql = new StringBuffer();
|
|
|
|
|
Object[] values = new Object[fs.size()];
|
|
|
|
|
sql.append("UPDATE ");
|
|
|
|
|
sql.append(aClass.getSimpleName());
|
|
|
|
|
sql.append(" SET ");
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < fs.size(); i++) {
|
|
|
|
|
Field f = fs.get(i);
|
|
|
|
|
f.setAccessible(true);
|
|
|
|
|
sql.append(f.getName());
|
|
|
|
|
sql.append(" = ?");
|
|
|
|
|
values[i] = f.get(po);
|
|
|
|
|
if (i != fs.size() - 1) {
|
|
|
|
|
sql.append(",");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 条件
|
|
|
|
|
sql.append(where.getSql());
|
|
|
|
|
|
|
|
|
|
System.out.println("SQL ==> " + sql.toString());
|
|
|
|
|
return executeUpdate(sql.toString(), concat(values, where.getArgs()));
|
|
|
|
|
}
|
|
|
|
|
} catch (IllegalAccessException e) {
|
|
|
|
|
e.printStackTrace();
|
|
|
|
|
} finally {
|
|
|
|
|
destroyed();
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public <T> List<T> select(Class<T> poClass, Where where, int pageNumber, int pageSize) throws SQLException, ClassNotFoundException {
|
|
|
|
|
ArrayList<T> list = new ArrayList<>();
|
|
|
|
|
try {
|
|
|
|
|
Class aClass = classMap.get(poClass.getName());
|
|
|
|
|
if (aClass == null) {
|
|
|
|
|
System.err.println(poClass.getName() + " not found.");
|
|
|
|
|
} else {
|
|
|
|
|
StringBuffer sql = new StringBuffer();
|
|
|
|
|
sql.append("SELECT ");
|
|
|
|
|
|
|
|
|
|
//获取字段列表
|
|
|
|
|
List<Field> fs = getFields(poClass);
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < fs.size(); i++) {
|
|
|
|
|
Field f = fs.get(i);
|
|
|
|
|
sql.append(f.getName().toUpperCase());
|
|
|
|
|
if (i != fs.size() - 1) {
|
|
|
|
|
sql.append(",");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sql.append(" FROM ");
|
|
|
|
|
sql.append(aClass.getSimpleName());
|
|
|
|
|
|
|
|
|
|
// 条件
|
|
|
|
|
sql.append(where.getSql());
|
|
|
|
|
|
|
|
|
|
//分页参数
|
|
|
|
|
if (pageSize > 0) {
|
|
|
|
|
sql.append(" LIMIT " + (pageNumber - 1) + "," + pageSize);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
System.out.println("SQL ==> " + sql.toString());
|
|
|
|
|
list.addAll(executeQuery(poClass, sql.toString(), where.getArgs()));
|
|
|
|
|
}
|
|
|
|
|
} finally {
|
|
|
|
|
destroyed();
|
|
|
|
|
}
|
|
|
|
|
return list;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 执行select查询,返回结果列表
|
|
|
|
|
*
|
|
|
|
|
* @param sql sql select 语句
|
|
|
|
|
* @param poClass 结果集的行数据处理类对象
|
|
|
|
|
* @return
|
|
|
|
|
* @throws SQLException
|
|
|
|
|
* @throws ClassNotFoundException
|
|
|
|
|
*/
|
|
|
|
|
public <T> List<T> executeQuery(Class<T> poClass, String sql, Object... args) throws SQLException, ClassNotFoundException {
|
|
|
|
|
List<T> rsList = new ArrayList<T>();
|
|
|
|
|
try {
|
|
|
|
|
resultSet = executeQuery(sql, args);
|
|
|
|
|
|
|
|
|
|
//获取字段列表
|
|
|
|
|
List<Field> fs = getFields(poClass);
|
|
|
|
|
|
|
|
|
|
while (resultSet.next()) {
|
|
|
|
|
try {
|
|
|
|
|
T o = poClass.newInstance();
|
|
|
|
|
for (int i = 0; i < fs.size(); i++) {
|
|
|
|
|
Field f = fs.get(i);
|
|
|
|
|
f.setAccessible(true);
|
|
|
|
|
|
|
|
|
|
if (f.getType() == String.class) {
|
|
|
|
|
String v = resultSet.getString(f.getName());
|
|
|
|
|
f.set(o, v);
|
|
|
|
|
} else if (f.getType() == Boolean.class || f.getType() == boolean.class) {
|
|
|
|
|
boolean v = resultSet.getBoolean(f.getName());
|
|
|
|
|
f.set(o, v);
|
|
|
|
|
} else if (f.getType() == Byte.class || f.getType() == byte.class) {
|
|
|
|
|
byte v = resultSet.getByte(f.getName());
|
|
|
|
|
f.set(o, v);
|
|
|
|
|
} else if (f.getType() == Short.class || f.getType() == short.class) {
|
|
|
|
|
short v = resultSet.getShort(f.getName());
|
|
|
|
|
f.set(o, v);
|
|
|
|
|
} else if (f.getType() == Character.class || f.getType() == char.class) {
|
|
|
|
|
short v = resultSet.getShort(f.getName());
|
|
|
|
|
f.set(o, (char) v);
|
|
|
|
|
} else if (f.getType() == Integer.class || f.getType() == int.class) {
|
|
|
|
|
int v = resultSet.getInt(f.getName());
|
|
|
|
|
f.set(o, v);
|
|
|
|
|
} else if (f.getType() == Long.class || f.getType() == long.class) {
|
|
|
|
|
long v = resultSet.getLong(f.getName());
|
|
|
|
|
f.set(o, v);
|
|
|
|
|
} else if (f.getType() == Float.class || f.getType() == float.class) {
|
|
|
|
|
float v = resultSet.getFloat(f.getName());
|
|
|
|
|
f.set(o, v);
|
|
|
|
|
} else if (f.getType() == Double.class || f.getType() == double.class) {
|
|
|
|
|
double v = resultSet.getDouble(f.getName());
|
|
|
|
|
f.set(o, v);
|
|
|
|
|
} else if (f.getType() == Byte[].class || f.getType() == byte[].class) {
|
|
|
|
|
byte[] v = resultSet.getBytes(f.getName());
|
|
|
|
|
f.set(o, v);
|
|
|
|
|
} else if (f.getType() == Date.class) {
|
|
|
|
|
Date v = resultSet.getDate(f.getName());
|
|
|
|
|
f.set(o, v);
|
|
|
|
|
} else {
|
|
|
|
|
String v = resultSet.getString(f.getName());
|
|
|
|
|
f.set(o, v);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
rsList.add(o);
|
|
|
|
|
} catch (InstantiationException e) {
|
|
|
|
|
e.printStackTrace();
|
|
|
|
|
} catch (IllegalAccessException e) {
|
|
|
|
|
e.printStackTrace();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} finally {
|
|
|
|
|
destroyed();
|
|
|
|
|
}
|
|
|
|
|
return rsList;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private List<Field> getFields(Class aClass) {
|
|
|
|
|
List<Field> fs = new ArrayList<>();
|
|
|
|
|
for (Field f : aClass.getDeclaredFields()) {
|
|
|
|
|
if (f.isAnnotationPresent(TableField.class)) {
|
|
|
|
|
fs.add(f);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return fs;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private <T> T[] concat(T[] arr1, T[] arr2) {
|
|
|
|
|
List<T> temp = new ArrayList<>();
|
|
|
|
|
temp.addAll(Arrays.asList(arr1));
|
|
|
|
|
temp.addAll(Arrays.asList(arr2));
|
|
|
|
|
return (T[]) temp.toArray();
|
|
|
|
|
}
|
|
|
|
|
}
|