序言
在MyBatis中实现组合模式来拼接SQL通常会涉及到使用SqlNode接口和其实现类,以及SqlNode的组合类。下面是一个简单的示例,展示如何使用组合模式来拼接SQL。
定义上下文
/**
* 动态sql上下文
* @author lty
*/
public class DynamicContext {
private Map<String,Object> binding;
private StringJoiner sqlBuilder = new StringJoiner(" ");
public DynamicContext() {
this(new HashMap<>());
}
public DynamicContext(Map<String,Object> binding){
this.binding = binding;
}
/**
* 获取绑定参数
* @return
*/
public Map<String, Object> getBinding() {
return binding;
}
/**
* 追加sql
* @param sql
*/
public void appendSql(String sql){
sqlBuilder.add(sql);
}
/**
* 获取sql
* @return
*/
public String getSql() {
return sqlBuilder.toString().trim();
}
}
定义接口
/**
* SQL节点
* @author lty
*/
public interface SqlNode {
/**
* 解析SQL
* @param context 上下文
*/
void parse(DynamicContext context);
}
普通静态节点
/**
* 普通静态节点
* @author lty
*/
public class StaticTextSqlNode implements SqlNode {
private String text;
public StaticTextSqlNode(String text) {
this.text = text;
}
@Override
public void parse(DynamicContext context) {
context.appendSql(text);
}
}
if节点
/**
* if 标签的实现类
* @author: lty
*/
public class IfSqlNode implements SqlNode {
private String test;
private SqlNode sqlNode;
public IfSqlNode(String test, SqlNode contents) {
this.test = test;
this.sqlNode = contents;
}
@SneakyThrows
@Override
public void parse(DynamicContext context) {
// 获取测试表达式的值
Boolean value = (Boolean) Ognl.getValue(this.test, context.getBinding());
if (value) {
sqlNode.parse(context);
}
}
}
混合节点
/**
* 混合节点
* @author lty
*/
public class MixedSqlNode implements SqlNode {
private List<SqlNode> sqlNodes;
public MixedSqlNode(List<SqlNode> sqlNodes) {
this.sqlNodes = sqlNodes;
}
@Override
public void parse(DynamicContext context) {
for (SqlNode sqlNode : sqlNodes) {
sqlNode.parse(context);
}
}
}
测试
public static void main(String[] args) {
DynamicContext context = new DynamicContext(new HashMap<String, Object>() {
{
put("sex", "1");
}
});
// 使用组合模式组合多个 SqlNode
SqlNode mixedSqlNode = new MixedSqlNode(
Lists.newArrayList(
new StaticTextSqlNode("SELECT * FROM table1"),
new StaticTextSqlNode("where id = 1"),
new IfSqlNode("sex!=1", new StaticTextSqlNode("and sex = '1'"))
)
);
mixedSqlNode.parse(context);
System.out.println("SQL: " + context.getSql());
// SQL: SELECT * FROM table1 where id = 1 and sex = '1'
}
使用组合模式组合多个 SqlNode,根据DynamicContext(动态上下文)去判断条件并根据传入的条件拼接SQL,实现动态SQL组合拼接