当前位置:数据库 > > 正文

mybatissql解析(mybatis动态sql实现逻辑代码详解)

时间:2021-10-07 00:14:33类别:数据库

mybatissql解析

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

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 包,如图其是一个抽象类,因此无法被实例化

    mybatissql解析(mybatis动态sql实现逻辑代码详解)

    需要通过 newInstance 来实例化

    mybatissql解析(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 文件解析

    到此这篇关于mybatis动态sql实现逻辑代码详解的文章就介绍到这了,更多相关mybatis动态sql内容请搜索开心学习网以前的文章或继续浏览下面的相关文章希望大家以后多多支持开心学习网!

    标签:
    上一篇下一篇

    猜您喜欢

    热门推荐