`

利用注解定义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 楼 白云天 2014-06-26  
还可以吗?

相关推荐

    SpringBoot项目整合MyBatis连接数据库

    在我们日常的开发过程中,肯定不可避免的会使用到数据库以及SQL语句。比如,刚开始学习Java的时候可能会遇到JDBC,它是连接Java和数据库的桥梁,我们可以使用JDBC来建立与数据库之间的连接并且执行相应的SQL语句。...

    mybatis 最佳实践

    MyBatis 的前身是 iBatis 。是一个数据持久层(ORM)框架。至今,MyBatis 源 码内的包名仍在使用 org.apache.ibatis。 MyBatis 是支持普通 SQL 查询,存储过程和高级映射的优秀...的配合数据库和 sql 语句来开发项目。

    mybatis教案

    Mybatis通过xml或注解的方式将要执行的各种statement(statement、preparedStatemnt、CallableStatement)配置起来,并通过java对象和statement中的sql进行映射生成最终执行的sql语句,最后由mybatis框架执行sql并将...

    Step By Step写测试(书签版).pdf

    5.11 执行SQL语句(Execute) 5.12 commit&rollback; 5.13 其它命令 5.14 事务管理 5.15 Martini项目下的ibatis文件配置 5.16 数据库测试FAQ 6 Spring和SQL跟踪 6.1 @Tracer 6.2 FAQ 7 JTester插件的使用 7.1 插件功能...

    java,mybiats总结

    Mybatis通过xml或注解的方式将要执行的各种statement(statement、preparedStatemnt、CallableStatement)配置起来,并通过java对象和statement中的sql进行映射生成最终执行的sql语句,最后由mybatis框架执行sql并将...

    Mybatis学习笔记整合架构

    Mybatis通过xml或注解的方式将要执行的各种statement(statement、preparedStatemnt、CallableStatement)配置起来,并通过java对象和statement中的sql进行映射生成最终执行的sql语句,最后由mybatis框架执行sql并将...

    springmybatis

    其实还有更简单的方法,而且是更好的方法,使用合理描述参数和SQL语句返回值的接口(比如IUserOperation.class),这样现在就可以至此那个更简单,更安全的代码,没有容易发生的字符串文字和转换的错误.下面是详细...

    Spring中文帮助文档

    11.2.6. 执行SQL语句 11.2.7. 执行查询 11.2.8. 更新数据库 11.2.9. 获取自动生成的主键 11.3. 控制数据库连接 11.3.1. DataSourceUtils类 11.3.2. SmartDataSource接口 11.3.3. AbstractDataSource类 ...

    Spring API

    11.2.6. 执行SQL语句 11.2.7. 执行查询 11.2.8. 更新数据库 11.2.9. 获取自动生成的主键 11.3. 控制数据库连接 11.3.1. DataSourceUtils类 11.3.2. SmartDataSource接口 11.3.3. AbstractDataSource类 ...

    spring chm文档

    11.2.6. 执行SQL语句 11.2.7. 执行查询 11.2.8. 更新数据库 11.3. 控制数据库连接 11.3.1. DataSourceUtils类 11.3.2. SmartDataSource接口 11.3.3. AbstractDataSource类 11.3.4. ...

    Spring-Reference_zh_CN(Spring中文参考手册)

    11.2.6. 执行SQL语句 11.2.7. 执行查询 11.2.8. 更新数据库 11.3. 控制数据库连接 11.3.1. DataSourceUtils类 11.3.2. SmartDataSource接口 11.3.3. AbstractDataSource类 11.3.4. SingleConnectionDataSource类 ...

    Spring 2.0 开发参考手册

    11.2.6. 执行SQL语句 11.2.7. 执行查询 11.2.8. 更新数据库 11.3. 控制数据库连接 11.3.1. DataSourceUtils类 11.3.2. SmartDataSource接口 11.3.3. AbstractDataSource类 11.3.4. ...

    jfinalpluginsjfinal-dreampie.zip

    cn.dreampie.jfinal-sqlinxml  https://github.com/Dreampie/jfinal-sqlinxml 基于jfinal 的类似ibatis的sql语句管理方案 cn.dreampie.jfinal-lesscss  https://github.com/Dreampie/jfinal-lesscss java...

Global site tag (gtag.js) - Google Analytics