该ORM支持的功能
调用简单函数实现对指定数据库的增删查改
将自定义对象生成数据库的字段
将数据库表的字段生成java bean对象
使用方法:
创建一个demo项目,导入jar包
将配置文件放入src目录下
调用TableContext.loadPoTables()方法自动按数据库的表构建java类
github地址
项目结构:
核心类:
Query抽象类:负责查询(对外提供服务核心类)
QueryFactory类:负责根据配置信息创建query对象
TypeConverto类:负责java与数据库的数据类型转换
TableContext类:负责获取管理数据库所有表结构和类结构的关系,并可以根据表结构生成类结构(调用工具类)
DBManger:根据配置信息,维持连接对象的管理(增加连接池)
工具类:
JDBCUtils封装常用JDBC操作
StringUtils封装常用字符串操作
JavaFileUtils封装文件操作:(将表结构封装成java类的操作)
ReflectUtils封装常用反射操作
bean类:
ColumnInfo类:封装数据库表中一个字段的信息
Configuration类:封装配置信息类
TableInfo类:封装数据库表的信息(表结构+表内所有的字段)
以下是程序源代码:
核心类
Query抽象类:
/*对外提供服务的核心类
* @author xjh
*/
@SuppressWarnings("all")
public abstract class Query implements Cloneable{
/*直接执行一个DML语句
* sql:sql语句
* params:语句内的参数
* return 执行语句后影响了几条记录*/
public int excuteDML(String sql,Object[] params){//执行DML语句
int count=0;
Connection conn=DBManger.getMysqlConn();
PreparedStatement ps=null;
try {
ps=conn.prepareStatement(sql);
//调用JDBCUtils包里的给prepareStatement传参操作
JDBCUtils.handleParams(params,ps);
count= ps.executeUpdate();
System.out.println(ps);
} catch (Exception e) {
e.printStackTrace();
}finally {
DBManger.close(ps,conn);
}
return count;
};
/*增加:将一个对象obj存储到数据库中
* 把对象不为null的属性往数据库中存储,如果数字为null则放0*/
public void insert(Object obj){//将obj新生成一个字段放入表中 insert into 表名 (id,uname,pwd) values (?,?,?)
Class c = obj.getClass();
List<Object> params=new ArrayList<>();//容器装对象不为null的属性的值,便于sql预处理赋值
TableInfo tableInfo = TableContext.poClassTableMap.get(c);//获得类对应的表,得到表名
Field fields[]=c.getDeclaredFields();//获得该类里所有的属性
StringBuilder sql=new StringBuilder("insert into "+ tableInfo.getTname()+" (");
int countNotNullField=0;//计算有多少个不为null的属性,方便在语句后加小问号
for(Field f:fields){//得到obj所有属性的值
String fieldname=f.getName();//Field的getName函数
Object fieldvalue= ReflectUtils.invokeGet(fieldname,obj);
if(fieldvalue!=null){sql.append(fieldname+",");
params.add(fieldvalue);}}
sql.setCharAt(sql.length()-1,')');//将当前字符串最后一个位置的,替换成)
sql.append(" value (");
for(int i=0;i<params.size();i++){sql.append("?,");}
sql.setCharAt(sql.length()-1,')');
excuteDML(sql.toString(),params.toArray());};
/*删除:根据clazz类找到对应的表,以及主键id删除对应的记录*/
public void delete(Class clazz,Object id){//id为需要删除的字段的主键的值
//通过传入的Class对象找TableInfo
TableInfo tableInfo= TableContext.poClassTableMap.get(clazz);//获得对应的表名
ColumnInfo onlyPriKey=tableInfo.getOnlyPriKey();//获得主键
String sql="delete from "+tableInfo.getTname()+" where "+onlyPriKey.getName()+"=?";
excuteDML(sql,new Object[]{id});};
/*删除:根据所给的对象,找到该对象的类,根据该对象的主键删除该对象在数据库表中对应的记录*/
public void delete(Object obj){
Class c = obj.getClass();
TableInfo tableInfo = TableContext.poClassTableMap.get(c);
ColumnInfo onlyPriKey = tableInfo.getOnlyPriKey();
//通过ReflectUtils包内的反射方法,调用get方法得到该对象属性的值 找到 对应字段的主键的值
Object priKeyvalue = ReflectUtils.invokeGet(onlyPriKey.getName(),obj);
delete(c, priKeyvalue);//调用上面写好的函数
};
/*修改:更新对象指定字段的属性
* fieldNames:需要更新的属性
* return 更新了几行*/
public int update(Object obj,String[] fieldNames){
//传入obj,{"age","salary"}-->update 表名 set age=?,salary=? where id=?
Class c = obj.getClass();
TableInfo tableInfo = TableContext.poClassTableMap.get(c);//通过对象获得类名获得表名
List<Object> params=new ArrayList<>();//存放该对象的属性的值
ColumnInfo onlyPriKey = tableInfo.getOnlyPriKey();//获得主键,通过主键值删除字段
Field fields[]=c.getDeclaredFields();
StringBuilder sql=new StringBuilder("update "+ tableInfo.getTname()+" set ");
for (String fieldname:fieldNames){
Object field=ReflectUtils.invokeGet(fieldname,obj);//得到该对象属性的值
params.add(field);
sql.append(fieldname+"=?,");
}
sql.setCharAt(sql.length()-1,' ');//把逗号替换成空格
sql.append("where "+onlyPriKey.getName()+"=?");
params.add(ReflectUtils.invokeGet(onlyPriKey.getName(),obj));
return excuteDML(sql.toString(),params.toArray());
};
/*---------------------------------------------查询----------------------------------------------------*/
/*查询多行记录:
* sql:查询语句
*clazz:封装数据的java bean对类的class对象
* params:sql的参数
* return 查询到的结果:一个list容器*/
public List QueryRows(String sql,Class clazz,Object[] params){//多行多列查询
Connection conn=DBManger.getMysqlConn();
List<Object>list=null;//放查询结果对象的容器
PreparedStatement ps=null;
ResultSet rs=null;
try {
ps=conn.prepareStatement(sql);
//调用JDBCUtils包里的给prepareStatement传参操作
JDBCUtils.handleParams(params,ps);
rs=ps.executeQuery();
ResultSetMetaData metaData=rs.getMetaData();//返回结果集的元数据
//多行,每一行为一个javabean对象
while (rs.next()){
if(list==null){list=new ArrayList<>();}
Object rowObj=clazz.newInstance();//创建一个javabean对象
//多列 select empname,salary from emp where id>?
for (int i=0;i<metaData.getColumnCount();i++){//getColumn函数得到查询语句结果集的列数,即属性数目
String columnName=metaData.getColumnLabel(i+1);//得到结果的列名,即属性标签名(如果没有标签则默认属性名)
Object columnValue=rs.getObject(i+1);
//调用rowObj对象的setEmpname方法,将结果集第一列的值设置进去
ReflectUtils.invokeSet(rowObj,columnName,columnValue);
}
list.add(rowObj);
}
} catch (Exception e) {
e.printStackTrace();
}finally {
DBManger.close(rs,ps,conn);
}
return list;};
/*查询单行记录:
* sql:查询语句
*clazz:封装数据的java bean对类的class对象
* params:sql的参数
* return 查询到的结果:一个对象*/
public Object QueryUniquerow(String sql,Class clazz,Object []params){
//查询一行:直接调用查询多行的函数,返回第一行数据
List list=QueryRows(sql,clazz,params);
return (list!=null&&list.size()>0)?list.get(0):null;
};
/*根据主键获得一个字段*/
public Object QueryById(Class clazz,Object id){
//select* from emp where id=?
TableInfo tableInfo=TableContext.poClassTableMap.get(clazz);//获得表信息
ColumnInfo onlyPriKey=tableInfo.getOnlyPriKey();//获得主键
String sql="select * from "+tableInfo.getTname()+" where "+onlyPriKey.getName()+"=? ";
return QueryUniquerow(sql,clazz,new Object[]{id});
}
/*查询返回一个值(一行一列):
* sql:查询语句
* param:sql的参数
* return 查询到的结果:一个对象*/
public Object QueryValue(String sql,Object []params){//sql查询语句,返回一个值,例如计算行数
Connection conn=DBManger.getMysqlConn();
Object value=null;//放查询结果对象的容器
PreparedStatement ps=null;
ResultSet rs=null;
try {
ps=conn.prepareStatement(sql);
//调用JDBCUtils包里的给prepareStatement传参操作
JDBCUtils.handleParams(params,ps);
rs=ps.executeQuery();
ResultSetMetaData metaData=rs.getMetaData();//返回结果集的元数据
while (rs.next()){
value=rs.getObject(1);
}
} catch (Exception e) {
e.printStackTrace();
}finally {
DBManger.close(rs,ps,conn);
}
return value;};
/*查询返回一个数字(一行一列)比如查询id:
* sql:查询语句
* param:sql的参数
* return 查询到的结果:一个对象*/
public Number QueryNumber(String sql,Object []params){//sql语句查询结果为一个数字
return (Number) QueryValue(sql,params);};
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
DBManger类:
/*根据配置信息,维持连接对象的 管理(增加连接池)*/
public class DBManger {
private static Configuration conf;
static {//加载配置文件,封装成一个对象
Properties pros=new Properties();//读取配置资源文件
try {
pros.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("db.properties"));//读取bin目录下资源
} catch (IOException e) {
e.printStackTrace();
}
conf=new Configuration();
conf.setDriver(pros.getProperty("driver"));
conf.setUrl(pros.getProperty("url"));
conf.setUser(pros.getProperty("user"));
conf.setPassword(pros.getProperty("password"));
conf.setSrc(pros.getProperty("src"));
conf.setPopackage(pros.getProperty("popackage"));
conf.setUsingdb(pros.getProperty("usingdb"));
conf.setQueryClass(pros.getProperty("queryClass"));
}
/*获得Connection对象*/
public static Connection getMysqlConn() {//连接数据库
try {
Class.forName(conf.getDriver());//得到驱动
String url = conf.getUrl();
return DriverManager.getConnection(url, conf.getUser(), conf.getPassword());//建立连接
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/*关闭传入的ResultSet Statement Connection对象*/
public static void close(ResultSet rs, Statement ps, Connection conn) {
try {
if (conn != null) {
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
try {
if (rs != null) {
rs.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
try {
if (ps != null) {
ps.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
/*关闭传入的 Statement Connection对象*/
public static void close(Statement ps, Connection conn) {
try {
if (conn != null) {
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
try {
if (ps != null) {
ps.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
/*关闭传入的Connection对象*/
public static void close( Connection conn) {
try {
if (conn != null) {
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
/*返回Configuration对象*/
public static Configuration getConf(){
return conf;
}
}
TableContext类:
/*负责获取管理数据库所有表结构和类结构的关系,并可以根据表结构生成类结构*/
public class TableContext {
/*表名为key,表信息对象为value*/
public static Map<String, TableInfo> tables=new HashMap<String, TableInfo>();//启动时就加载数据库的表
/*将po的class对象和表信息对象关联起来,便于重用*/
public static Map<Class,TableInfo> poClassTableMap=new HashMap<Class, TableInfo>();//在启动的时候将生成Class对象与其在数据库的表对应起来
private TableContext(){};
/*初始化,获得数据库元数据,得到数据库表的信息*/
static {
try {
Connection con = DBManger.getMysqlConn();
DatabaseMetaData dbmd = con.getMetaData();//DatabaseMetaData类是java.sql包中的类,可以获取我们连接到的数据库的结构、存储等很多信息
ResultSet rs = dbmd.getTables("sorm", "sorm", "%", new String[]{"TABLE"});
/*getTables()方法,该方法需要传进4个参数:数据库名称(若不传入数据库名称sorm则会读取所有数据库的表),模式,表名,类型标准*/
while (rs.next()) {
String tableName = (String) rs.getObject("TABLE_NAME");
TableInfo ti = new TableInfo(tableName, new HashMap<String, ColumnInfo>(), new ArrayList<ColumnInfo>());
tables.put(tableName, ti);
ResultSet set = dbmd.getColumns(null, "%", tableName, "%");
while (set.next()) {
ColumnInfo ci = new ColumnInfo(set.getString("COLUMN_NAME"), set.getString("TYPE_NAME"), 0);
ti.getColumns().put(set.getString("COLUMN_NAME"), ci);
}
ResultSet keySet = dbmd.getPrimaryKeys(null, "%", tableName);
while (keySet.next()) {
ColumnInfo ci2 = (ColumnInfo) ti.getColumns().get(keySet.getString("COLUMN_NAME"));
ci2.setKeyType(1);
ti.getPriKeys().add(ci2);
}
if(ti.getPriKeys().size()>0){//去唯一主键,方便使用
ti.setOnlyPriKey(ti.getPriKeys().get(0));
}
}
} catch (SQLException e) {
e.printStackTrace();
}
try {
UpdatePoFile();//根据数据库的表生成PO包下的类
loadPoTables();//加载这些类,并与表绑定起来,便于操作
} catch (IOException e) {
e.printStackTrace();
}
}
/*静态方法:调用该方法根据获得数据库表结构,更新配置po包下的类*/
public static void UpdatePoFile() throws IOException {
Map<String, TableInfo> map = TableContext.tables; //循环获得表内容
for (String Tablename : map.keySet()) {
TableInfo t = map.get(Tablename);
javaFileUtils.createJavaPoFile(t, new MysqlTypeConvertor());
}
}
public static void loadPoTables(){
for(TableInfo tableInfo:tables.values()){
try {
Class c=Class.forName(DBManger.getConf().getPopackage()+"."+ StringUtils.firstChar2UpperCase(tableInfo.getTname()));//让jvm加载po包的类
poClassTableMap.put(c,tableInfo);//将生成的类与数据库的表关联起来
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
Map<String,TableInfo> tables=TableContext.tables;
System.out.println(tables);
}
}
TypeConvertor接口:
public interface TypeConvertor {
/*将数据库数据类型转换为java类型
*columnType:数据库字段的数据类型
* return java的数据类型 */
public String databaseType2javaType(String columnType);
/*将java数据类型转换为数据库数据类型
*javaType:java内的数据类型
* return 数据库的数据类型 */
public String javaType2databaseType(String javaType);
}
MysqlTypeConvertor类实现上面接口:
/*mysql数据库和java数据类型转换,继承TypeConvertor接口*/
public class MysqlTypeConvertor implements TypeConvertor {
@Override
public String databaseType2javaType(String columnType) {
if(columnType.equalsIgnoreCase("varchar")||columnType.equalsIgnoreCase("char")){//将数据库的varchar类型转为java的String
return "String";
}else if(columnType.equalsIgnoreCase("int")||
columnType.equalsIgnoreCase("tinyint")||
columnType.equalsIgnoreCase("smallint")||
columnType.equalsIgnoreCase("integer")){return "Integer";}
else if(columnType.equalsIgnoreCase("bigint")){return "Long";}
else if(columnType.equalsIgnoreCase("double")||columnType.equalsIgnoreCase("float")){return "Double";}
else if(columnType.equalsIgnoreCase("clob")){return "java.sql.Clob";}
else if(columnType.equalsIgnoreCase("blob")){return "java.sql.Blob";}
else if(columnType.equalsIgnoreCase("date")){return "java.sql.Date";}
else if(columnType.equalsIgnoreCase("time")){return "java.sql.Time";}
else if(columnType.equalsIgnoreCase("timestamp")){return "java.sql.Timestamp";}
return null;
}
@Override
public String javaType2databaseType(String javaType) {
return null;
}
}
QueryFactory类:
(核心使用类)
/*根据配置文件创建Query对象
*工厂类是单例模式
* 使用原型模式,工厂模式 ,通过该类获得需要的Query对象*/
public class QueryFactory {
private static Query prototypeObj;
static {//静态加载配置文件的指定的Query类
try {
Class clazz=Class.forName(DBManger.getConf().getQueryClass());
prototypeObj= (Query) clazz.newInstance();
} catch (Exception e) {
e.printStackTrace();
}
}
private QueryFactory(){};
public static Query createQuery(){
try {
return (Query) prototypeObj.clone();
} catch (Exception e) {
e.printStackTrace();
return null;
}
};
}
工具类
封装了一些常用的jdbc,处理字符串,java文件操作,反射操作的方法
JDBCUtils
/*封装JDBC常用操作*/
public class JDBCUtils {
public static void handleParams(Object[] params, PreparedStatement ps){//给sql语句处理参数
if(params!=null){//有参数才进行预处理
for (int i=0; i <params.length; i++) {
try {
ps.setObject(i+1,params[i]);
} catch (SQLException e) {
e.printStackTrace();
}
}}
}
}
StringUtils
public class StringUtils {
/*将目标字符首字母变为大写
* str为目标字符串
* return 首字母变为大小的字符串*/
public static String firstChar2UpperCase(String str){
return str.toUpperCase().substring(0,1)+str.substring(1);//例如:将str全部转为大写,截取第一个字符,再拼接原str的剩余字符
}
}
JavaFileUtils类
/*封装生成java类文件(源代码)的常用操作*/
public class javaFileUtils {
/*根据字段信息生成java属性信息。如:var username-->生成private String username;以及该属性的set,get方法
* column:字段信息
* convertor:数据类型转换器
* return java属性和set/get方法源码*/
public static JavaFieldGetSet createJavaFieldGetSetSRC(ColumnInfo column, TypeConvertor convertor) {
JavaFieldGetSet jfgs = new JavaFieldGetSet();//该类封装java属性和get,set方法源代码
String javaFieldType = convertor.databaseType2javaType(column.getDataType());
jfgs.setFieldInfo("\t" + "private " + javaFieldType + " " + column.getName() + ";\n");
//生成getter的源代码,例如 public int getID(){ return id;}
StringBuilder getSrc = new StringBuilder();//StringBuilder便于拼接字符串
getSrc.append("\tpublic " + javaFieldType + " get" + StringUtils.firstChar2UpperCase(column.getName()) + "(){\n");
getSrc.append("\treturn " + column.getName() + ";}\n");
jfgs.setGetInfo(getSrc.toString());
//生成setter的源代码,例如 public int getID(){ return id;}
StringBuilder setSrc = new StringBuilder();//StringBuilder便于拼接字符串
setSrc.append("\tpublic void set" + StringUtils.firstChar2UpperCase(column.getName()) + "(" + javaFieldType + " " + column.getName() + "){\n");
setSrc.append("\tthis." + column.getName() + "=" + column.getName() + ";}\n");
jfgs.setSetInfo(setSrc.toString());
return jfgs;
}
/*根据表信息生成java类的源代码
* tableInfo:表信息
* convertor:数据类型转换器
* return java类的源代码*/
public static String createJavaSrc(TableInfo tableInfo, TypeConvertor convertor) {
StringBuilder src = new StringBuilder();
Map<String, ColumnInfo> columns = tableInfo.getColumns();
List<JavaFieldGetSet> javaFields = new ArrayList<JavaFieldGetSet>();//存储表内所有的字段
for (ColumnInfo c : columns.values()) {
javaFields.add(createJavaFieldGetSetSRC(c, convertor));
}
//开始拼接源码
//生成package语句
src.append("package " + DBManger.getConf().getPopackage() + ";\n\n");//通过DBManger类中的Conf对象得到配置文件写好的存放类的位置
//生成import语句
src.append("import java.sql.*;\n");
src.append("import java.util.*;\n\n\n");
//生成类声明语句
src.append("public class " + StringUtils.firstChar2UpperCase(tableInfo.getTname()) + " {\n");
//生成属性列表
for (JavaFieldGetSet f : javaFields) {
src.append(f.getFieldInfo());//调用上面的写好的方法得到属性信息
}
src.append("\n\n");//空行
//生成get方法列表
for (JavaFieldGetSet f : javaFields) {
src.append(f.getGetInfo());//调用上面的写好的方法得到属性信息
}
//生成set方法列表
for (JavaFieldGetSet f : javaFields) {
src.append(f.getSetInfo());//调用上面的写好的方法得到属性信息
}
//生成类结束语句
src.append("}\n");
return src.toString();
}
public static void createJavaPoFile(TableInfo tableInfo,TypeConvertor convertor) throws IOException {
String src=createJavaSrc(tableInfo, convertor);//调用上面的方法生成一张表对应的java类的源代码
String secPath=DBManger.getConf().getSrc()+"/";//得到配置文件内的src文件的地址
String packagePath=DBManger.getConf().getPopackage().replaceAll("\\.","\\\\");//得到配置文件内po包的地址,在java内一个反斜杠都要写成两个
File f=new File(secPath+"\\"+packagePath);
if(!f.exists()){
f.mkdir();
}
BufferedWriter bw=null;//通过流将源码写入文件
bw=new BufferedWriter(new FileWriter(f.getAbsoluteFile()+"\\"+StringUtils.firstChar2UpperCase(tableInfo.getTname())+".java",false));
try {
bw.write(src);
System.out.println("建立表"+tableInfo.getTname()+"对应的java类"+StringUtils.firstChar2UpperCase(tableInfo.getTname())+".java"+"到指定目录下");
} catch (IOException e) {
e.printStackTrace();
}finally {
if(bw!=null){
try {
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) throws IOException {//测试代码
// ColumnInfo ci = new ColumnInfo("id", "tinyint", 0);
// JavaFieldGetSet j = createJavaFieldGetSetSRC(ci, new MysqlTypeConvertor());
// j.toString()
Map<String,TableInfo>map= TableContext.tables; //循环获得表内容
for(String Tablename:map.keySet()){ TableInfo t=map.get(Tablename);
createJavaPoFile(t,new MysqlTypeConvertor());//根据表内容新建类,将该代码写成方法放入TableContext类中}
}
}
}
ReflectUtils
/*封装反射的的常用操作*/
public class ReflectUtils {
/*调用obj对象的某一属性的get方法*/
public static Object invokeGet(String fieldName,Object obj){
//通过反射机制,调用属性的get或set方法
try {
Class c=obj.getClass();
Method m=c.getDeclaredMethod("get"+StringUtils.firstChar2UpperCase(fieldName),null);
return m.invoke(obj,null);//调用get方法得到该属性的值
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public static void invokeSet(Object obj,String fieldName,Object fieldValue){
//通过反射机制,调用属性的get或set方法
if(fieldValue!=null){
try {
Class c=obj.getClass();
Method m=c.getDeclaredMethod("set"+StringUtils.firstChar2UpperCase(fieldName),fieldValue.getClass());
m.invoke(obj,fieldValue);//调用get方法得到该属性的值
} catch (Exception e) {
e.printStackTrace();
}}
}
}
/*封装表中一个字段的信息*/
public class ColumnInfo {
private String name;//字段名称
private String dataType;//字段数据类型
private int KeyType;//0代表非主键,1代表主键,2代表外键
public ColumnInfo() {
}
public ColumnInfo(String name, String dataType, int keyType) {
this.name = name;
this.dataType = dataType;
KeyType = keyType;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDataType() {
return dataType;
}
public void setDataType(String dataType) {
this.dataType = dataType;
}
public int getKeyType() {
return KeyType;
}
public void setKeyType(int keyType) {
KeyType = keyType;
}
}
Configuration类
public class Configuration {
private String driver;//数据库驱动
private String url;//数据库url
private String user;//数据库用户名
private String password;//数据库密码
private String src;//项目源码路径
private String popackage;//扫描后生成java类存储的包,po:Persistence object持久化对象
private String usingdb;//选择数据库类型
private String queryClass;//项目选择的查询类,即Query的一个子类
public Configuration() {//无参构造
}
public String getDriver() {
return driver;
}
public void setDriver(String driver) {
this.driver = driver;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getUser() {
return user;
}
public void setUser(String user) {
this.user = user;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getSrc() {
return src;
}
public void setSrc(String src) {
this.src = src;
}
public String getPopackage() {
return popackage;
}
public void setPopackage(String popackage) {
this.popackage = popackage;
}
public String getUsingdb() {
return usingdb;
}
public void setUsingdb(String usingdb) {
this.usingdb = usingdb;
}
public String getQueryClass() {
return queryClass;
}
public void setQueryClass(String queryClass) {
this.queryClass = queryClass;
}
}
TableInfo类
public class TableInfo {
/*表名*/
private String tname;
/*表中所有字段信息*/
private Map<String,ColumnInfo> columns;
/*唯一主键:目前只处理表中只有一个主键的情况*/
private ColumnInfo onlyPriKey;//单一主键
private List<ColumnInfo> priKeys;//联合主键
public TableInfo() {
}
public TableInfo(String tname, Map<String, ColumnInfo> columns, ColumnInfo onlyPriKey) {
this.tname = tname;
this.columns = columns;
this.onlyPriKey = onlyPriKey;
}
public TableInfo(String tname, Map<String, ColumnInfo> columns, List<ColumnInfo> priKeys) {
this.tname = tname;
this.columns = columns;
this.priKeys = priKeys;
}
public String getTname() {
return tname;
}
public void setTname(String tname) {
this.tname = tname;
}
public Map<String, ColumnInfo> getColumns() {
return columns;
}
public void setColumns(Map<String, ColumnInfo> columns) {
this.columns = columns;
}
public ColumnInfo getOnlyPriKey() {
return onlyPriKey;
}
public void setOnlyPriKey(ColumnInfo onlyPriKey) {
this.onlyPriKey = onlyPriKey;
}
public List<ColumnInfo> getPriKeys() {
return priKeys;
}
public void setPriKeys(List<ColumnInfo> priKeys) {
this.priKeys = priKeys;
}
}
JavaFieldGetSet类用于辅助JavaFileUtils类存储java属性以及getter setter的源码
/*封装java属性和get,set方法源代码*/
public class JavaFieldGetSet {
private String fieldInfo;
private String getInfo;
private String setInfo;
public String getFieldInfo() {
return fieldInfo;
}
public void setFieldInfo(String fieldInfo) {
this.fieldInfo = fieldInfo;
}
public String getGetInfo() {
return getInfo;
}
public void setGetInfo(String getInfo) {
this.getInfo = getInfo;
}
public String getSetInfo() {
return setInfo;
}
public void setSetInfo(String setInfo) {
this.setInfo = setInfo;
}
@Override
public String toString() {
System.out.println(this.getFieldInfo());
System.out.println(this.getGetInfo());
System.out.println(this.getSetInfo());
return super.toString();
}
}
如何使用该框架:
首先导入Jar包(该框架的jar包以及Mysql驱动jar包),然后编写配置文件。最后调用QueryFactory创建一个Query类实现对数据库的操作。
简单示例:
/*客户端调用的测试类*/
public class test {
public static void main(String[] args) throws ParseException {//测试单行单列查找
Query q=QueryFactory.createQuery();
Object o =q.QueryValue("select empname from emp where id=?", new Object[]{2});
System.out.println(o);
testDML();
}
public static void testQueryRows() {//测试查找语句,多行多列查找
String sql = "select empname,age from emp where id>?";
List<Emp> l = new MysqlQuery().QueryRows(sql, Emp.class, new Object[]{0});
for (Emp e : l) {
System.out.println(e.getEmpname() + e.getAge());
}
}
public static void testDML() throws ParseException {//测试DML语句
DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
Date d = df.parse("2024-08-05");
MysqlTypeConvertor mc = new MysqlTypeConvertor();
Emp e = new Emp();
e.setId(3);
e.setEmpname("test");
e.setBirthday(new java.sql.Date(d.getTime()));
MysqlQuery ms = new MysqlQuery();
ms.update(e, new String[]{"empname", "birthday"});
}
}
配置文件:
driver:com.mysql.cj.jdbc.Driver
url:jdbc:mysql://localhost:3306/sorm?useUnicode=true&characterEncoding=UTF-8&userSSL=false&serverTimezone=GMT%2B8
user:root
password:xjh1999
src:E:\\Idea workspace\\JDBC_project\\Moudel3\\src
popackage:cn.xjh.po
usingdb:mysql
queryClass:cn.xjh.sorm.core.MysqlQuery
driver:数据库驱动器
url:连接数据库的url,最后一个sorm是数据库的名字
user:数据库用户名
password:密码
src:当前项目的src目录
popackage:数据库表生成的java对象存储的包
usingdb:使用的数据库类型
queryClass:使用的Query类(目前只有MysqlQuery类,只支持mysql)
补充:如果要进行联表查询,则需要自己在po包内创建好相关的类,再调用
insert方法,将新的类当作参数传入进去。
public class EmpVO {//联合查询
//例如select e.id,e.empname ,e.salary,d.dname from emp e JOIN dept d on e.deptID=d.id
//专门建一个java bean来存放查询结果
private Integer id;
private String empname;
private Double salary;
private String dname;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getEmpname() {
return empname;
}
public void setEmpname(String empname) {
this.empname = empname;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
public String getDname() {
return dname;
}
public void setDname(String dname) {
this.dname = dname;
}
public EmpVO() {
}
}