如何解析Mybatis xml文件中配置的sql

本文详细介绍了如何使用抽象类实现SQL语句的解析与生成过程,通过文本SQL、条件判断(如if标签)及引用标签(如include)等元素,动态构建最终SQL查询语句,展示了SQL在Mybatis XML配置文件中的应用与解析流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

首先抽象一个SQL语句类:

public abstract class AbstractSQLStatementNode implements ISQLStatement {

	protected List<ISQLStatement> sqlStatements = new ArrayList<>();
	
	@Override
	public void appendSQL(ISQLStatement sql) {
		sqlStatements.add(sql);
	}


	@Override
	public String getSQL(Object object) {
		StringBuilder sb = new StringBuilder();
		for (ISQLStatement stmt : sqlStatements) {
			sb.append(stmt.getSQL(object));
		}
		return sb.toString().trim();
	}

}

然后是文本SQL:

public class PlainSQLNode extends AbstractSQLStatementNode  {

	private final String sql;

	public PlainSQLNode(String sql) {
		this.sql = sql;
	}

	@Override
	public String getSQL(Object object) {
		return sql;
	}

	@Override
	public String toString() {
		return sql;
	}

}


以Mybatis xml中<if test="...">...</if>为例

public class IfSQLNode extends AbstractSQLStatementNode {

	private final String test;
	
	public IfSQLNode(String test) {
		this.test = test;
	}

	public String getTest() {
		return test;
	}

	@Override
	public String getSQL(Object object) {
		try {
			Boolean b = (Boolean) Ognl.getValue(test, object, Boolean.TYPE);
			return b ? super.getSQL(object) : "";
		}
		catch (OgnlException e) {
			 throw new SQLSyntaxException(e);
		}
	}

}

再增加一个Include标签例

public class IncludeSQLNode extends AbstractSQLStatementNode {

	private final TableNode node;
	private final String refid;
	
	public IncludeSQLNode(TableNode node, String refid) {
		this.node = node;
		this.refid = refid;
	}
	
	@Override
	public String getSQL(Object object) {
		SQLNode sqlnode = node.getSQLNode(refid);
		return sqlnode.getSQL(object);
	}

}


其它的xml标签类似,完成最终的sql

调用AbstractSQLStatementNode.getSQL方法,参数为客户端传入参数

XML例子如下:

	<select id="findPage" parameterType="java.util.Map" resultMap="ORG">
 		SELECT * FROM XT_ORG WHERE  BDELETE<>1  <if test="name != null"> AND NAME=#{name}</if> LIMIT #{OFFSET}, #{ROWS}
 	</select>


根据是否传入了name,即可成功执行出最终的sql

 SELECT * FROM XT_ORG WHERE  BDELETE<>1 AND NAME=#{name} LIMIT #{OFFSET}, #{ROWS}

再解析SQL得到,并提出参数

 SELECT * FROM XT_ORG WHERE  BDELETE<>1 AND NAME=? LIMIT ?,?

即可生成最终的PrepareStatement

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值