/**

*

* 拼接Where的指令,较简单的where组装,如果复杂的请在模版直接写where 语句

* @author xianyl

* @since 2018年1月26日-下午8:57:02

*/

public class WhereDirective extends Directive {

//运算符号集合、逻辑符号集合、between条件集合,字段名

public static final String KV_SIGNS = "kv_signs";

public static final String KV_LOGICS = "kv_logics";

public static final String KV_BETWEEN = "kv_between";

public void exec(Env env, Scope scope, Writer writer) {

SqlPara sqlPara = (SqlPara)scope.get("_SQL_PARA_");//SqlKit.SQL_PARA_KEY 需要跟它一致

if (sqlPara == null) {

throw new TemplateException("#where directive invoked by getSqlPara(...) method only", location);

}

//获取参数

Map data = null;

Kv signs = null, logics = null, between = null;

try {

Record record = (Record)exprList.eval(scope);

data = record.getColumns();

signs = (Kv) data.remove(KV_SIGNS);

logics = (Kv) data.remove(KV_LOGICS);

between = (Kv) data.remove(KV_BETWEEN);

} catch (Exception e) {

}

//判断参数不能为null 并且只能是Record

if(MapUtils.isEmpty(data)) return;

StringBuilder sb = new StringBuilder();

//循环拼接参数

Object logic;

Object sign;

for(Entry d : data.entrySet()){

Object _end = null;

//判断逻辑符号

if(logics == null){

logic = LogicsSymbol.And;//没有逻辑符号集合,这是and

}else{

logic = logics.get(d.getKey());

if(logic == null){

logic = LogicsSymbol.And;//没有对应字段的逻辑符号,这是and

}

}

//判断运算符号

if(signs == null){

sign = SignsSymbol.Eq;//没有运算符号集合,这是eq

}else{

sign = signs.get(d.getKey());

if(sign == null){

//没有对应字段的运算符号,这是eq

sign = SignsSymbol.Eq;

}

if(sign == SignsSymbol.Between){

//如果是between运算符号,需要检查between里面的field_end的数据取出

_end = between == null ? null : between.get(d.getKey() + "_end");

}

}

//拼接条件

this.join(sb,sqlPara,d.getKey(),d.getValue(),logic,sign,_end);

}

//写where

write(writer, sb.toString());

}

/**

* 拼接其中一个条件语句

* @param sb

* @param sqlPara

* @param key  字段名

* @param value 字段值

* @param logic 逻辑符号

* @param sign 运算符号

* @param _end between时字段的第二个值

*/

private void join(StringBuilder sb, SqlPara sqlPara, String key, Object value, Object logic, Object sign, Object _end) {

//第一时间判断_end 是否为null, 如果是 SignsSymbol.Between 转成 SignsSymbol.Gte

if(sign == SignsSymbol.Between && _end == null){

sign = SignsSymbol.Gte;

}

//拼接逻辑符号

if(sb.length() == 0){

if(logic == LogicsSymbol.And){

sb.append(" where ");

}else{

sb.append(" where 1=1 ").append(logic);

}

}else{

sb.append(" ").append(logic);

}

//拼接参数

sb.append(" ").append(key).append(" ").append(sign).append(" ").append("?");

sqlPara.addPara(sign == SignsSymbol.Like ? "%"+value+"%" :value);

if(sign == SignsSymbol.Between){

//如果between

sb.append(" and ").append("?");

sqlPara.addPara(_end);

}

}

}模版 :

#namespace("user")

#sql("list")

select * from user #where(data)

#end

#end

java调用方法:

/**

* 根据模板动态生成 sql 跟参数

* @param key  模板名 namespace.sql

* @param record 查询条件 键值对

* @param signs 运算符号集合  {"field":SignsSymbol.Gt} , 如果没有,则为Eq

* @param logics 逻辑符号集合 {"field":LogicsSymbol.And}, 如果没有,则为Or

* @param between between条件集合 {"field_end":value}, signs为between时检查这个,如果没有指定的field_end,则转为Gte运算符号

* @return

*/

public SqlPara getSqlPara(String key, Record data, Kv signs, Kv logics, Kv between){

//这几个字段名需要跟WhereDirective里面的对应起来

data.set(WhereDirective.KV_SIGNS, signs);

data.set(WhereDirective.KV_LOGICS, logics);

data.set(WhereDirective.KV_BETWEEN, between);

//data跟sql模版的参数对应起来

return Db.getSqlPara(key, Kv.by("data", data));

}

mysql where 拼接_分一个mysql拼接where语句的Directive,并请教一个问题相关推荐

  1. mysql炸包_炸裂!MySQL 82 张图带你飞

    之前两篇文章带你了解了 MySQL 的基础语法和 MySQL 的进阶内容,那么这篇文章我们来了解一下 MySQL 中的高级内容. 其他文章: 本文思维导图如下. 事务控制和锁定语句 我们知道,MyIS ...

  2. mysql function函数_详解MySQL如何按表创建千万级的压测数据

    概述 有时我们要对系统做压测,或者数据库压力测试,这时候需要对某些表插入几百万或者上千万数据,下面介绍下怎么利用MySQL循环和存储过程对特定表的创建千万行数据. 1.准备测试表 CREATE TAB ...

  3. mysql 开发规范_专业级的MySQL开发设计规范及SQL编写规范

    在团队开发过程中为了项目的稳定,代码的高效,管理的便捷制定内部种开发设计规范是必不可少的, 这里分享一份我们定义MySQL开发设计规范包括表设计规范,字段设计规范,SQL编写规范 数据库对象命名规范 ...

  4. mysql 硬负载_为啥单机MySQL又遭遇瓶颈?MySQL主从复制替你解决单机问题

    成长是一棵树,总是在你不知不觉的情况下快乐长大:成长是一株草,总是在你不知不觉的情况下长满大地:成长是一朵花,总是在你不知不觉的情况下开满山头. 这不,随着时间的迁移.项目网站的用户量.数据量持续上升 ...

  5. mysql算法函数_十个实用MySQL函数

    本文首发于个人微信公众号<andyqian>,期待你的关注! 前言 继上一次<十个实用MySQL命令>后,今天奉上十个实用MySQL函数.下面都是一些比较常用且简单的函数,在工 ...

  6. mysql数据库参考_干货:MySQL数据库优化参考

    标签: 本文整理了一些MySQL的通用优化方法,做个简单的总结分享,旨在帮助那些没有专职MySQL DBA的企业做好基本的优化工作,至于具体的SQL优化,大部分通过加适当的索引即可达到效果,更复杂的就 ...

  7. mysql数据库算法_数据库:MySQL索引背后的数据结构及算法原理【转】

    原文:http://blog.codinglabs.org/articles/theory-of-mysql-index.html 摘要 本文以MySQL数据库为研究对象,讨论与数据库索引相关的一些话 ...

  8. mysql 变量 数据类型_浅谈mysql(二)数据类型

    //我...我才是不是傲娇呢 //如有问题还请多多指教.上回我们说到我们如何使用MySQL,关键是要看它的用途.用途衍生语句.之后文章的思路,也是如此,从用途出发,然后再到语句. 那么,我们先问几个问 ...

  9. sphinx mysql存储引擎_基于Sphinx+MySQL的千万级数据全文检索(搜索引擎)架构设计...

    Sphinx,单一索引最大可包含1亿条记录,在1千万条记录情况下的查询速度为0.x秒(毫秒级).Sphinx创建索引的速度为:创建100万条记录的索引只需3-4分钟,创建1000万条记录的索引可以在5 ...

  10. java mysql mac 安装_最新版MySQL在MacOS上的安装与使用!

    在 MacOS 上安装最新版的 MySQL 有三种方法:使用 Docker 安装: 使用 Homebrew 运行 brew install mysql 安装: 使用安装包安装. 我们本文将采用最常规的 ...

最新文章

  1. oracle 的替代变量和
  2. vue中使用baidushare分享到微信无法显示bug解决方案
  3. 基于MATLAB均值漂移图像分割技术
  4. mysql金额数字转成中文_数字转换成汉字金额(转)
  5. ewsa 字典_湖南字典头条胖U
  6. 支付宝报错:missing-signature 未设置签名参数
  7. 什么专业的会学python语言_为什么要学习Python编程语言?哪些人适合学习Python?...
  8. 【Python脚本进阶】2.4、conficker蠕虫(下):暴破口令,远程执行进程
  9. 实验四 使用CANVAS API画图
  10. 【谷歌浏览器】扫码登录不上解决方案
  11. MySQL复制一张表数据到另一张新表
  12. if三种实现方式(if if else if else if else switch case for while)
  13. 历史上的今天:大型计算机先驱和小型机之父诞生;中国雅虎邮箱成历史
  14. 计算机唤醒休眠蓝屏,分享win10睡眠唤醒就蓝屏的解决办法
  15. 网络安全学习小结--kali基本工具、webshell、代码审计
  16. C++核心准则讨论:如果一个类是资源句柄,则它需要一个构造函数,一个析构函数以及复制和/或移动操作
  17. JdbcTemplate报空指针异常 已解决
  18. nginx 地址重写 、反向代理
  19. HTML5+JS游戏开发模块----canvas打字游戏
  20. Signal TapII 软件的使用

热门文章

  1. leetcode 刷题140 141
  2. 全网首个OpenPrompt尝鲜报告:Prompt研究者必备实验利器
  3. AI打AI,人脸对抗攻击公开课第四讲预告:对抗防御介绍
  4. 用开源的人工标注数据来增强RoFormer-Sim
  5. ICCV 2019 | 通过多标签相关性研究提升神经网络视频分类能力
  6. 如何使用计算机中的导出,如何将iPhone手机中的音乐导出至电脑
  7. IDEA主题设置(字体颜色背景)
  8. Spring Boot-@Configuration注解
  9. OpenCV——释放时错误[SourceReaderCB::~SourceReaderCB terminating async callback]解决方案
  10. Little Sub and Apples