- 浏览: 68223 次
- 性别:
- 来自: 北京
最新评论
-
u010902814:
好,但是自己还是迷迷糊糊的,需要钻研
Wicket源码初读 -
u010902814:
...
Wicket源码初读 -
huguohuan:
照着做,果然解决问题了,谢谢。
Tomcat服务器中Quartz重复执行两次原因浅析
2016-12-21 更新
已经加入GitHub托管: https://github.com/leitelyaya/mybatis-3 注意3.2.x
另外已修复ForEach污染全局变量的问题
实际使用效果嘛,临时表数据越少越好,如果不少,请放弃此优化
特感谢这篇博文讲解参数使用:http://blog.csdn.net/isea533/article/details/44002219
------------------------------------------------------------------------------------------------------------------------------------------
应用系统在设计多功能过滤时往往想到使用多表联结查询,如过滤字段增多,数据所关联的表增大时,数据量大,导致查询时间过长,本着exists优化多表的原则,为Mybatis提供一个方便的编码方式。
E.g. 订单查询列表页,不输入条件时查询所有,输入订单类条件时过滤订单,输入订单收货人、发票、商品信息时,过滤相关的订单
原始SQL:
用MyBatis则是:
理想模式下使用exists代替联结优化:
MyBatis下写得就繁琐了:
当查询条件多的时候,exists外层if的查询就难写了,无奈没有现成检测子查询下所有的if语句的结果返回是不符合的情况
理想处理如下:
自定义一个节点,判断上述情况
第一步,更新DTD,使得配置文件验证通过
第二步,配置新解析器,解析自定义节点
新的DTD,在项目资源目录下增加
org.apache.ibatis.builder.xml.mybatis-3-mapper.dtd
注意,项目资源获取优先级大于MyBatis包中的DTD,故而设定为同一个路径,同一个名字,会自动载入改好的文件
更改默认mapper语言解析器:
创建解析器:
org.apache.ibatis.scripting.ExtendingXMLLanguageDriver
org.apache.ibatis.scripting.xmltags.ExtendingXMLScriptBuilder
添加match_any的标签解析器:
org.apache.ibatis.scripting.xmltags.MatchAnySqlNode
~_~ 简单粗暴搞定..
已经加入GitHub托管: https://github.com/leitelyaya/mybatis-3 注意3.2.x
另外已修复ForEach污染全局变量的问题
实际使用效果嘛,临时表数据越少越好,如果不少,请放弃此优化
特感谢这篇博文讲解参数使用:http://blog.csdn.net/isea533/article/details/44002219
------------------------------------------------------------------------------------------------------------------------------------------
应用系统在设计多功能过滤时往往想到使用多表联结查询,如过滤字段增多,数据所关联的表增大时,数据量大,导致查询时间过长,本着exists优化多表的原则,为Mybatis提供一个方便的编码方式。
E.g. 订单查询列表页,不输入条件时查询所有,输入订单类条件时过滤订单,输入订单收货人、发票、商品信息时,过滤相关的订单
原始SQL:
select * from order left join receiver using (xx) left join invoice using (xx) left join goods using (xx) where order...= xx and receiver... = xx and invoice... = xx and goods... = xx
用MyBatis则是:
select * from order left join receiver using (xx) left join invoice using (xx) left join goods using (xx) ... <where> <if test="order..."> and order...= #{order.xx} </if> <if test="receiver..." and receiver...= #{receiver.xx} </if> <if test="invoice..." and invoice...= #{invoice.xx} </if> <if test="goods..." and goods...= #{goods.xx} </if> </where>
理想模式下使用exists代替联结优化:
select * from order where order...= xx and exists ( select 1 from receiver where order.xx=receiver.xx and receiver... = xx ) and exists ( select 1 from invoice where order.xx=invoice.xx and invoice... = xx ) and exists ( select 1 from goods where order.xx=goods.xx and goods... = xx )
MyBatis下写得就繁琐了:
select * from order <where> <if test="order..."> order...= xx </if> <if test="receiver.a!=null && receiver.b!=null && receiver.c!=null ..."> and exists ( select 1 from receiver where order.xx=receiver.xx <if test="receiver.a!=null"> and receiver.a = #{receiver.a} </if> <if test="receiver.b!=null"> and receiver.b = #{receiver.b} </if> <if test="receiver.c!=null"> and receiver.c = #{receiver.c} </if> ) ... </where>
当查询条件多的时候,exists外层if的查询就难写了,无奈没有现成检测子查询下所有的if语句的结果返回是不符合的情况
理想处理如下:
select * from order <where> <if test="order..."> order...= xx </if> <match_any> and exists ( select 1 from receiver where order.xx=receiver.xx <if test="receiver..."> and receiver... = xx </if> <if test="receiver..."> and receiver... = xx </if> <if test="receiver..."> and receiver... = xx </if> ) </match_any> ... </where>
自定义一个节点,判断上述情况
第一步,更新DTD,使得配置文件验证通过
第二步,配置新解析器,解析自定义节点
新的DTD,在项目资源目录下增加
org.apache.ibatis.builder.xml.mybatis-3-mapper.dtd
注意,项目资源获取优先级大于MyBatis包中的DTD,故而设定为同一个路径,同一个名字,会自动载入改好的文件
<?xml version="1.0" encoding="UTF-8" ?> <!-- Copyright 2009-2016 the original author or authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --> <!ELEMENT mapper (cache-ref | cache | resultMap* | parameterMap* | sql* | insert* | update* | delete* | select* )+> <!ATTLIST mapper namespace CDATA #IMPLIED > <!ELEMENT cache-ref EMPTY> <!ATTLIST cache-ref namespace CDATA #REQUIRED > <!ELEMENT cache (property*)> <!ATTLIST cache type CDATA #IMPLIED eviction CDATA #IMPLIED flushInterval CDATA #IMPLIED size CDATA #IMPLIED readOnly CDATA #IMPLIED blocking CDATA #IMPLIED > <!ELEMENT parameterMap (parameter+)?> <!ATTLIST parameterMap id CDATA #REQUIRED type CDATA #REQUIRED > <!ELEMENT parameter EMPTY> <!ATTLIST parameter property CDATA #REQUIRED javaType CDATA #IMPLIED jdbcType CDATA #IMPLIED mode (IN | OUT | INOUT) #IMPLIED resultMap CDATA #IMPLIED scale CDATA #IMPLIED typeHandler CDATA #IMPLIED > <!ELEMENT resultMap (constructor?,id*,result*,association*,collection*, discriminator?)> <!ATTLIST resultMap id CDATA #REQUIRED type CDATA #REQUIRED extends CDATA #IMPLIED autoMapping (true|false) #IMPLIED > <!ELEMENT constructor (idArg*,arg*)> <!ELEMENT id EMPTY> <!ATTLIST id property CDATA #IMPLIED javaType CDATA #IMPLIED column CDATA #IMPLIED jdbcType CDATA #IMPLIED typeHandler CDATA #IMPLIED > <!ELEMENT result EMPTY> <!ATTLIST result property CDATA #IMPLIED javaType CDATA #IMPLIED column CDATA #IMPLIED jdbcType CDATA #IMPLIED typeHandler CDATA #IMPLIED > <!ELEMENT idArg EMPTY> <!ATTLIST idArg javaType CDATA #IMPLIED column CDATA #IMPLIED jdbcType CDATA #IMPLIED typeHandler CDATA #IMPLIED select CDATA #IMPLIED resultMap CDATA #IMPLIED > <!ELEMENT arg EMPTY> <!ATTLIST arg javaType CDATA #IMPLIED column CDATA #IMPLIED jdbcType CDATA #IMPLIED typeHandler CDATA #IMPLIED select CDATA #IMPLIED resultMap CDATA #IMPLIED > <!ELEMENT collection (constructor?,id*,result*,association*,collection*, discriminator?)> <!ATTLIST collection property CDATA #REQUIRED column CDATA #IMPLIED javaType CDATA #IMPLIED ofType CDATA #IMPLIED jdbcType CDATA #IMPLIED select CDATA #IMPLIED resultMap CDATA #IMPLIED typeHandler CDATA #IMPLIED notNullColumn CDATA #IMPLIED columnPrefix CDATA #IMPLIED resultSet CDATA #IMPLIED foreignColumn CDATA #IMPLIED autoMapping (true|false) #IMPLIED fetchType (lazy|eager) #IMPLIED > <!ELEMENT association (constructor?,id*,result*,association*,collection*, discriminator?)> <!ATTLIST association property CDATA #REQUIRED column CDATA #IMPLIED javaType CDATA #IMPLIED jdbcType CDATA #IMPLIED select CDATA #IMPLIED resultMap CDATA #IMPLIED typeHandler CDATA #IMPLIED notNullColumn CDATA #IMPLIED columnPrefix CDATA #IMPLIED resultSet CDATA #IMPLIED foreignColumn CDATA #IMPLIED autoMapping (true|false) #IMPLIED fetchType (lazy|eager) #IMPLIED > <!ELEMENT discriminator (case+)> <!ATTLIST discriminator column CDATA #IMPLIED javaType CDATA #REQUIRED jdbcType CDATA #IMPLIED typeHandler CDATA #IMPLIED > <!ELEMENT case (constructor?,id*,result*,association*,collection*, discriminator?)> <!ATTLIST case value CDATA #REQUIRED resultMap CDATA #IMPLIED resultType CDATA #IMPLIED > <!ELEMENT property EMPTY> <!ATTLIST property name CDATA #REQUIRED value CDATA #REQUIRED > <!ELEMENT typeAlias EMPTY> <!ATTLIST typeAlias alias CDATA #REQUIRED type CDATA #REQUIRED > <!ELEMENT select (#PCDATA | include | trim | where | set | foreach | choose | if | bind | match_any)*> <!ATTLIST select id CDATA #REQUIRED parameterMap CDATA #IMPLIED parameterType CDATA #IMPLIED resultMap CDATA #IMPLIED resultType CDATA #IMPLIED resultSetType (FORWARD_ONLY | SCROLL_INSENSITIVE | SCROLL_SENSITIVE) #IMPLIED statementType (STATEMENT|PREPARED|CALLABLE) #IMPLIED fetchSize CDATA #IMPLIED timeout CDATA #IMPLIED flushCache (true|false) #IMPLIED useCache (true|false) #IMPLIED databaseId CDATA #IMPLIED lang CDATA #IMPLIED resultOrdered (true|false) #IMPLIED resultSets CDATA #IMPLIED > <!ELEMENT insert (#PCDATA | selectKey | include | trim | where | set | foreach | choose | if | bind | match_any)*> <!ATTLIST insert id CDATA #REQUIRED parameterMap CDATA #IMPLIED parameterType CDATA #IMPLIED timeout CDATA #IMPLIED flushCache (true|false) #IMPLIED statementType (STATEMENT|PREPARED|CALLABLE) #IMPLIED keyProperty CDATA #IMPLIED useGeneratedKeys (true|false) #IMPLIED keyColumn CDATA #IMPLIED databaseId CDATA #IMPLIED lang CDATA #IMPLIED > <!ELEMENT selectKey (#PCDATA | include | trim | where | set | foreach | choose | if | bind | match_any)*> <!ATTLIST selectKey resultType CDATA #IMPLIED statementType (STATEMENT|PREPARED|CALLABLE) #IMPLIED keyProperty CDATA #IMPLIED keyColumn CDATA #IMPLIED order (BEFORE|AFTER) #IMPLIED databaseId CDATA #IMPLIED > <!ELEMENT update (#PCDATA | selectKey | include | trim | where | set | foreach | choose | if | bind | match_any)*> <!ATTLIST update id CDATA #REQUIRED parameterMap CDATA #IMPLIED parameterType CDATA #IMPLIED timeout CDATA #IMPLIED flushCache (true|false) #IMPLIED statementType (STATEMENT|PREPARED|CALLABLE) #IMPLIED keyProperty CDATA #IMPLIED useGeneratedKeys (true|false) #IMPLIED keyColumn CDATA #IMPLIED databaseId CDATA #IMPLIED lang CDATA #IMPLIED > <!ELEMENT delete (#PCDATA | include | trim | where | set | foreach | choose | if | bind | match_any)*> <!ATTLIST delete id CDATA #REQUIRED parameterMap CDATA #IMPLIED parameterType CDATA #IMPLIED timeout CDATA #IMPLIED flushCache (true|false) #IMPLIED statementType (STATEMENT|PREPARED|CALLABLE) #IMPLIED databaseId CDATA #IMPLIED lang CDATA #IMPLIED > <!-- Dynamic --> <!ELEMENT include (property+)?> <!ATTLIST include refid CDATA #REQUIRED > <!ELEMENT bind EMPTY> <!ATTLIST bind name CDATA #REQUIRED value CDATA #REQUIRED > <!ELEMENT sql (#PCDATA | include | trim | where | set | foreach | choose | if | bind | match_any)*> <!ATTLIST sql id CDATA #REQUIRED lang CDATA #IMPLIED databaseId CDATA #IMPLIED > <!ELEMENT trim (#PCDATA | include | trim | where | set | foreach | choose | if | bind | match_any)*> <!ATTLIST trim prefix CDATA #IMPLIED prefixOverrides CDATA #IMPLIED suffix CDATA #IMPLIED suffixOverrides CDATA #IMPLIED > <!ELEMENT where (#PCDATA | include | trim | where | set | foreach | choose | if | bind | match_any)*> <!ELEMENT set (#PCDATA | include | trim | where | set | foreach | choose | if | bind | match_any)*> <!ELEMENT foreach (#PCDATA | include | trim | where | set | foreach | choose | if | bind | match_any)*> <!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 | include | trim | where | set | foreach | choose | if | bind | match_any)*> <!ATTLIST when test CDATA #REQUIRED > <!ELEMENT otherwise (#PCDATA | include | trim | where | set | foreach | choose | if | bind | match_any)*> <!ELEMENT if (#PCDATA | include | trim | where | set | foreach | choose | if | bind | match_any)*> <!ATTLIST if test CDATA #REQUIRED > <!ELEMENT match_any (#PCDATA | include | trim | where | set | foreach | choose | if | bind)*>
更改默认mapper语言解析器:
<settings> ... <setting name="defaultScriptingLanguage" value="extending"/> </settings> <typeAliases> <typeAlias type="org.apache.ibatis.scripting.ExtendingXMLLanguageDriver" alias="extending"/> </typeAliases>
创建解析器:
org.apache.ibatis.scripting.ExtendingXMLLanguageDriver
public class ExtendingXMLLanguageDriver extends XMLLanguageDriver implements LanguageDriver { @Override public SqlSource createSqlSource(Configuration configuration, XNode script, Class<?> parameterType) { return new ExtendingXMLScriptBuilder(configuration, script, parameterType).parseScriptNode(); } }
org.apache.ibatis.scripting.xmltags.ExtendingXMLScriptBuilder
public class ExtendingXMLScriptBuilder extends BaseBuilder { private XNode context; private boolean isDynamic; private Class<?> parameterType; public ExtendingXMLScriptBuilder(Configuration configuration, XNode context) { this(configuration, context, null); } public ExtendingXMLScriptBuilder(Configuration configuration, XNode context, Class<?> parameterType) { super(configuration); this.context = context; this.parameterType = parameterType; } public SqlSource parseScriptNode() { List<SqlNode> contents = parseDynamicTags(context); MixedSqlNode rootSqlNode = new MixedSqlNode(contents); SqlSource sqlSource = null; if (isDynamic) { sqlSource = new DynamicSqlSource(configuration, rootSqlNode); } else { sqlSource = new RawSqlSource(configuration, rootSqlNode, parameterType); } return sqlSource; } private List<SqlNode> parseDynamicTags(XNode node) { List<SqlNode> contents = new ArrayList<SqlNode>(); NodeList children = node.getNode().getChildNodes(); for (int i = 0; i < children.getLength(); i++) { XNode child = node.newXNode(children.item(i)); if (child.getNode().getNodeType() == Node.CDATA_SECTION_NODE || child.getNode().getNodeType() == Node.TEXT_NODE) { String data = child.getStringBody(""); TextSqlNode textSqlNode = new TextSqlNode(data); if (textSqlNode.isDynamic()) { contents.add(textSqlNode); isDynamic = true; } else { contents.add(new StaticTextSqlNode(data)); } } else if (child.getNode().getNodeType() == Node.ELEMENT_NODE) { // issue #628 String nodeName = child.getNode().getNodeName(); NodeHandler handler = nodeHandlers.get(nodeName); if (handler == null) { throw new BuilderException("Unknown element <" + nodeName + "> in SQL statement."); } handler.handleNode(child, contents); isDynamic = true; } } return contents; } private Map<String, NodeHandler> nodeHandlers = new HashMap<String, NodeHandler>() { private static final long serialVersionUID = 7123056019193266281L; { put("trim", new TrimHandler()); put("where", new WhereHandler()); put("set", new SetHandler()); put("foreach", new ForEachHandler()); put("if", new IfHandler()); put("choose", new ChooseHandler()); put("when", new IfHandler()); put("otherwise", new OtherwiseHandler()); put("bind", new BindHandler()); put("match_any", new MatchAnyHandler()); } }; private interface NodeHandler { void handleNode(XNode nodeToHandle, List<SqlNode> targetContents); } private class BindHandler implements NodeHandler { public void handleNode(XNode nodeToHandle, List<SqlNode> targetContents) { final String name = nodeToHandle.getStringAttribute("name"); final String expression = nodeToHandle.getStringAttribute("value"); final VarDeclSqlNode node = new VarDeclSqlNode(name, expression); targetContents.add(node); } } private class TrimHandler implements NodeHandler { public void handleNode(XNode nodeToHandle, List<SqlNode> targetContents) { List<SqlNode> contents = parseDynamicTags(nodeToHandle); MixedSqlNode mixedSqlNode = new MixedSqlNode(contents); String prefix = nodeToHandle.getStringAttribute("prefix"); String prefixOverrides = nodeToHandle.getStringAttribute("prefixOverrides"); String suffix = nodeToHandle.getStringAttribute("suffix"); String suffixOverrides = nodeToHandle.getStringAttribute("suffixOverrides"); TrimSqlNode trim = new TrimSqlNode(configuration, mixedSqlNode, prefix, prefixOverrides, suffix, suffixOverrides); targetContents.add(trim); } } private class WhereHandler implements NodeHandler { public void handleNode(XNode nodeToHandle, List<SqlNode> targetContents) { List<SqlNode> contents = parseDynamicTags(nodeToHandle); MixedSqlNode mixedSqlNode = new MixedSqlNode(contents); WhereSqlNode where = new WhereSqlNode(configuration, mixedSqlNode); targetContents.add(where); } } private class SetHandler implements NodeHandler { public void handleNode(XNode nodeToHandle, List<SqlNode> targetContents) { List<SqlNode> contents = parseDynamicTags(nodeToHandle); MixedSqlNode mixedSqlNode = new MixedSqlNode(contents); SetSqlNode set = new SetSqlNode(configuration, mixedSqlNode); targetContents.add(set); } } private class ForEachHandler implements NodeHandler { public void handleNode(XNode nodeToHandle, List<SqlNode> targetContents) { List<SqlNode> contents = parseDynamicTags(nodeToHandle); MixedSqlNode mixedSqlNode = new MixedSqlNode(contents); String collection = nodeToHandle.getStringAttribute("collection"); String item = nodeToHandle.getStringAttribute("item"); String index = nodeToHandle.getStringAttribute("index"); String open = nodeToHandle.getStringAttribute("open"); String close = nodeToHandle.getStringAttribute("close"); String separator = nodeToHandle.getStringAttribute("separator"); ForEachSqlNode forEachSqlNode = new ForEachSqlNode(configuration, mixedSqlNode, collection, index, item, open, close, separator); targetContents.add(forEachSqlNode); } } private class IfHandler implements NodeHandler { public void handleNode(XNode nodeToHandle, List<SqlNode> targetContents) { List<SqlNode> contents = parseDynamicTags(nodeToHandle); MixedSqlNode mixedSqlNode = new MixedSqlNode(contents); String test = nodeToHandle.getStringAttribute("test"); IfSqlNode ifSqlNode = new IfSqlNode(mixedSqlNode, test); targetContents.add(ifSqlNode); } } private class MatchAnyHandler implements NodeHandler { public void handleNode(XNode nodeToHandle, List<SqlNode> targetContents) { List<SqlNode> contents = parseDynamicTags(nodeToHandle); List<SqlNode> dynamicContents = new ArrayList<>(); for (SqlNode node : contents) { if (node instanceof IfSqlNode || node instanceof ChooseSqlNode || node instanceof ForEachHandler) { dynamicContents.add(node); } } MixedSqlNode mixedSqlNode = new MixedSqlNode(contents); MixedSqlNode dynamicSqlNode = new MixedSqlNode(dynamicContents); MatchAnySqlNode matchAnySqlNode = new MatchAnySqlNode(configuration, mixedSqlNode, dynamicSqlNode); targetContents.add(matchAnySqlNode); } } private class OtherwiseHandler implements NodeHandler { public void handleNode(XNode nodeToHandle, List<SqlNode> targetContents) { List<SqlNode> contents = parseDynamicTags(nodeToHandle); MixedSqlNode mixedSqlNode = new MixedSqlNode(contents); targetContents.add(mixedSqlNode); } } private class ChooseHandler implements NodeHandler { public void handleNode(XNode nodeToHandle, List<SqlNode> targetContents) { List<SqlNode> whenSqlNodes = new ArrayList<SqlNode>(); List<SqlNode> otherwiseSqlNodes = new ArrayList<SqlNode>(); handleWhenOtherwiseNodes(nodeToHandle, whenSqlNodes, otherwiseSqlNodes); SqlNode defaultSqlNode = getDefaultSqlNode(otherwiseSqlNodes); ChooseSqlNode chooseSqlNode = new ChooseSqlNode(whenSqlNodes, defaultSqlNode); targetContents.add(chooseSqlNode); } private void handleWhenOtherwiseNodes(XNode chooseSqlNode, List<SqlNode> ifSqlNodes, List<SqlNode> defaultSqlNodes) { List<XNode> children = chooseSqlNode.getChildren(); for (XNode child : children) { String nodeName = child.getNode().getNodeName(); NodeHandler handler = nodeHandlers.get(nodeName); if (handler instanceof IfHandler) { handler.handleNode(child, ifSqlNodes); } else if (handler instanceof OtherwiseHandler) { handler.handleNode(child, defaultSqlNodes); } } } private SqlNode getDefaultSqlNode(List<SqlNode> defaultSqlNodes) { SqlNode defaultSqlNode = null; if (defaultSqlNodes.size() == 1) { defaultSqlNode = defaultSqlNodes.get(0); } else if (defaultSqlNodes.size() > 1) { throw new BuilderException("Too many default (otherwise) elements in choose statement."); } return defaultSqlNode; } } }
添加match_any的标签解析器:
org.apache.ibatis.scripting.xmltags.MatchAnySqlNode
public class MatchAnySqlNode implements SqlNode { private final Configuration configuration; private final SqlNode dynamicContents; private SqlNode contents; public MatchAnySqlNode(Configuration configuration, SqlNode contents, SqlNode dynamicContents) { this.contents = contents; this.dynamicContents = dynamicContents; this.configuration = configuration; } public boolean apply(DynamicContext context) { DynamicContext oldContext = context; context = new FilterContext(oldContext); dynamicContents.apply(context); String sqlS = context.getSql(); context = new FilterContext(oldContext); contents.apply(context); String sqlN = context.getSql(); context = oldContext; if (sqlS.trim().length() > 0) { context.appendSql(sqlN); return true; } return true; } private class FilterContext extends DynamicContext { private DynamicContext delegate; StringBuffer buffer; public FilterContext(DynamicContext delegate) { super(configuration, null); buffer = new StringBuffer(); this.delegate = delegate; } @Override public Map<String, Object> getBindings() { return delegate.getBindings(); } @Override public void bind(String name, Object value) { delegate.bind(name, value); } @Override public void appendSql(String sql) { buffer.append(sql); } @Override public String getSql() { return buffer.toString(); } } }
~_~ 简单粗暴搞定..
发表评论
-
应用多数据源支持读写分离
2016-11-17 16:52 548经过测试,MySQL的ReplicationConnecti ... -
实施MySQL ReplicationDriver支持读写分离
2016-11-03 19:46 4565MySQL 提供支持读写分离的驱动类: com.mysq ... -
Hibernate Example 学习
2012-06-15 10:35 3993excludeNone是去除所有的过滤。 /** ... -
服务器操作手册
2011-01-28 12:38 0服务器操作手册 一、后台服务器 1. 网卡配置:# ifc ... -
Tomcat服务器中Quartz重复执行两次原因浅析
2010-12-28 17:35 10613且不论很是热火的解决方案, 就表面感觉而言, 一个程序会执行两 ... -
Hibernate简单关系下的组合查询方案 基于QBE
2010-12-23 18:24 0由于工作异动,融入了新的团队,架构师对框架的选型是基于原有的系 ... -
Wicket源码初读
2010-10-26 14:01 1802项目需要用到Wicket,对于我来说,这可真是个新兴事物。市面 ...
相关推荐
Mybatis框架(子查询)
mybatis一对多的查询方法详解! mybatis一对多的查询方法详解! mybatis一对多的查询方法详解! mybatis一对多的查询方法详解!
通过mybatis的拦截器,实现为所有sql(或指定sql) 统一添加查询条件,譬如通过线程变量传递某参数(日期),来实现对指定参数的数据筛选,而不需要在每个查询前,手动将该条件注入到查询中。因该资料网络较少,故特此...
mybatis批量添加数据的方法1
mybatis中文离线文档
实现Mybatis框架中一对多关联映射的查询操作。 User用户表 - Order_form订单表属于 1-N 的关系。 一个用户对象包含一批订单信息
实现Mybatis框架中一对一关联映射的查询操作。 User用户表 - User_Card身份证表属于 1-1 的关系
Mybatis多参数查询与列表查询不同方式实现,效果看博文 http://blog.csdn.net/evankaka/article/details/45671473
主要介绍了Mybatis基于注解实现多表查询功能,非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下
mybatis之多对多
就是代码而已《哈哈哈》
MyBatis高级映射(一对多查询)
针对父子级数据目录查询, 以前都是逐级的去根据父级id查询子集目录, 查出后最后再在代码中拼成树形结构, 相当复杂,我们可以利用 mybatis 提供的 collection 标签自动组织树形结构
关于springboot 和mybatis使用添加mybatis依赖 首先是springboot项目,依赖mybatis 。环境不多说,主要看配置。
mybatis添加ehcache缓存支持,基于maven项目管理
mybatis分页插件支持查询~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
主要给大家介绍了关于mybatis拦截器实现通用权限字段添加的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用mybatis具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
mybatis_3.5.9官方中文文档pdf
mybatis中,sqlserver分页
MyBatis3官方中文文档高清 MyBatis3官方中文文档高清 MyBatis3官方中文文档高清 MyBatis3官方中文文档高清