利用引语定义SQL语句,实现类是iBatis的数据库访问

利用注解定义SQL语句,实现类是iBatis的数据库访问
import java.lang.annotation.*;


@Target({ElementType.METHOD,ElementType.TYPE})   //用于 方法
@Retention(RetentionPolicy.RUNTIME) //在运行时加载到Annotation到JVM中
public @interface SqlDef {   
    String sql();    //定义一个 SQL 语句
    String name() default "";
}

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.HashMap;

import javax.persistence.NamedAttributeNode;


@Target({ElementType.TYPE})   //用于 方法
@Retention(RetentionPolicy.RUNTIME) //在运行时加载到Annotation到JVM中
public @interface SqlDefs {

SqlDef[] defs() default {};

}



import java.lang.reflect.Method;
import java.util.HashMap;

@SqlDefs(defs={@SqlDef(name="update",
      sql="update g_product set name=${name},version=#{version} where id=${id}"),
   @SqlDef(name="insert",
      sql="insert into g_product (name,version) values (${name},${version}"),
   @SqlDef(name="delete",
      sql="delete from g_product where id=${id}"),
   @SqlDef(name="selectAll",
      sql="select * from g_product"),
   @SqlDef(name="findOne",
      sql="select * from g_product where id=${id}"),
   })
public class SqlService {

protected Sql dao;

public SqlService(Sql dao){
this.dao=dao;
}

/**
* 获取 SQL 语句
* @param method_name  方法名称
* @param types        方法的参数类别  
* @return
*/
public String getSqlCommand(String sqlId){
String sql=null;
try{
Class<? extends SqlService> cls=this.getClass();
if(cls.isAnnotationPresent(SqlDefs.class)){
SqlDefs sm=(SqlDefs) cls.getAnnotation(SqlDefs.class);
SqlDef[] mps=sm.defs();
for(int i=0;i<mps.length;i++){
// System.out.println(mps[i].name()+"\t"+mps[i].sql());
if(sqlId.equalsIgnoreCase(mps[i].name())){
sql = mps[i].sql();
break;
}
}

    }catch(Exception e){
    e.printStackTrace();
    }
return sql;
}


/**
* 获取 SQL 语句
* @param method_name  方法名称
* @param types        方法的参数类别  
* @return
*/
public String getSqlCommand(String method_name,Class []types){
String sql=null;
try{
Class cls=this.getClass();
    Method method = cls.getMethod(method_name,types);
    if(method.isAnnotationPresent(SqlDef.class)){
    SqlDef ad = method.getAnnotation(SqlDef.class);
    sql=ad.sql();
    }   
    }catch(Exception e){
    e.printStackTrace();
    }

return sql;
}


@SqlDef(sql="update g_product set name=${name},version=#{version} where id=${id} ")
public int sampleUpdate(int id, String name,int version){

Class []type={int.class,String.class,int.class};

String sql=getSqlCommand("sampleUpdate",type);
if(sql==null){
return -1;
}
HashMap<String,Object> ps=new HashMap<String,Object>();
ps.put("id", id);
ps.put("name", name);
ps.put("version", version);

    int r=dao.update(sql, ps);
    return r;
}

public void testSql(int id, String name,int version){
HashMap<String,Object> ps=new HashMap<String,Object>();
ps.put("id", id);
ps.put("name", name);
ps.put("version", version);

}


public static void main(String []args){

SqlService sb=new SqlService(null);
String sql=sb.getSqlCommand("update_");
System.out.println(sql);

}


}


import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

import javax.sql.DataSource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.PreparedStatementSetter;
import org.springframework.jdbc.datasource.DataSourceUtils;

public class Sql {
protected Logger log = LoggerFactory.getLogger(Sql.class);

DataSource ds;
JdbcTemplate db ;

public Sql(DataSource ds){
this.ds=ds;
this.db = new JdbcTemplate(ds);
}

/**
* 更新操作, sql 中用 #{param_name}, 或者 ${param_name} 代表参数, ${param} 作为 SQL 语句的一部分
* @param sql
* @param param
* @return
*/
public int tUpdate(String sql,final HashMap<String,Object> param){
int ret=0;
long t=System.currentTimeMillis();
final ArrayList<String> pList=new ArrayList<String>();
String sqlCmd=getSqlCmd(sql,param,pList);
try{
ret=db.update(sqlCmd,new PreparedStatementSetter(){
public void setValues(PreparedStatement ps) throws SQLException{
Object v;
String key;
for(int i=0;i<pList.size();i++){
key=pList.get(i); 
v=param.get(key);
ps.setObject(i+1, v);
}
}
});
}catch(Exception e){
log.error("Update_sql["+sqlCmd+"]", e);
}
t=System.currentTimeMillis()-t;
log.debug("Exec_sql["+sqlCmd+"],time="+t);

return ret;
}

/**
* 更新操作, sql 中用 #{param_name}, 或者 ${param_name} 代表参数, ${param} 作为 SQL 语句的一部分
* @param sql
* @param param
* @return
*/
public int update(String sql,HashMap<String,Object> param){
int ret=0;
Connection con=null;
PreparedStatement st=null;
long t=System.currentTimeMillis();

ArrayList<String> pList=new ArrayList<String>();
String sqlCmd=getSqlCmd(sql,param,pList);

try{
con=DataSourceUtils.doGetConnection(ds);
st=con.prepareStatement(sqlCmd);
Object v;
String key;
for(int i=0;i<pList.size();i++){
key=pList.get(i); 
v=param.get(key);
st.setObject(i+1, v);
}
ret=st.executeUpdate();
}catch(Exception e){
log.error("Update_sql["+sqlCmd+"]", e);
}finally{
try{
if(st!=null){
st.close();
}
}catch(Exception e){}
try{
if(con!=null){
con.close();
//DataSourceUtils.doCloseConnection(con, ds);
}
}catch(Exception e){
log.error("Close Exception:", e);
}
}
t=System.currentTimeMillis()-t;
log.debug("Exec_sql["+sqlCmd+"],time="+t);

return ret;
}

public JResult select(String sql,HashMap<String,Object> param){
JResult rs=null;
Connection con=null;
PreparedStatement st=null;
long t=System.currentTimeMillis();

ArrayList<String> pList=new ArrayList<String>();
String sqlCmd=getSqlCmd(sql,param,pList);
ResultSet set=null;
try{
con=DataSourceUtils.doGetConnection(ds);
st=con.prepareStatement(sqlCmd);
Object v;
String key;
for(int i=0;i<pList.size();i++){
key=pList.get(i); 
v=param.get(key);
st.setObject(i+1, v);
}
set=st.executeQuery();
ResultSetMetaData met=set.getMetaData();
List<String[]> ls=new ArrayList<String[]>();
int num=met.getColumnCount();
String []cols=new String[num];
for(int i=0;i<cols.length;i++){
cols[i]=met.getColumnName(i+1);
}
ls.add(cols);
while(set.next()){
cols=new String[num];
for(int i=0;i<cols.length;i++){
cols[i]=set.getString(i+1);
}
ls.add(cols);
}
rs=new JResult(ls);
}catch(Exception e){
log.error("Update_sql["+sqlCmd+"]", e);
}finally{
try{
if(set!=null){
set.close();
}
if(st!=null){
st.close();
}
}catch(Exception e){}
try{
if(con!=null){
DataSourceUtils.doCloseConnection(con, ds);
}
}catch(Exception e){
log.error("Close Exception:", e);
}
}
t=System.currentTimeMillis()-t;
log.debug("Exec_sql["+sqlCmd+"],time="+t);

return rs;
}

/**
* 处理 sql , 获取 sql 中的参数名称, 将 #{p_name} 中的 p_name 加入到 pList, 且 将 #{p_name} 替换为  ? ;
* 将  ${p_name} 替换为具体的值 , p_name 不加入到 pList
* @param sql
* @param param
* @param ps
* @return
*/
public static String getSqlCmd(String sql,HashMap<String,Object> param,ArrayList<String> pList){
if(param==null || param.size()==0){
return sql;
}
StringBuilder sb=new StringBuilder();
pList.clear();
char c;
String key=null;
int i=0;
while(i<sql.length()){
key=null;
c=sql.charAt(i);
if(c=='#' || c=='$'){
if(i+1<sql.length()){
char t=sql.charAt(i+1);
if(t=='{'){
key=getKey(sql,i+1);
}
}
}
if(key!=null){
i+=key.length()+3;
if(c=='$'){ //替换为值
Object v=param.get(key);
if(v==null){
sb.append("null");
}else{
if(v instanceof Number){
sb.append(v.toString());
}else{
sb.append('\'');
if( v instanceof Date ){
sb.append(getTM((java.util.Date)v));
}else{
if( v instanceof Calendar ){
sb.append(getTM((Calendar)v));
}else{
sb.append(v.toString());
}
}
sb.append('\'');
}
}
}else{ //'#' 替换为参数
sb.append('?');
pList.add(key);
}
}else{
sb.append(c);
i++;
}
}
return sb.toString();
}

public static String getKey(String msg,int from){
int i=from+1;
int to=-1;
char c;
String key=null;
while(i<msg.length()){
c=msg.charAt(i);
if(c=='}'){
to=i;
break;
}
i++;
}
if(to>0){
key=msg.substring(from+1, to);
}
return key;
}

public static String getTM(Date d){
DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 
String s = df.format(d);
return s;
}

public static String getTM(Calendar c){
DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 
String s = df.format(new Date(c.getTimeInMillis()));  
return s;
}



}
1 楼 白云天 23 小时前  
还可以吗?