下面是我自己在前阵子为了工作上的需要来实现的一个ROR形式的Java中的ActiveRecord框架,其实可能会有一些瑕疵,希望朋友们测试,研究后给我好的意见,我的目的是想开源出来,大家共同进步。
下面的是主框架ActiveRecord
以mysql数据库为例,给出主要类的代码:
package com.abblie.jdbc.mysql;
import com.abblie.jdbc.Base;
import com.abblie.jdbc.anno.Table;
import com.abblie.jdbc.handler.RecordHandler;
import com.abblie.jdbc.iface.BaseActiveRecord;
import com.database.pool.DBConnect;
/**
* <b>mysql数据库操作基础类封装过的方法: </b><br/>
* 查询用方法:find(tag,param) <br/>
* 添加用方法:add(obj) <br/>
* 修改用方法:edit(obj)<br/>
* 删除用方法:del(obj)<br/>
*/
public abstract class ActiveRecord extends Base implements BaseActiveRecord{
public ActiveRecord() {
super();
}
public ActiveRecord(Class clss) {
this.clss=clss;
}
public ActiveRecord(DBConnect conn) {
this.conn=conn;
}
public ActiveRecord(Class clss,String dbName) {
this.clss=clss;
this.dbName=dbName;
}
//调用数据库
public DBConnect call(String dbName) {
return super.call(dbName);
}
//调用数据库,带外连接
public DBConnect call(DBConnect conn,String dbName) {
this.conn=conn;
return call(dbName);
}
//打开数据库连接(内连接)
public DBConnect open() {
return super.open();
}
//打开数据库连接(外连接)
public DBConnect open(DBConnect conn) {
return super.open(conn);
}
//关闭数据库连接(内连接)
public void close() {
super.close();
}
//关闭数据库连接(外连接)
public void close(DBConnect conn) {
super.close(conn);
}
//查询主方法(内连接)
public Object find(int tag, Object... param) {
open();
Object obj = find_by_conn(conn, tag, param);
close();
return obj;
}
//外连接查询主方法
public Object find_by_conn(DBConnect conn,int tag, Object... param) {
Object obj = null;
switch (tag) {
case $ONE :
obj = find_reone_by_conn(conn, param);
break;
case $PAGE :
obj = find_page_by_conn(conn, param);
break;
case $ALL :
obj = find_all_by_conn(conn, param);
break;
case $SQL :
obj = find_sql_by_conn(conn, param);
break;
case $JOIN :
obj = find_join_by_conn(conn, param);
break;
case $COUNT :
obj = find_conver_by_conn(conn, $COUNT, param);
break;
case $MAX :
obj = find_conver_by_conn(conn, $MAX, param);
break;
case $MIN :
obj = find_conver_by_conn(conn, $MIN, param);
break;
case $SUM :
obj = find_conver_by_conn(conn, $SUM, param);
break;
case $AVG :
obj = find_conver_by_conn(conn, $AVG, param);
break;
case $CONVER :
obj = find_conver_by_conn(conn, param);
break;
case $SOME :
obj = find_some_by_conn(conn, param);
break;
default :
obj = find_reone_by_conn(conn, param);
break;
}
return obj;
}
//查询部分值的方法(内连接)
public Object find_some(Object... param) {
open();
Object obj = find_some_by_conn(conn, param);
close();
return obj;
}
//查询部分值的方法(外连接)
public Object find_some_by_conn(DBConnect conn, Object... param) throws NumberFormatException {
int len=param.length;
if (len < 2) {
System.out.println("是否没有设置返回标签或者查询的参数没有齐全?");
return null;
}
Object obj=null;
Table table = getTable();
int rtag = Integer.valueOf(param[0].toString());
// 当只有要求字段查询时
if (len == 2) {
String[] fields = RecordHandler.getStrs(param[1].toString());
int flen = fields.length;
sql = "SELECT ";
for (int i = 0; i < flen; i++) {
if (i == (flen - 1)) {
sql += fields[i];
} else {
sql += fields[i] + ",";
}
}
sql += " FROM " + table.name();
switch (rtag) {
case $RONE :
if (flen == 1) {
sql += " LIMIT 0,1";
obj = getOneBySql(conn, sql);
} else {
System.out.println("请求的查询条件错误,只能查询单个值对象!");
}
break;
case $ROBJ :
sql += " LIMIT 0,1";
obj = getBeanBySql(conn, sql);
break;
case $RLIST :
obj = getListBySql(conn, sql);
break;
default :
System.out.println("请求的返回类型或要求的查询字段或者参数不齐全!");
break;
}
}
// 当有sql条件查询时
if (len == 3) {
String[] fields = RecordHandler .getStrs(param[1].toString());
int flen = fields.length;
sql = "SELECT ";
for (int i = 0; i < flen; i++) {
if (i == (flen - 1)) {
sql += fields[i];
} else {
sql += fields[i] + ",";
}
}
sql += " FROM " + table.name();
switch (rtag) {
case $RONE :
if (flen == 1) {
sql += " WHERE " + param[2].toString() + " LIMIT 0,1";
obj = getOneBySql(conn, sql);
} else {
System.out.println("request is error,your input feild must be only one!");
}
break;
case $ROBJ :
sql += " WHERE " + param[2].toString() + " LIMIT 0,1";
obj = getBeanBySql(conn, sql);
break;
case $RLIST :
sql += " WHERE " + param[2].toString();
obj = getListBySql(conn, sql);
break;
default :
System.out.println("your request type or input feild or input param is error!");
break;
}
}
// 当有其它参数条件时
if (len > 3) {
String[] fields = RecordHandler .getStrs(param[1].toString());
int flen = fields.length;
sql = "SELECT ";
for (int i = 0; i < flen; i++) {
if (i == (flen - 1)) {
sql += fields[i];
} else {
sql += fields[i] + ",";
}
}
sql += " FROM " + table.name();
switch (rtag) {
case $RONE :
if (flen == 1) {
sql += " WHERE " + param[2].toString() + " LIMIT 0,1";
obj = getOneByParam2(conn, sql, param);
} else {
System.out.println("request is error,your input feild must be only one!");
}
break;
case $ROBJ :
sql += " WHERE " + param[2].toString() + " LIMIT 0,1";
obj = getBeanByParam2(conn, sql, param);
break;
case $RLIST :
sql += " WHERE " + param[2].toString();
obj = getListByParam2(conn, sql, param);
break;
default :
System.out.println("your request type or input feild or input param is error!");
break;
}
}
return obj;
}
//聚合函数(内连接)
public Object find_conver(Object... param) {
open();
Object obj=find_conver_by_conn(conn,param);
close();
return obj;
}
//聚合函数(外连接)
public Object find_conver_by_conn(DBConnect conn, Object... param) throws NumberFormatException {
int len=param.length;
if(len<1) {
System.out.println("The input params is not enough!");
return null;
}
Object obj=null;
int tags2=Integer.valueOf(param[0].toString());
switch (tags2) {
case $COUNT :
obj = doConver(conn, "COUNT", param);
break;
case $MIN :
obj = doConver(conn, "MIN", param);
break;
case $MAX :
obj = doConver(conn, "MAX", param);
break;
case $SUM :
obj = doConver(conn, "SUM", param);
break;
case $AVG :
obj = doConver(conn, "AVG", param);
break;
default :
break;
}
return obj;
}
//连接查询(内连接)
public Object find_join(Object... param) {
open();
Object obj = find_join_by_conn(conn, param);
close();
return obj;
}
public Object find_join_inner(Object... param) {
return find_join($INNER,param);
}
//连接查询(外连接)
public Object find_join_by_conn(DBConnect conn, Object... param) throws NumberFormatException {
int len=param.length;
if (len < 1) {
System.out.println("parameter is not complete");
return null;
}
Object obj=null;
int tags1 = Integer.valueOf(param[0].toString());// 采用什么连接查询
if (len==1) {
linkSql(tags1);
obj = getListBySql(conn, sql);
} else if(len==2){
linkSql(tags1);
String start = param[1].toString().toUpperCase();
if (start.startsWith("ORDER")||start.startsWith("GROUP")) {
sql += " " + param[1];
}else {
sql += " WHERE " + param[1];
}
obj = getListBySql(conn, sql);
}else if (len>2) {
//当有参数传入时
linkSql(tags1);
String start = param[1].toString().toUpperCase();
if (start.startsWith("ORDER")||start.startsWith("GROUP")) {
sql += " " + param[1];
}else {
sql += " WHERE " + param[1];
}
obj = getListByParam1(conn, sql, param);
}
return obj;
}
//SQL语句查询(内连接)
public Object find_sql(Object...param) {
open();
Object obj=find_sql_by_conn(conn,param);
close();
return obj;
}
//SQL语句查询(外连接)
public Object find_sql_by_conn(DBConnect conn, Object... param) throws NumberFormatException {
int len=param.length;
if (len < 2) {
System.out.println("输入的参数不齐全!");
return null;
}
Object obj=null;
int tags = Integer.valueOf(param[0].toString());// 返回标志位
sql = param[1].toString();
if (len == 2) {
switch (tags) {
case $RONE :
obj = getOneBySql(conn, sql);
break;
case $ROBJ :
obj = getBeanBySql(conn, sql);
break;
case $RLIST :
obj = getListBySql(conn, sql);
break;
default :
obj = getOneBySql(conn, sql);
break;
}
} else if (len > 2) {
switch (tags) {
case $RONE :
obj = getOneByParam1(conn, sql, param);
break;
case $ROBJ :
obj = getBeanByParam1(conn, sql, param);
break;
case $RLIST :
obj = getListByParam1(conn, sql, param);
break;
default :
obj = getOneByParam1(conn, sql, param);
break;
}
}
return obj;
}
//查询全部(内连接)
public Object find_all(Object... param) {
open();
Object obj=find_all_by_conn(conn, param);
close();
return obj;
}
//查询全部(外连接)
public Object find_all_by_conn(DBConnect conn, Object... param) {
Object obj=null;
int len=param.length;
Table table = getTable();
sql = "SELECT * FROM " + table.name();
if (len == 0) {
obj = getListBySql(conn, sql);
} else if (len == 1) {
String start = param[0].toString().toUpperCase();
if (start.startsWith("ORDER")||start.startsWith("GROUP")) {
sql += " " + param[0];
}else {
sql += " WHERE " + param[0];
}
obj = getListBySql(conn, sql);
} else if (len > 1) {
sql += " WHERE " + param[0];
obj = getListByParam0(conn, sql, param);
}
return obj;
}
//分页查询(内连接)
public Object find_page(Object... param) {
open();
Object obj=find_page_by_conn(conn, param);
close();
return obj;
}
//分页查询(外连接)
public Object find_page_by_conn(DBConnect conn, Object... param) throws NumberFormatException {
int len=param.length;
if (len < 2) {
System.out.println("输入的参数不齐全!");
return null;
}
Object obj=null;
Table table = getTable();
sql = "SELECT * FROM " + table.name();
int page = Integer.valueOf(param[0].toString());
int size = Integer.valueOf(param[1].toString());
if (len == 2) {
sql += " LIMIT " + size * (page - 1) + "," + size;
obj = getListBySql(conn, sql);
} else if (len == 3) {
String start = param[2].toString().toUpperCase();
if (start.startsWith("ORDER")||start.startsWith("GROUP")) {
sql += " " + param[2] + " LIMIT " + size * (page - 1)+ "," + size;
} else if(param[2].toString().length()>0){
sql += " WHERE " + param[2] + " LIMIT " + size * (page - 1) + "," + size;
}else {
sql +=param[2] + " LIMIT " + size * (page - 1) + "," + size;
}
obj = getListBySql(conn, sql);
} else if (len > 3) {
sql += " WHERE " + param[2] + " LIMIT " + size * (page - 1) + "," + size;
obj = getListByParam2(conn, sql, param);
}
return obj;
}
//返回单个值查询(内连接)
public Object find_reone(Object... param) {
open();
Object obj = find_reone_by_conn(conn, param);
close();
return obj;
}
//返回单个值查询(外连接)
public Object find_reone_by_conn(DBConnect conn, Object... param) {
Object obj=null;
int len=param.length;
Table table = getTable();
sql = "SELECT * FROM " + table.name();
if (len == 0) {
sql += " LIMIT 0,1";
obj = getBeanBySql(conn, sql);
} else if (len == 1) {
String start = param[0].toString().toUpperCase();
if ("DESC".equals(start)) {
sql += " ORDER BY " + table.key() + " DESC LIMIT 0,1";
} else if ("ASC".equals(start)) {
sql += " ORDER BY " + table.key() + " ASC LIMIT 0,1";
} else if (start.startsWith("ORDER")||start.startsWith("GROUP")) {
sql += " " + param[0] + " LIMIT 0,1";
} else {
sql += " WHERE " + param[0] + " LIMIT 0,1";
}
obj = getBeanBySql(conn, sql);
} else if (len > 1) {
sql += " WHERE " + param[0] + " LIMIT 0,1";
obj = getBeanByParam0(conn, sql, param);
}
return obj;
}
/**
* @param obj
* @param len
* @param param
* @return
*/
private Object doConver(DBConnect conn, String type, Object... param) {
int len=param.length;
Object obj=null;
Table table = getTable();
if (len == 1) {
sql = "SELECT "+type+"("+table.key()+") AS ONE FROM "+table.name();
obj=getOneBySql(conn, sql);
}else if (len == 2) {
sql = "SELECT "+type+"("+param[1].toString()+") AS ONE FROM "+table.name();
obj=getOneBySql(conn, sql);
}else if (len==3) {
sql = "SELECT "+type+"("+param[1].toString()+") AS ONE FROM "+table.name()+" "+param[2].toString();
obj=getOneBySql(conn, sql);
}else if(len >3){
sql = "SELECT "+type+"("+param[1].toString()+") AS ONE FROM "+table.name()+" "+param[2].toString();
obj = getOneByParam2(conn, sql, param);
}
System.out.println(sql);
return obj;
}
public int save(int tag, Object... param) {
open();
int i = save_by_conn(conn, tag, param);
close();
return i;
}
/**
* 添加 修改 删除
*
* @param tag
* @param param
* @return int
*/
public int save_by_conn(DBConnect conn,int tag, Object... param) {
int rel = 0;
table = getTable();
switch (tag) {
case $ADD :
// ADD
rel = execute(conn, TSql.addSQL(clss, param[0]));
break;
case $MOD :
// EDIT
rel = execute(conn, TSql.editSQL(clss, param[0]));
break;
case $DEL :
// DEL
rel = execute(conn, TSql.delSQL(clss, Integer.valueOf(param[0].toString())));
break;
default :
break;
}
return rel;
}
// 其它操作接口
public int add_by_conn(DBConnect conn,Object... param) {
return save_by_conn(conn,$ADD, this, param);
}
public int add(Object... param) {
return save($ADD, this, param);
}
public int mod_by_conn(DBConnect conn,Object... param) {
return save_by_conn(conn,$MOD, this, param);
}
public int mod(Object... param) {
return save($MOD, this, param);
}
public int del_by_conn(DBConnect conn,Object id, Object... param) {
return save_by_conn(conn,$DEL, id, param);
}
public int del(Object id, Object... param) {
return save($DEL, id, param);
}
private void linkSql(int tags1) {
switch (tags1) {
case $LEFT :// 左连接
sql = TSql.linkSql(clss, $LEFT);
break;
case $RIGHT :// 右连接
sql = TSql.linkSql(clss, $RIGHT);
break;
case $INNER :// 内连接
sql = TSql.linkSql(clss, $INNER);
break;
case $OUTER :// 外连接
sql = TSql.linkSql(clss, $OUTER);
break;
case $CROSS :// 交叉连接
sql = TSql.linkSql(clss, $CROSS);
break;
default :
break;
}
}
}
时间关系,以后慢慢介绍。
下面给出我的项目中调用这个框架的部分代码以用参考。目的只想大家能把这个框架用起来,不断改进,不断优化。以达到让Java的敏捷开发。
主要Action中代码:CompanyAction.java
package action;
import com.util.lang.StringUtil;
import bean.Company;
@SuppressWarnings("serial")
public class CompanyAction extends BaseAction {
private Company company;
public CompanyAction() {
company = new Company();
}
public String list() {
tag("list");
set("list", company.find_all());
return SUCCESS;
}
public String toadd() {
tag("toadd");
set("list", company.find_all());
return SUCCESS;
}
public String add() {
tag("toadd");
// 检查输入
if (StringUtil.isEmpty(company.getCname())) {
set("list", company.find_all());
msg("公司名称不能为空!");
return SUCCESS;
}
company.add();
msg("公司添加成功!");
return list();
}
public String tomod() {
tag("tomod");
set("list", company.find_all());
company = (Company) company.find_reone("id=?", get("id"));
return SUCCESS;
}
public String mod() {
tag("mod");
// 检查输入
if (StringUtil.isEmpty(company.getCname())) {
set("list", company.find_all());
msg("公司名称不能为空!");
return SUCCESS;
}
if (company.getId()==company.getPid()) {
set("list", company.find_all());
msg("上级公司不能选择本公司!");
return SUCCESS;
}
company.mod();
msg("公司修改成功!");
return list();
}
public String del() {
company.del(get("id"));
msg("公司删除成功!");
return list();
}
public Company getCompany() {
return company;
}
public void setCompany(Company company) {
this.company = company;
}
}
对应的Bean类代码是:Company.java
package bean;
import java.io.Serializable;
import com.abblie.jdbc.anno.Table;
import com.abblie.jdbc.mysql.ActiveRecord;
@SuppressWarnings("serial")
@Table(name = "company", key = "id")
public class Company extends ActiveRecord implements Serializable {
private int id;
private int pid;
private String cname;
private String address;
private String logo;
private String website;
private String note;
public String getLogo() {
return logo;
}
public String getWebsite() {
return website;
}
public void setLogo(String logo) {
this.logo = logo;
}
public void setWebsite(String website) {
this.website = website;
}
public String getAddress() {
return address;
}
public String getCname() {
return cname;
}
public int getId() {
return id;
}
public String getNote() {
return note;
}
public void setAddress(String address) {
this.address = address;
}
public void setCname(String cname) {
this.cname = cname;
}
public void setId(int id) {
this.id = id;
}
public void setNote(String note) {
this.note = note;
}
public int getPid() {
return pid;
}
public void setPid(int pid) {
this.pid = pid;
}
}
后面是相关包,包中有原代码可以查看,直接导入Eclipse就行了。
有两个配置文件要给出:
web.prop
[configfile]
dbconfigfile=server_db.prop
server_db.prop
[dbconfig] dblist=server logfile=d:\\server.log dbdefault=server sqlout=true [server] url=jdbc:mysql://localhost/server?useUnicode=true&characterEncoding=UTF-8 username=root password=111111 maxconn=10 driver=org.gjt.mm.mysql.Driver