不足地方希望大神指点,欢迎讨论
首先定义可操作类接口,所有想进行数据库操作的都实现这个接口;
接口定义很简单,
getId() 其实就是获取对象的主键,在这可能定义不准确
modify 列用了java8的函数结构定义可修改属性;其作用就是可以单独同步修改属性,本文中没有用到,暂时放这吧,以后有空在上传怎么用这个函数;
代码如下
package mypack;
public interface HashID {
public Object getId();
/**
* 修改标记
* @param name 修改的属性名
*/
default void modify(String name) {
ORMUtils.modifys.add(name);
}
}
// 主键注解,在主键增加@Primarykey 标识为主键;详细用法建议java core中注解;
package mypack;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Primarykey {
}
对象的数据库操作:
本列子全部用定义的类名,字段名作为数据库表名以及字段名;其实还可以用xml配置(如hibernate的配置),json, 注解等多种设置进行 数据库字段名和类名称,字段名进行映射。废话不多说,直接上代码
package mypack;
import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Timestamp;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
public class ORMUtils {
static Set<String> modifys = new HashSet<>();
public static Connection getConn() throws Exception {
String driver = "com.mysql.jdbc.Driver";//mysql驱动,不解释
String url = "jdbc:mysql://127.0.0.1:3306/test";//mysql连接url,不解释
String user = "root";//mysql用户
String password = "123456";//mysql密码
Class.forName(driver); //加载驱动
return DriverManager.getConnection(url, user, password);//获取连接
}
public static void doInsert(HashID data) throws Exception {
List<Field> fieldList = new LinkedList<>();
getAllFeild(fieldList, data.getClass());
StringBuffer keys = new StringBuffer();
StringBuffer values = new StringBuffer();
for (Field field : fieldList) {
if (keys.length() > 0) {
keys.append(",");
values.append(",");
}
//字段名用定义属性名处理,可以用hibernate类是的xml配置,注解等其他方式处理
keys.append("`").append(field.getName()).append("`");
values.append("?");
}
//生成插入sql,不做关联处理(左联,右联,内联等)
StringBuffer sql = new StringBuffer();
sql.append("INSERT INTO `");
//此处为表名,我以类名为表名;可以用hibernate类似的xml配置,注解等多种方式
sql.append(data.getClass().getSimpleName());
sql.append("` ( ").append(keys).append(") VALUES (").append(values.toString()).append(");");
try (Connection conn = getConn();PreparedStatement statement = conn.prepareStatement(sql.toString())) {
int index = 1;
for (Field field : fieldList) {
setStatement(statement, index, data, field);
index ++;
}
statement.executeUpdate();
}
}
// 此处不处理,详细见根据主键检索doSelect(Class<T> clazz, Object Id)
//public <T extends HashID> T doSelect(Class<T> clazz, String sql) {
//List<Field> fieldList = new LinkedList<>();
//
//return null;
//}
//
// 检索,返回单个对象;返回多个有空增加
public static <T extends HashID> T doSelect(Class<T> clazz, Object Id) throws Exception {
List<Field> fieldList = new LinkedList<>();
getAllFeild(fieldList, clazz);
// 此处查找主键
Field key = null;
for (Field field : fieldList) {
if (field.isAnnotationPresent(Primarykey.class)) {
key = field;
break;
}
}
// 主键不存在,不能处理;自己写sql查询
if (key == null) {
throw new RuntimeException("unkown select key:" + Id);
}
// 查询sql,根据 主键检索,此处用定义属性名。可以用配置,或者注解等其他方式
String sql = "SELECT * FROM `" + clazz.getSimpleName() + "` where `" + key.getName() + "` = " + Id +";";
try (Connection conn = getConn();
PreparedStatement statement = conn.prepareStatement(sql);
ResultSet result = statement.executeQuery()) {
if (result.next()) {
// 注意:此类一定要有public 的无参数构造方法,当然可以自行处理有参数构造方法
T data = clazz.newInstance();
for (Field field : fieldList) {
//属性赋值
setValue(result, data, field);
}
return data;
} else {
return null;
}
}
}
public static void doUpdate(HashID data) throws Exception {
List<Field> fieldList = new LinkedList<>();
getAllFeild(fieldList, data.getClass());
Field key = null;
StringBuffer keys = new StringBuffer();
for (Field field : fieldList) {
if (field.isAnnotationPresent(Primarykey.class)) {
key = field;
}
if (keys.length() > 0) {
keys.append(",");
}
//字段名用定义属性名处理,可以用hibernate类是的xml配置,注解等其他方式处理
keys.append("`").append(field.getName()).append("` = ?");
}
StringBuffer sql = new StringBuffer();
sql.append("UPDATE `").append(data.getClass().getSimpleName());
sql.append("` SET ").append(keys.toString());
sql.append(" WHERE `").append(key.getName()).append("` = ").append(data.getId()).append(";");
try (Connection conn = getConn();
PreparedStatement statement = conn.prepareStatement(sql.toString())) {
int index = 1;
for (Field field : fieldList) {
setStatement(statement, index, data, field);
index ++;
}
statement.executeUpdate();
}
}
public static void doDelete(HashID data) throws Exception {
doDelete(data.getClass(), data.getId());
}
public static void doDelete(Class<?> clazz, Object Id) throws Exception {
List<Field> fieldList = new LinkedList<>();
getAllFeild(fieldList, clazz);
Field key = null;
for (Field field : fieldList) {
if (field.isAnnotationPresent(Primarykey.class)) {
key = field;
break;
}
}
String sql = "DELETE FROM `" + clazz.getSimpleName() + "` WHERE `" + key.getName() + "` = " + Id + ";";
System.out.println(sql);
try (Connection conn = getConn();
PreparedStatement statement = conn.prepareStatement(sql)) {
statement.executeUpdate();
}
}
private static void setStatement(PreparedStatement statement, int index, HashID data, Field field) throws Exception {
boolean isAccess = field.isAccessible();
try {
//关闭安全检查,否者读取不到私有的属性
field.setAccessible(true);
if (field.getType() == byte.class || field.getType() == Byte.class ) {
statement.setByte(index, field.getByte(data));
} else if (field.getType() == boolean.class || field.getType() == Boolean.class ) {
statement.setBoolean(index, field.getBoolean(data));
} else if (field.getType() == short.class || field.getType() == Short.class ) {
statement.setShort(index, field.getShort(data));
} else if (field.getType() == char.class || field.getType() == Character.class ) {
statement.setString(index, String.valueOf(field.getChar(data)));
} else if (field.getType() == int.class || field.getType() == Integer.class ) {
statement.setInt(index, field.getInt(data));
} else if (field.getType() == float.class || field.getType() == Float.class ) {
statement.setFloat(index, field.getFloat(data));
} else if (field.getType() == long.class || field.getType() == Long.class ) {
statement.setLong(index, field.getLong(data));
} else if (field.getType() == double.class || field.getType() == Double.class ) {
statement.setDouble(index, field.getDouble(data));
} else if (field.getType() == String.class) {
statement.setString(index, field.get(data).toString());
} else if (field.getType() == Timestamp.class){
statement.setObject(index, field.get(data));
} else {
//本列只支持以上类型,如果需要新类型自行增加处理;泛型处理也可以支持,由于空闲时间有限,泛型类型较为复杂,此处不做处理,以后有机会再发泛型处理
throw new RuntimeException("uns provided type:" + field.getType());
}
} finally {
field.setAccessible(isAccess);
}
}
private static void setValue(ResultSet result, HashID data, Field field) throws Exception {
boolean isAccess = field.isAccessible();
try {
//关闭安全检查,否者读取不到私有的属性
field.setAccessible(true);
if (field.getType() == byte.class || field.getType() == Byte.class ) {
field.setByte(data, result.getByte(field.getName()));
} else if (field.getType() == boolean.class || field.getType() == Boolean.class ) {
field.setBoolean(data, result.getBoolean(field.getName()));
} else if (field.getType() == short.class || field.getType() == Short.class ) {
field.setShort(data, result.getShort(field.getName()));
} else if (field.getType() == char.class || field.getType() == Character.class ) {
field.set(data, result.getString(field.getName()).charAt(0));
} else if (field.getType() == int.class || field.getType() == Integer.class ) {
field.setInt(data, result.getInt(field.getName()));
} else if (field.getType() == float.class || field.getType() == Float.class ) {
field.setFloat(data, result.getFloat(field.getName()));
} else if (field.getType() == long.class || field.getType() == Long.class ) {
field.setLong(data, result.getLong(field.getName()));
} else if (field.getType() == double.class || field.getType() == Double.class ) {
field.setDouble(data, result.getDouble(field.getName()));
} else if (field.getType() == String.class) {
field.set(data, result.getString(field.getName()));
} else if (field.getType() == Timestamp.class){
field.set(data, result.getTimestamp(field.getName()));
} else {
//本列只支持以上类型,如果需要新类型自行增加处理;泛型处理也可以支持,由于空闲时间有限,泛型类型较为复杂,此处不做处理,以后有机会再发泛型处理
throw new RuntimeException("uns provided type:" + field.getType());
}
} finally {
field.setAccessible(isAccess);
}
}
// 获取所有定义属性,此处不做特殊处理;如果需要的自行处理,比如static final 等定义
// 还可以用注解方式决定是否处理该属性
private static void getAllFeild(List<Field> fieldList, Class<?> clazz) {
if (clazz == Object.class) {
return;
} else {
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
fieldList.add(field);
}
getAllFeild(fieldList, clazz.getSuperclass());
}
}
}
//本示列用的mysql数据库,驱动自行下载
// 建表语句
CREATE TABLE `userinfo` (
`Id` int(11) NOT NULL DEFAULT '0',
`name` varchar(24) DEFAULT '',
`sex` tinyint(1) DEFAULT '0',
`age` smallint(6) DEFAULT '0',
`money` float(6,2) DEFAULT '0.00',
`bornTime` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`Id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
测试列子
package mypack;
import java.sql.Timestamp;
public class UserInfo implements HashID {
@Primarykey
private int Id;
private String name;
private byte sex;
private short age;
private float money;
private Timestamp bornTime;
@Override
public Object getId() {
return Id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public byte getSex() {
return sex;
}
public void setSex(byte sex) {
this.sex = sex;
}
public short getAge() {
return age;
}
public void setAge(short age) {
this.age = age;
}
public float getMoney() {
return money;
}
public void setMoney(float money) {
this.money = money;
}
public Timestamp getBornTime() {
return bornTime;
}
public void setBornTime(Timestamp bornTime) {
this.bornTime = bornTime;
}
public void setId(int id) {
Id = id;
}
@Override
public String toString() {
return String.format("Id=%s, name=%s, age=%s, borntime=%s", Id, name, age, bornTime);
}
public static void main(String[] args) throws Exception {
//插入测试
//UserInfo info = new UserInfo();
//info.setId(1024);
//info.setName("刘振");
//info.setAge((short)80);
//info.setSex((byte)1);
//info.setMoney(50.5f);
//info.setBornTime(new Timestamp(System.currentTimeMillis()));
//ORMUtils.doInsert(info);
//检索测试
UserInfo info = ORMUtils.doSelect(UserInfo.class, 1024);
System.out.println(info);
// 修改测试
//info.setName("刘宇轩");
//info.setAge((short)1);
//info.setBornTime(new Timestamp(System.currentTimeMillis()));
//ORMUtils.doUpdate(info);
//System.out.println(info);
//删除测试
ORMUtils.doDelete(info);
}
}