mybatis动态sql实现逻辑代码详解

作者:_东极 时间:2024-01-13 05:13:04 

mybatis通过将sql配置xml文件中,通过解析xml动态标签来实现动态sql
如下样例 xml文件


<?xml version = "1.0" ?>
<!DOCTYPE script SYSTEM "script-1.0.dtd">
<script namespace="user">
   <common id="commonOrder">
       order by id desc
   </common>
   <sql id="queryUser">
       select * from user
       <where>
           <if test='id != null '>
               id = #{id}
           </if>
           <if test="names != null and names.size() >0">
               and name in
               <foreach collection="names" item="item" separator="," open="(" close=")">
                   ${item}
               </foreach>
           </if>
       </where>
       <ref id="commonOrder"/>
   </sql>

<sql id="updateUser">
       update user set name = ${name}
       <where>
           <if test='id != null '>
               id = #{id}
           </if>
       </where>
   </sql>

</script>

1.xml文件读取

xml标签编写规则


<!ELEMENT script (#PCDATA | sql | common)*>
<!ATTLIST script
namespace CDATA #REQUIRED
>
<!ELEMENT sql (#PCDATA | trim | where | set | foreach | choose | if | ref)*>
<!ATTLIST sql
id CDATA #REQUIRED
>
<!ELEMENT common (#PCDATA | trim | where | set | foreach | choose | if)*>
<!ATTLIST common
id CDATA #REQUIRED
>
<!ELEMENT ref (#PCDATA)*>
<!ATTLIST ref
id CDATA #REQUIRED
>
<!ELEMENT trim (#PCDATA | trim | where | set | foreach | choose | if)*>
<!ATTLIST trim
prefix CDATA #IMPLIED
prefixOverrides CDATA #IMPLIED
suffix CDATA #IMPLIED
suffixOverrides CDATA #IMPLIED
>
<!ELEMENT where (#PCDATA | trim | where | set | foreach | choose | if | ref)*>
<!ELEMENT set (#PCDATA | trim | where | set | foreach | choose | if)*>

<!ELEMENT foreach (#PCDATA | trim | where | set | foreach | choose | if)*>
<!ATTLIST foreach
collection CDATA #REQUIRED
item CDATA #IMPLIED
index CDATA #IMPLIED
open CDATA #IMPLIED
close CDATA #IMPLIED
separator CDATA #IMPLIED
>

<!ELEMENT choose (when* , otherwise?)>
<!ELEMENT when (#PCDATA | trim | where | set | foreach | choose | if)*>
<!ATTLIST when
test CDATA #REQUIRED
>
<!ELEMENT otherwise (#PCDATA | trim | where | set | foreach | choose | if)*>

<!ELEMENT if (#PCDATA | trim | where | set | foreach | choose | if)*>
<!ATTLIST if
test CDATA #REQUIRED
>

DocumentBuilderFactory 是jdk自带的解析xml文件操作,位于 javax.xml.parsers 包,如图其是一个抽象类,因此无法被实例化

mybatis动态sql实现逻辑代码详解

需要通过 newInstance 来实例化

mybatis动态sql实现逻辑代码详解

实例化对象后的属性 setValidating(true); 即通过xml的 验证规则进行xml格式验证

setNamespaceAware 设置忽略命名空间
对于xml文件的命名空间的定义,详见
https://www.jb51.net/article/219617.htm


private Document buildXml(InputStream scriptFile)
throws ParserConfigurationException, SAXException, IOException {
DocumentBuilderFactory factory = DocumentBuilderFactory
.newInstance();
//默认情况下,解析器不验证文档。将这个参数设置为 true 可打开验证功能。
factory.setValidating(true);
//是否设置命名空间
factory.setNamespaceAware(false);
//确定是否要忽略文件中的注释。其默认值为 false。
factory.setIgnoringComments(true);
//确定是否要忽略元素内容中的空白(类似于浏览器对待 HTML 的方式)。其默认值为 false。
factory.setIgnoringElementContentWhitespace(false);
//定解析器是否要将 CDATA 节点转换为文本,以及是否要和周围的文本节点合并(如果适用的话)。其默认值为 false。
factory.setCoalescing(false);
//确定是否要展开外部实体引用。如果为 true,外部数据将插入文档。其默认值为 true
factory.setExpandEntityReferences(true);

DocumentBuilder builder = factory.newDocumentBuilder();
//设置验证规则文件 dtd文件
builder.setEntityResolver(new EntityResolver() {
@Override
public InputSource resolveEntity(String publicId,
String systemId) throws SAXException, IOException {
return new InputSource(new ClassPathResource("script-1.0.dtd").getInputStream());
}
});
//设置错误解析器
builder.setErrorHandler(new ErrorHandler() {
@Override
public void error(SAXParseException exception)
throws SAXException {
throw exception;
}

@Override
public void fatalError(SAXParseException exception)
throws SAXException {
throw exception;
}

@Override
public void warning(SAXParseException exception)
throws SAXException {
}
});
return builder.parse(scriptFile);
}

2.xml 文件解析

来源:https://blog.csdn.net/wwwzydcom/article/details/119649970

标签:mybatis,动态,sql
0
投稿

猜你喜欢

  • Python产生batch数据的操作

    2022-11-22 16:00:59
  • python网络编程学习笔记(二):socket建立网络客户端

    2023-08-18 13:57:44
  • Python如何基于Tesseract实现识别文字功能

    2022-11-09 11:52:18
  • Oracle 数据库中创建合理的数据库索引

    2024-01-24 12:37:05
  • 华为校园招聘上机笔试题 扑克牌大小(python)

    2021-11-25 23:54:22
  • python登录WeChat 实现自动回复实例详解

    2021-05-25 03:22:22
  • Python实现打砖块小游戏代码实例

    2021-02-27 00:35:38
  • windows环境下tensorflow安装过程详解

    2021-12-10 15:59:34
  • JS 实现计算器详解及实例代码(一)

    2024-04-17 10:08:57
  • 游戏开发进阶Unity网格(Mesh\\动态合批\\骨骼动画\\蒙皮)

    2022-03-18 11:20:26
  • python版本的仿windows计划任务工具

    2021-06-09 03:55:07
  • 详解Python中的Lock和Rlock

    2023-08-11 18:35:20
  • 以数据库字段分组显示数据的sql语句(详细介绍)

    2024-01-29 07:39:49
  • MySQL数据库的触发器和事务

    2024-01-15 21:35:08
  • CSS Frameworks的概念

    2008-01-23 18:41:00
  • python实现外卖信息管理系统

    2021-07-16 07:00:26
  • MySQL的数据库常用命令 超级实用版分享

    2012-01-05 18:58:00
  • 使用Python OpenCV为CNN增加图像样本的实现

    2023-10-13 02:51:31
  • 十分钟教会你用Python处理CSV文件

    2022-02-05 02:24:12
  • react+django清除浏览器缓存的几种方法小结

    2022-10-05 03:07:45
  • asp之家 网络编程 m.aspxhome.com