继往开来 吐故纳新
日历
网志分类
· 所有网志 (990)
· 个人作品 (62)
· 软件设计 (33)
· 面向对象编程 (22)
· JavaAPI (39)
· Java开源工具 (31)
· Swing (34)
· Java语法细节 (39)
· 样式表CSS (12)
· XML (10)
· J2EE(JavaEE) (23)
· 算法数据结构 (64)
· 正则表达式 (4)
· 软件知识 (6)
· Java线程 (9)
· Web开发.Jsp/Servlet/Struts (20)
· 程序随想录 (7)
· Spring (5)
· Hibernate (7)
· J2SE 高级 (2)
· J2SE 高级 (0)
· Web开发.Ajax (16)
· Web开发.JavaScript (43)
· DB4O (2)
· Web开发.CSS/Html (22)
· C# (20)
· ERP (4)
· JDBC (1)
· 编程资源 (16)
· 编程感悟 (29)
· DB/Sql (13)
· VB (29)
· VC (2)
· 桌面脚本 (3)
· 新兴软件 (3)
· 英语学习 (21)
· 网文转载 (159)
· 职场风云 (39)
· 诗词歌赋 (32)
· 生活感言 (77)
· 奇文共赏 (13)
· 财经纵横 (6)
· 未分类 (11)
站内搜索
友情链接
· 歪酷博客
· 我的歪酷 非非共享界
· 偶要雷锋
· 豆瓣
· nczonline
· 当当网
· easyjf中文站
· Donews
· 天极Java文章列表
· W3CSchool
· taiten的BLOG
· Dojo中国
· Dojo
· Extjs.com
· Lifehack中文网志
· JaveEye的一个AS专题
· Banq's JDon
· Java 中文网址大全
· 梦想Java
· 360Doc个人图书馆
· java开源大全
· 我在硅谷动力的软件下载站
· 站长中国
· 随意贴
· CSS教学素材站
· java 参考中文站
· 面向构件与SOA社区
· 彩字生成
· 派派小说论坛
· 如坐春风
· 英语学习网
· BBC CHina
· www.dlbang.com
· 古文竖排格式在线转化工具
· 免费家谱
· 图片上传基地
· 风景壁纸
· 和风细雨
· MyC#BlogInCsdn

订阅 RSS

0207495

歪酷博客

开此博一为经验积累,二为资料收集,三为同道交流,四为资源共享.
« 上一篇: 文须有利于天下 下一篇: 代码大全摘录-与所有程序员共勉 »
Junglesong @ 2006-04-25 13:44

在程序中写SQL语句是我们通常用于访问数据库的方法,但这种方式和OO是不兼容的,有很多弊端,但O/R Mapping有时又有点庞大,本人制作了几个类,希望和大家探讨一下一种新方法的可行性。讲述在下面,请大家保持耐心。

先把类代码贴上来:
// SqlMaker:这个类构成SQL语句的主体。
import java.util.HashMap;
import java.util.Iterator;

public class SqlMaker{
  protected String selectPart="";
  protected String orderPart="";
  protected HashMap condiions=new HashMap(); 
 
  public void addCondition(String key,Condition value){
    condiions.put(key,value);
  }
 
  public void refreshCondition(String key,Object value){
    condiions.remove(key);
    condiions.put(key,value);
  }
 
  public String getAllSql(){
    String allSql="";
    allSql+=selectPart;
   
    allSql+=" where ";   
    Iterator it = condiions.values().iterator();
      while (it.hasNext()) {
          Object value = it.next();
         
          if(value instanceof SqlMaker){
            allSql+="("+((SqlMaker)value).getAllSql()+")";
          }
          else{      
            allSql+=((Condition)value).getSql();
          }
      }

      allSql+=" 1=1 "; 
    allSql+=orderPart;
    return allSql;
  }

  public HashMap getCondiions() {
    return condiions;
  }
  public void setCondiions(HashMap condiions) {
    this.condiions = condiions;
  }
  public String getOrderPart() {
    return orderPart;
  }
  public void setOrderPart(String orderPart) {
    this.orderPart = orderPart;
  }
  public String getSelectPart() {
    return selectPart;
  }
  public void setSelectPart(String selectPart) {
    this.selectPart = selectPart;
  }
}


// Condition类:这个类构成每个小条件
public class Condition{
  private String field="";
  private String operator="";
  private Object value="";
 
  public static final String OPRT_Photocopy=" =";
  public static final String OPRT_Equal="=";
  public static final String OPRT_BigThan=">=";
  public static final String OPRT_LessThan="<=";
  public static final String OPRT_Like="like";
  public static final String OPRT_In="in";
 
  public Condition(String field,String operator,Object value){
    this.field=field;
    this.operator=operator;
    this.value=value;
  }
 
  public String getSql(){
    String retval="";
   
    if(value instanceof SqlMaker){
      retval+=field+" ";
      retval+=operator+" ";  
      retval+="("+((SqlMaker)value).getAllSql()+") and ";

    }  
    else{
      retval+=field+" ";
     
      if(operator.equals(OPRT_Photocopy)){
        retval+=operator+" ";  
        retval+=value+" and ";
      }
      else{
        retval+=operator+" '";   
        retval+=value+"' and ";
      }
      if(((String)value).length()<1) retval="";
    }  
   
    return retval;
  }
 
  public String getField() {
    return field;
  }

  public void setField(String field) {
    this.field = field;
  }

  public String getOperator() {
    return operator;
  }

  public void setOperator(String operator) {
    this.operator = operator;
  }
}

这里是三个表的原数据:






调用方法如下:
    // Eg.01 :这一段是一个Select加一个where
    SqlMaker sqlBook=new SqlMaker();
    // Setup Sql Logic
    sqlBook.setSelectPart("select NAME, TYPE, AUTHOR, BRIEF from BOOK");
    sqlBook.addCondition("NAME",new Condition("NAME",Condition.OPRT_Equal,""));
    sqlBook.addCondition("AUTHOR",new Condition("AUTHOR",Condition.OPRT_Like,""));
   
    
    // Add Condition
    sqlBook.refreshCondition("NAME",new Condition("NAME",Condition.OPRT_Equal,"d"));
    sqlBook.refreshCondition("AUTHOR",new Condition("AUTHOR",Condition.OPRT_Like,"d%"));
   
    // Get Sql
    String bookSql=sqlBook.getAllSql();
    System.out.println("bookSql="+bookSql);
     输出:bookSql=select NAME, TYPE, AUTHOR, BRIEF from BOOK where AUTHOR like 'd%' and NAME = 'd' and  1=1 

    
    // Eg.02:这一段是一个Select加两个where
    SqlMaker sqlTank=new SqlMaker();
    // Setup Sql Logic
    sqlTank.setSelectPart("select NAME, NATION, WEIGHT, PRODUCTTIME from TANKS");
    sqlTank.addCondition("WEIGHTFROM",new Condition("WEIGHT",Condition.OPRT_BigThan,""));
    sqlTank.addCondition("WEIGHTTO",new Condition("WEIGHT",Condition.OPRT_LessThan,""));
    sqlBook.addCondition("BRIEF",new Condition("BRIEF",Condition.OPRT_Equal,""));

    // Add Condition
    sqlTank.refreshCondition("WEIGHTFROM",new Condition("WEIGHT",Condition.OPRT_BigThan,"30"));
    sqlTank.refreshCondition("WEIGHTTO",new Condition("WEIGHT",Condition.OPRT_LessThan,"60"));
   
    // Get Sql
    System.out.println("TankSql="+sqlTank.getAllSql());
    输出:TankSql=select NAME, NATION, WEIGHT, PRODUCTTIME from TANKS where WEIGHT >= '30' and WEIGHT <= '60' and  1=1 
    

    // Eg.03:复合查询例子
    SqlMaker sqlTank2=new SqlMaker();
    // Setup Sql Logic
    sqlTank2.setSelectPart("select NAME, NATIONS.NATION, WEIGHT, PRODUCTTIME from TANKS,NATIONS");
    sqlTank2.addCondition("NATIONOUUTERLINK",new Condition("TANKS.NATION",Condition.OPRT_Photocopy,"NATIONS.ID(+)"));
    sqlTank2.addCondition("WEIGHTFROM",new Condition("WEIGHT",Condition.OPRT_BigThan,""));
    sqlTank2.addCondition("WEIGHTTO",new Condition("WEIGHT",Condition.OPRT_LessThan,""));
   
    // Add Condition
    sqlTank2.refreshCondition("NATION",new Condition("NATIONS.NATION",Condition.OPRT_Equal,"Germany"));
    sqlTank2.refreshCondition("WEIGHTFROM",new Condition("WEIGHT",Condition.OPRT_BigThan,"30"));
    sqlTank2.refreshCondition("WEIGHTTO",new Condition("WEIGHT",Condition.OPRT_LessThan,"60"));
   
    // Get Sql
    System.out.println("TankSql2="+sqlTank2.getAllSql());   
    输出:TankSql2=select NAME, NATIONS.NATION, WEIGHT, PRODUCTTIME from TANKS,NATIONS where WEIGHT >= '30' and TANKS.NATION  = NATIONS.ID(+) and NATIONS.NATION = 'Germany' and WEIGHT <= '60' and  1=1 


    // Eg.04:子查询例子
    SqlMaker sqlTank3=new SqlMaker();
    // Setup Sql Logic
    sqlTank3.setSelectPart("select NATION from TANKS ");   
    SqlMaker subSql=new SqlMaker();
    subSql.setSelectPart("select distinct id from nations");   
    sqlTank3.addCondition("Nation",new Condition("NATION",Condition.OPRT_In,subSql));  
   
    // Get Sql
    System.out.println("TankSql3="+sqlTank3.getAllSql());
   输出:TankSql3=select NATION from TANKS  where NATION in (select distinct id from nations where  1=1 ) and  1=1 


这个设计的基本思想是将SQl语句中的“select .....where......Order by...”三部分分开,select 和Order 部分一般比较简单,这里用String来存储,也保持了原SQL的简单性,where部分比较复杂,但经分析大多是  key operator  value的形式,因此用Condition类来描述它,多个Condition保存在SqlMaker类中,用遍历来生成整个Where部分,同时也可以消除了许多复杂的分支。用户最后调用SqlMaker.getAllSql()可以得到完整的SQL语句.

基本调用过程详述

   // 新建一个SqlMaker 类的实例sqlBook,用于Book表的查询
    SqlMaker sqlBook=new SqlMaker();

    // 这里是初始化部分,一般按最长的SQL语句书写
    sqlBook.setSelectPart("select NAME, TYPE, AUTHOR, BRIEF from BOOK");// 建立Sql语句的select部分
    sqlBook.addCondition("NAME",new Condition("NAME",Condition.OPRT_Equal,""));// 添加条件一
    sqlBook.addCondition("AUTHOR",new Condition("AUTHOR",Condition.OPRT_Like,""));// 添加条件二   
    
    // 这里是临时赋值部分,根据View的传值进行变化
    sqlBook.refreshCondition("NAME",new Condition("NAME",Condition.OPRT_Equal,"d"));// 为条件一赋值
    sqlBook.refreshCondition("AUTHOR",new Condition("AUTHOR",Condition.OPRT_Like,"d%"));// 为条件二赋值
    
    // 得到最终的SQL语句
    String bookSql=sqlBook.getAllSql();// 得到最终的SQL语句
    System.out.println("bookSql="+bookSql);// 输出



本文系原创文章,转载请注明出处。








最新评论


beyond.name

2006-04-27 16:11 网址: http://beyond.name

真是不错!
谢谢!!!


评论 / 个人网页 / 扔小纸条
* 昵称

已经注册过? 请登录

新用户请先注册 以便能显示头像及追踪评论回复

Email
网址
* 评论
表情
 


 

分类小组论坛
杂谈 , 娱乐、八卦 , 文学、艺术 , 体育 , 旅游、同城 , 象牙塔 , 情感 , 时尚、生活 , 星座 , 科技

请注意遵守中华人民共和国法律法规, 如威胁到本站生存, 将依法向有关部门报告, 同时本站的相关记录可能成为对您不利的证据.

相关法律法规
全国人大常委会关于维护互联网安全的决定
中华人民共和国计算机信息系统安全保护条例
中华人民共和国计算机信息网络国际联网管理暂行规定
计算机信息网络国际联网安全保护管理办法
计算机信息系统国际联网保密管理规定