-
java 动态 sql_java实现动态sql解析
2021-02-27 10:44:16System.out.println("取得的sql="+sql); } public String buildSql(String xml, Map hm) throws JDOMException, IOException { SAXBuilder jdomBuilder = new SAXBuilder(); Document jdomDocument = jdomBuilder....package test;
import org.apache.ibatis.scripting.xmltags.ExpressionEvaluator;
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.JDOMException;
import org.jdom2.input.SAXBuilder;
import java.io.IOException;
import java.io.StringReader;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
/**
* Created by Chentq on 2017/8/25.
*/
public class TestOgnl {
private static ExpressionEvaluator evaluator = new ExpressionEvaluator();
public static void main(String[] args) throws JDOMException, IOException {
Map hm = new HashMap<>();
// hm.put("name","aaaa");
hm.put("gb", "gebian");
hm.put("sfz", "sfz");
hm.put("sex", 1);
hm.put("birth", 2);
String xml = "" +
" " +
" " +
" select a, b, c" +
" from ac01_1" +
" where aac002 = #{sfz}" +
" " +
" and aac003 = #{name}" +
" " +
" " +
" " +
" " +
" " +
" " +
" select a, b, c" +
" from ac01_2" +
" where aac001 = #{gb}" +
" and aac003 = #{name}" +
" " +
" and aac004 = #{sex}" +
" " +
" " +
" " +
" " +
" " +
" select a, b, c" +
" from ac01_3" +
" where aac001 = #{gb}" +
" " +
" and aac004 = #{sex}" +
" " +
" " +
" " +
" " +
"";
TestOgnl to = new TestOgnl();
String sql = to.buildSql(xml, hm);
System.out.println("----- done. --------");
System.out.println("取得的sql="+sql);
}
public String buildSql(String xml, Map hm) throws JDOMException, IOException {
SAXBuilder jdomBuilder = new SAXBuilder();
Document jdomDocument = jdomBuilder.build(new StringReader(xml));
System.out.println(jdomDocument.getRootElement().getName());
if(!"sql".equals(jdomDocument.getRootElement().getName())){
System.out.println("非法的xml");
return null;
}
String sql;
Element select = jdomDocument.getRootElement();
sql = analyseEl(select.getChildren(), hm);
if(null != sql && !"".equals(sql)){
return sql;
}
return null;
}
private String analyseEl(List els, Map hm) {
Element el = null;
Element el2 = null;
for (Iterator iter = els.iterator(); iter.hasNext();){
el = iter.next();
if("if".equals(el.getName())){
String test = el.getAttributeValue("test");
System.out.println("test="+test);
if(!evaluator.evaluateBoolean(test, hm)){
continue;
}
String sql;
sql = analyseEl(el.getChildren(), hm);
if(null != sql && !"".equals(sql)){
return sql;
}
}else if("select".equals(el.getName())){
List list = el.getChildren();
for (Iterator iter2 = list.iterator(); iter2.hasNext();){
el2 = iter2.next();
if("if".equals(el2.getName())){
System.out.println("test="+el2.getAttributeValue("test"));
if(!evaluator.evaluateBoolean(el2.getAttributeValue("test"), hm)){
el.removeContent(el.indexOf(el2));
}
}
}
System.out.println(el.getValue());
return el.getValue();
}else{
System.out.println("无有效配置.");
}
}
return null;
}
}
-
实现Ibatis的动态解析SQL功能
2013-05-10 15:12:34曾几何时,一直想实现Ibatis的动态解析SQL功能,前些日子写了一个,基本实现( [color=red]暂不支持嵌套标签[/color]): [code="java"] import java.io.File; import java.util.HashMap; import java....曾几何时,一直想实现Ibatis的动态解析SQL功能,前些日子写了一个,基本实现(
[color=red]暂不支持嵌套标签[/color]):
import java.io.File;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
/**
*
* @description SQL动态解析
* @author 杨惠
* @version 1.0
* @date 2013-5-10
*/
public class SqlParse {
private static Logger logger = Logger.getLogger(SqlParse.class);
private String encoding = "UTF-8";
private SAXReader saxReader = null;
private Document document = null;
// XML文件全路径
private String filePath = "D:\\sql.xml";
public SqlParse() {
Init();
}
public SqlParse(String filePath) {
this.filePath = filePath;
Init();
}
/**
* 初始化
*/
private void Init() {
File file = new File(filePath);
if (file.exists() && file.isFile()) {
try {
saxReader = new SAXReader();
document = saxReader.read(file);
} catch (Exception e) {
logger.error(e);
document = null;
} finally {
saxReader = null;
file = null;
}
} else {
logger.error("指定文件不存在;");
}
}
/**
* 根据传入参数Map,动态替换SQL标签,解析成最终执行的SQL语句
*
* @param selectID
* select元素的ID
* @param mapPara
* SQL参数
* @return
* @throws Exception
*/
@SuppressWarnings("unchecked")
public final Map<String, String> parseSql(String strID,
Map<String, String> mapPara) throws Exception {
// 1.根据sqlID获得SQL语句元素
Element elementParent = (Element) document
.selectSingleNode("//select[@id='" + strID + "'] ");
if (elementParent == null) {
logger.info("文件名:" + filePath + ";信息:无id="
+ strID + "的元素。");
return null;
}
if (mapPara == null) {
mapPara = new HashMap<String, String>();
}
// 2.解析每一个子元素标签,例如isNotEmpty,isEqual等
List<Element> listElements = elementParent.elements();
if (listElements != null && (!listElements.isEmpty())) {
for (Element element : listElements) {
parseElement(element, mapPara);
}
}
// 3.解析SQL,用Map值替换SQL标签
String strSQL = elementParent.getStringValue();
Set<String> setKey = mapPara.keySet();
String strProperty = null;
for (Iterator<String> iterator = setKey.iterator(); iterator.hasNext();) {
strProperty = (String) iterator.next();
strSQL = strSQL.replaceAll("#" + strProperty + "#",
mapPara.get(strProperty));
strProperty = null;
}
Map<String, String> mapSQL = new HashMap<String, String>();
mapSQL.put("sqlText", strSQL.replaceAll("\\s{2,}", " "));
List<Attribute> listAttribute = elementParent.attributes();
for (Attribute attribute : listAttribute) {
mapSQL.put(attribute.getName(), attribute.getText());
}
// 4.释放变量
strID = null;
mapPara = null;
elementParent = null;
listElements = null;
setKey = null;
strSQL = null;
return mapSQL;
}
/**
* 解析每一个标签元素
*
* @param element
* 标签元素
* @param mapPara
* SQL参数
* @throws Exception
*/
private final void parseElement(Element element, Map<String, String> mapPara)
throws Exception {
// 获得节点名称、属性,属性值
String strElementName = element.getName();
String strProperty = element.attributeValue("property").trim();
String strPropertyValue = mapPara.get(strProperty);
// 是否删除该节点
boolean booDelete = false;
// 标签处理
if (StringUtils.equals(strElementName, "isNotEmpty")) {
// 是否非空
if (StringUtils.isBlank(strPropertyValue)) {
booDelete = true;
}
} else if (StringUtils.equals(strElementName, "isEmpty")) {
// 是否为空
if (StringUtils.isNotBlank(strPropertyValue)) {
booDelete = true;
}
} else {
// 比较值
if (StringUtils.isBlank(strPropertyValue)) {
booDelete = true;
} else {
double douPropertyValue = Double.parseDouble(strPropertyValue);
double douCompareValue = Double.parseDouble(element
.attributeValue("compareValue").trim());
if (StringUtils.equals(strElementName, "isGreaterThan")) {
// 是否大于
if (douPropertyValue <= douCompareValue) {
booDelete = true;
}
} else if (StringUtils.equals(strElementName, "isGreaterEqual")) {
// 是否大于等于
if (douPropertyValue < douCompareValue) {
booDelete = true;
}
} else if (StringUtils.equals(strElementName, "isLessThan")) {
// 是否小于
if (douPropertyValue >= douCompareValue) {
booDelete = true;
}
} else if (StringUtils.equals(strElementName, "isEqual")) {
// 是否等于
if (douPropertyValue != douCompareValue) {
booDelete = true;
}
} else if (StringUtils.equals(strElementName, "isNotEqual")) {
// 是否不等于
if (douPropertyValue == douCompareValue) {
booDelete = true;
}
} else if (StringUtils.equals(strElementName, "isLessEqual")) {
// 是否小于等于
if (douPropertyValue > douCompareValue) {
booDelete = true;
}
}
}
}
if (booDelete == true) {
element.getParent().remove(element);
}
// 释放变量
element = null;
mapPara = null;
strElementName = null;
strProperty = null;
strPropertyValue = null;
}
/**
* 获得:XML文件编码
*
* @return the encoding
*/
public final String getEncoding() {
return encoding;
}
/**
* 设置:XML文件编码
*
* @param encoding
* the encoding to set
*/
public final void setEncoding(String encoding) {
if (encoding != null) {
this.encoding = encoding;
}
}
/**
* 获得:Document
*
* @return the document
*/
public final Document getDocument() {
return document;
}
/**
* 设置:Document
*
* @param document
* the document to set
*/
public final void setDocument(Document document) {
if (document != null) {
this.document = document;
}
}
/**
* 获得:XMl文件全路径(含文件名)
*
* @return the filePath
*/
public final String getFilePath() {
return filePath;
}
/**
* 设置:XMl文件全路径(含文件名)
*
* @param filePath
* the filePath to set
*/
public final void setFilePath(String filePath) {
if (filePath != null) {
this.filePath = filePath;
}
}
public static void main(String[] args) {
try {
Map<String, String> mapPara = new HashMap<String, String>();
mapPara.put("menucode", "sysAdmin");
SqlParse sqlParse = new SqlParse("d:/sql.xml");
System.out.println(sqlParse.parseSql(
"queryMenuAsList", mapPara));
} catch (Exception e) {
e.printStackTrace();
}
}
}
上面main方法打印结果:{id=queryMenuAsList, name=菜单表, sqlText= select menucode as 菜单编码,menuname as 菜单名称 from tb_upc_menu where 1=1 and menucode='myWork' }
Sql.xml:<?xml version="1.0" encoding="UTF-8"?>
<root>
<select id="queryMenuAsList" name="菜单表">
select menucode as 菜单编码,menuname as 菜单名称 from tb_upc_menu
where 1=1
<isNotEmpty property="menucode">
and menucode='myWork'
</isNotEmpty>
</select>
<select id="queryUserAsList" name="用户表">
select row_number() OVER(
order by createtime desc) as 序号,usercode as ID,username as 名称,mobile
as 手机号 from tb_upc_user
</select>
</root> -
java动态设置xml值_Java实现xml动态配置表和字段数据查询
2021-02-26 18:53:59在java里加载解析xml,取数据库相关信息,链接数据库,拼接sql,我这里用jdbc链接,查询表数据,并返回。下面我列出主要的代码供参考,具体解析xml可以通过多种方法,这里就不列了。new oracle.jdbc.driver.Oracle...在java里加载解析xml,取数据库相关信息,链接数据库,拼接sql,我这里用jdbc链接,查询表数据,并返回。下面我列出主要的代码供参考,具体解析xml可以通过多种方法,这里就不列了。
new oracle.jdbc.driver.OracleDriver();
String spath= this.getRequest().getRealPath("/");
spath=spath+"\\dbcofig\\oildbconf.xml";
List atxt = new ArrayList();
//从配置文件里取配置的表名
try {
GetTablenames(spath);
List depttree=getoiltree(this.tableen,this.tablezh,oilbh);
//默认查询第一个表的数据
//取表字段
Getcolsinfo(spath,tableen.get(0));
Getdbinfo(spath);
//取数据库信息
Class.forName(this.driverClass);
con = DriverManager.getConnection(this.jdbcUrl,this.user,this.pwd);
stmt = con.createStatement();
//拼sql选择字段
String strcol="";
for(int i=0;i
if(i==0){
strcol=colen.get(i);
}else{
strcol=strcol+","+colen.get(i);
}
}
String sqlstr="select "+strcol+" from "+tableen.get(0) +" where jh= '"+oilbh+"' order by "+colen.get(0);
result = stmt.executeQuery(sqlstr); //执行SQL 语句,查询数据库
while (result.next()){
Map map = new LinkedHashMap();
for(int j=0;j
map.put(colen.get(j),result.getObject(j+1));
}
atxt.add(map);
}
setAttr("result",atxt);//保存查询结果
result.close();
con.close();
-
MyBatis 源码学习11——动态SQL实现原理(下)
2020-05-12 00:59:32五、动态SQL解析过程 SqlSource用于描述通过XML文件或者Java注解配置的SQL资源信息; SqlNode用于描述动态SQL...1.使用LanguageDriver解析sql语句,将解析后sqlNode对象放入SqlSource对象中,并SqlSource对象放入Mappe五、动态SQL解析过程
SqlSource用于描述通过XML文件或者Java注解配置的SQL资源信息;
SqlNode用于描述动态SQL中
<if>、<where>
等标签信息;LanguageDriver用于对Mapper SQL配置进行解析,将SQL配置转换为SqlSource对象。
MyBatis动态SQL的解析过程,主要分为两部分:
1.使用LanguageDriver解析sql语句,将解析后sqlNode对象放入SqlSource对象中,并SqlSource对象放入MappedStatement对象的属性保存。
2.执行Mapper时,会根据传入的参数信息会调用MappedStatement对象的getBoundSql()方法,方法里会调用SqlSource对象的getBoundSql()方法获取BoundSql对象。整个过程主要是将SqlNode对象转换为SQL语句。
六、动态SQL解析–项目加载时
项目加载时,主要是使用LanguageDriver解析sql语句,将动态SQL配置转换为SqlNode对象,放入SqlSource对象中,并SqlSource对象放入MappedStatement对象的属性保存。
从XMLLanguageDriver类的createSqlSource()方法出发进行分析:
1.首先创建了一个XMLScriptBuilder对象(Mapper SQL配置的解析实际上是委托给XMLScriptBuilder类来完成的),
2.然后调用XMLScriptBuilder对象的parseScriptNode()方法完成解析工作。
XMLScriptBuilder类的parseScriptNode()方法的实现:
1.调用parseDynamicTags()方法将SQL配置转换为SqlNode对象,
2.然后判断SQL配置是否为动态SQL,如果为动态SQL,则创建DynamicSqlSource对象,
3.否则创建RawSqlSource对象。
注意:MyBatis中判断SQL配置是否属于动态SQL的标准是SQL配置是否包含
<if>、<where>、<trim>
等元素或者${}
参数占位符。XMLScriptBuilder类的parseDynamicTags()方法的实现:
1.对SQL配置的所有子元素进行遍历,如果子元素类型为SQL文本,则使用TextSqlNode对象描述SQL节点信息,
2.若SQL节点中存在
${}
参数占位符,则设置XMLScriptBuilder对象的isDynamic属性值为true;3.如果子元素为
<if>、<where>
等标签,则使用对应的NodeHandler处理。XMLScriptBuilder类中定义了一个私有的NodeHandler接口,并为每种动态SQL标签提供了一个NodeHandler接口的实现类,通过实现类处理对应的动态SQL标签,把动态SQL标签转换为对应的SqlNode对象。
XMLScriptBuilder类中为NodeHandler接口提供了8个实现类,每个实现类用于处理对应的动态SQL标签,例如IfHandler用于处理动态SQL配置中的
<if>
标签,将<if>
标签内容转换为IfSqlNode对象。
NodeHandler接口:
NodeHandler接口中只有一个handleNode()方法,该方法接收一个动态SQL标签对应的XNode对象和一个存放SqlNode对象的List对象,
handleNode()方法中对XML标签进行解析后,把生成的SqlNode对象添加到List对象中。IfHandler类的实现:
1.继续调用XMLScriptBuilder类的parseDynamicTags()方法完成
<if>
标签子节点的解析,如果子节点内容为动态SQL标签,继续调用动态SQL标签对应的NodeHandler进行处理,这样就“递归”地完成了所有动态SQL标签的解析。2.将子节点转换为MixedSqlNode对象,
3.然后获取
<if>
标签test属性对应的OGNL表达式,4.接着创建IfSqlNode对象并添加到List对象中。
ForEachHandler类的实现:
调用XMLScriptBuilder类的parseDynamicTags()解析
<foreach>
标签所有子元素,如果子元素中包含<if>
标签或<foreach>
标签,则继续调用IfHandler或者ForEachHandler对象的handleNode()方法进行处理,
直到所有的动态SQL元素全部被转换成SqlNode对象。注意:XMLScriptBuilder类的构造方法中,会调用initNodeHandlerMap()方法将所有NodeHandler的实例注册到Map中,所以解析动态SQL标签时,只需要根据标签名称获取对应的NodeHander对象进行处理即可。
XMLScriptBuilder类的parseScriptNode()方法的实现:
动态SQL标签解析完成后,将解析后生成的SqlNode对象封装在SqlSource对象中。
MyBatis中的MappedStatement用于描述Mapper中的SQL配置,SqlSource创建完毕后,最终会存放在MappedStatement对象的sqlSource属性中。
Executor组件操作数据库时,会调用MappedStatement对象的getBoundSql()方法获取BoundSql对象
七、动态SQL解析–方法调用时
执行Mapper时,会根据传入的参数信息会调用MappedStatement对象的getBoundSql()方法,方法里会调用SqlSource对象的getBoundSql()方法获取BoundSql对象,整个过程主要是将SqlNode对象转换为SQL语句。
DynamicSqlSource类的getBoundSql()方法的实现:
1.首先根据参数对象创建DynamicContext对象,
2.然后调用SqlNode对象的apply()方法对动态SQL进行解析,
3.动态SQL解析完成后,调用DynamicContext对象的getSql()方法获取动态SQL解析后的结果。
4.接着调用SqlSourceBuilder对象的parse()方法对动态SQL解析后的结果进一步解析处理,该方法返回一个StaticSqlSource对象,StaticSqlSource用于描述动态SQL解析后的静态SQL资源。
SqlSourceBuilder类的parse()方法的实现:
1.首先创建了一个ParameterMappingTokenHandler对象,ParameterMappingTokenHandler为MyBatis参数映射处理器,用于处理SQL中的#{}参数占位符。
2.接着创建了一个GenericTokenParser对象,GenericTokenParser用于对SQL中的#{}参数占位符进行解析,获取#{}参数占位符中的内容.
例如下面是一个可能的#{}参数占位符配置:
#{userId,javaType=long,jdbcType=NUMERIC,typeHandler=MyTypeHandler}
该参数占位符经过GenericTokenParser解析后,获取参数占位符内容,即userId,javaType=long,jdbcType=NUMERIC,typeHandler=MyTypeHandler,
该内容会经过ParameterMappingTokenHandler对象进行替换处理。GenericTokenParser类解析#{}参数占位符的过程:
GenericTokenParser的parse()方法中,对SQL配中的所有#{}参数占位符进行解析,获取参数占位符的内容,
然后调用ParameterMappingTokenHandler的handleToken()方法对参数占位符内容进行替换。那么#{}占位符内容到底被替换成了什么呢?
ParameterMappingTokenHandler的handleToken()方法:
1.SQL配置中的所有#{}参数占位符内容都被替换成了“?”字符,因为MyBatis默认情况下会使用PreparedStatement对象与数据库进行交互,设置参数时使用?来占位,
2.调用buildParameterMapping()方法对占位符内容进行解析,将占位符内容转换为ParameterMapping对象。
ParameterMapping对象用于描述MyBatis参数映射信息,便于后续根据参数映射信息获取对应的TypeHandler为PreparedStatement对象设置值。
buildParameterMapping()方法解析参数占位符生成ParameterMapping对象的过程如下:
如上面的代码所示,在ParameterMappingTokenHandler类的buildParameterMapping()方法中首先将参数占位符内容转换为Map对象,例如参数占位符内容如下:
#{userId,javaType=long,jdbcType=NUMERIC,typeHandler=MyTypeHandler}
将会转换成如下Map对象:
然后通过一系列的逻辑判断参数的类型(javaType属性值),最后通过建造者模式构建ParameterMapping对象。
八、从源码角度分析#{}和${}的区别
从源码的角度分析一下MyBatis两种常用的参数占位符#{}和${}的区别。
${}
参数占位符的解析过程:
当动态SQL配置中存在${}
参数占位符时,MyBatis使用TextSqlNode对象描述对应的SQL节点,调用TextSqlNode对象的apply()方法时会完成动态SQL的解析。即${}参数占位符的解析是在TextSqlNode类的apply()方法中完成的,方法的实现:TextSqlNode类的apply()方法的实现:
1.首先调用createParser()方法创建一个GenericTokenParser对象,通过GenericTokenParser对象解析${}参数占位符,
2.然后通过BindingTokenParser对象处理参数占位符的内容。
**createParser()**内容如下:
该方法返回一个GenericTokenParser对象,指定openToken属性为“${”,closeToken属性为“}”,
TokenHandler为BindingTokenParser对象。GenericTokenParser解析参数占位符的过程:
遍历获取所有${}参数占位符的内容,然后调用BindingTokenParser对象的handleToken()方法对参数占位符内容进行替换。BindingTokenParser类的handleToken()方法实现如下:
根据参数占位符名称获取对应的参数值,然后替换为对应的参数值。
假设我们的SQL配置如下:
如果Mapper调用时传入的参数值如下:
上面的Mapper调用将会抛出异常,原因是TextSqlNode类的apply()方法中解析${}参数占位符时,只是对参数占位符内容进行替换,将参数占位符替换
为对应的参数值,因此SQL配置解析后的内容如下:上面的内容是一条不合法的SQL语句,因此会执行失败,如果希望${}参数占位符解析后生成正确的SQL语句,则可以在参数内容前后加上一个单引号,具体如下:
#{}参数占位符的解析过程,可参考SqlSourceBuilder类的parse()方法。假设我们有如下SQL配置:
#{}参数占位符的内容将会被替换为“?”。上面的SQL语句解析后的结果如下:
MyBatis将会使用PreparedStatement对象与数据库进行交互,过程大致如下:
总结一下#{}和${}参数占位符的区别:
${}参数占位符:内容会被直接替换为参数值。
#{}参数占位符:占位符内容会被替换成“?”,然后通过PreparedStatement对象的setXXX()方法为参数占位符设置值,
能够有效避免SQL注入问题,我们可以优先考虑使用#{}占位符,当#{}参数占位符无法满足需求时,才考虑使用${}参数占位符。 -
Java注解2--解析注解与注解反射生成SQL语句
2018-01-31 13:40:25三解析注解 注解处理器解析注解的代码例子...即通过反射获取类、函数或成员上的运行时注解信息,从而实现动态控制程序运行的逻辑。 解析注解主要用到两个类库: 1.1. java.lang.annotation.Annotation Java使用An -
java mysql sqlload_Java调用SqlLoader将大文本数据导入数据库
2021-02-03 23:52:17项目描述将一千万条数据,大约500M的文本文档的数据导入到数据库分析:通过Java的IO流解析txt文本文档,拼接动态sql实现insert入库,可以实现,缺点如下第一:IO流解析大文本文件对机器性能要求较高,测试大约消耗2G... -
JAVA SPI机制解析(JDK11)
2020-03-31 17:38:25在jdk中 java.sql.Driver就是使用了SPI机制。 不同的数据库服务商提供了不同的数据库驱动,为了方便第三方灵活的添加不同的实现,JDK特此提供了解决方案SPI机制,具体实现过程: 定义功能接口 各服务商提供不同的... -
Java调用SqlLoader将大文本导入数据库
2019-10-01 20:28:28分析:通过Java的IO流解析txt文本文档,拼接动态sql实现insert入库,可以实现,缺点如下 第一:IO流解析大文本文件对机器性能要求较高,测试大约消耗2G左右的内存 第二:拼接sql语句insert一千万条数据大约需要2... -
Spark SQL java.lang.StackOverflowError 异常处理
2018-08-31 10:51:03前言 之前写了一个hive业务数据ETL后导出的程序,通过通过SparkSQL实现的,当时的需求是每天导出前一天的数据。数据在hive中是有年月日分区...哈哈,果然,程序一跑在spark解析SQL的时候就报错了,错误如下: Exce... -
jdk8stream+mybatis动态sql代替mybatis foreach in 查询
2018-12-04 15:51:51替换mybatis提供的foreach标签实现in查询,老实讲写sql的时候每次弄那个foreach挺烦的,有时候已经拿到了sql拼接字符还要拆成数组扔到sql里面,深感处理数据还是java代码更方便,于是就想着用这种方式偷懒: 但跑完出来... -
java大数据批量处理实现方式
2018-09-07 10:30:001. 各批量方式对比 Mybatis与JDBC批量插入MySQL数据库性能测试及解决方案 ...1)给spring jdbctemplate加上一层“华丽外衣”-动态SQL&&SQL语句以文件存放 2)Spring JDBC 常用批量操作及插入操作... -
python sql模板_数据开发_SQL模板引擎
2021-02-09 06:45:02SQL模板引擎动态拼接SQL,替换变量,填充数据解析SQL命令动态拼接sql字符方案一:String/StringBuffer/StringBuilder缺点:Java不支持多行字符串,也不能自动解析字符串里的变量一种是利用%操作符实现,另外一种是... -
JAVA_API1.6文档(中文)
2010-04-12 13:31:34javax.sql.rowset.serial 提供实用工具类,允许 SQL 类型与 Java 编程语言数据类型之间的可序列化映射关系。 javax.sql.rowset.spi 第三方供应商在其同步提供者的实现中必须使用的标准类和接口。 javax.swing 提供... -
[Java][MyBatis]物理分页实现
2014-04-10 09:52:11[Java][MyBatis]物理分页实现 Mybatis3.0出来已有段时间了,其实自己挺喜欢这样的一个持久化框架的,因为它简单实用,学习成本低。Mybatis3.0在整体结构上和ibatis2.X差不多,改进...动态sql用OGNL解析 3. 加入注解配 -
java源码包---java 源码 大量 实例
2013-04-18 23:15:26Java实现的FTP连接与数据浏览程序,实现实例化可操作的窗口。 部分源代码摘录: ftpClient = new FtpClient(); //实例化FtpClient对象 String serverAddr=jtfServer.getText(); //得到服务器地址 ... -
java源码包2
2013-04-20 11:28:17Java实现的FTP连接与数据浏览程序,实现实例化可操作的窗口。 部分源代码摘录: ftpClient = new FtpClient(); //实例化FtpClient对象 String serverAddr=jtfServer.getText(); //得到服务器... -
精通Java JDK
2009-06-27 20:03:50HelloWord\JSPDemo2.jsp JSP中使用Java脚本实现动态页面 LoginDemo\JavaBeanDemo.java一个简单的JavaBean的例子 LoginDemo\Check.java Servlet控制器程序 LoginDemo\SQLQuery.java 实现数据库连接及数据验证的... -
java源码包
2015-12-01 16:29:37Java实现的FTP连接与数据浏览程序,实现实例化可操作的窗口。 部分源代码摘录: ftpClient = new FtpClient(); //实例化FtpClient对象 String serverAddr=jtfServer.getText(); //得到服务器地址 ... -
java源码包3
2013-04-20 11:30:13Java实现的FTP连接与数据浏览程序,实现实例化可操作的窗口。 部分源代码摘录: ftpClient = new FtpClient(); //实例化FtpClient对象 String serverAddr=jtfServer.getText(); //得到服务器... -
java开源包1
2013-06-28 09:14:34jSIP这个Java包目标是用Java实现SIP(SIP:Session Initiation Protocol)协议及SIP协议的其它扩展部 分。 Java表达式语法解析库 parboiled parboiled 是一个纯Java库提供了一种轻量级,易于使用,功能强大和优雅的PEG... -
java开源包12
2013-06-28 10:14:45jSIP这个Java包目标是用Java实现SIP(SIP:Session Initiation Protocol)协议及SIP协议的其它扩展部 分。 Java表达式语法解析库 parboiled parboiled 是一个纯Java库提供了一种轻量级,易于使用,功能强大和优雅的PEG... -
Java资源包01
2016-08-31 09:16:25jSIP这个Java包目标是用Java实现SIP(SIP:Session Initiation Protocol)协议及SIP协议的其它扩展部 分。 Java表达式语法解析库 parboiled parboiled 是一个纯Java库提供了一种轻量级,易于使用,功能强大和优雅的PEG... -
java开源包101
2016-07-13 10:11:08jSIP这个Java包目标是用Java实现SIP(SIP:Session Initiation Protocol)协议及SIP协议的其它扩展部 分。 Java表达式语法解析库 parboiled parboiled 是一个纯Java库提供了一种轻量级,易于使用,功能强大和优雅的PEG... -
java开源包11
2013-06-28 10:10:38jSIP这个Java包目标是用Java实现SIP(SIP:Session Initiation Protocol)协议及SIP协议的其它扩展部 分。 Java表达式语法解析库 parboiled parboiled 是一个纯Java库提供了一种轻量级,易于使用,功能强大和优雅的PEG... -
java开源包6
2013-06-28 09:48:32jSIP这个Java包目标是用Java实现SIP(SIP:Session Initiation Protocol)协议及SIP协议的其它扩展部 分。 Java表达式语法解析库 parboiled parboiled 是一个纯Java库提供了一种轻量级,易于使用,功能强大和优雅的PEG... -
java api最新7.0
2013-10-26 17:34:06javax.sql.rowset.serial 提供实用工具类,允许 SQL 类型与 Java 编程语言数据类型之间的可序列化映射关系。 javax.sql.rowset.spi 第三方供应商在其同步提供者的实现中必须使用的标准类和接口。 javax.swing 提供一... -
java开源包10
2013-06-28 10:06:40jSIP这个Java包目标是用Java实现SIP(SIP:Session Initiation Protocol)协议及SIP协议的其它扩展部 分。 Java表达式语法解析库 parboiled parboiled 是一个纯Java库提供了一种轻量级,易于使用,功能强大和优雅的PEG... -
java开源包8
2013-06-28 09:55:26jSIP这个Java包目标是用Java实现SIP(SIP:Session Initiation Protocol)协议及SIP协议的其它扩展部 分。 Java表达式语法解析库 parboiled parboiled 是一个纯Java库提供了一种轻量级,易于使用,功能强大和优雅的PEG... -
java开源包9
2013-06-28 09:58:55jSIP这个Java包目标是用Java实现SIP(SIP:Session Initiation Protocol)协议及SIP协议的其它扩展部 分。 Java表达式语法解析库 parboiled parboiled 是一个纯Java库提供了一种轻量级,易于使用,功能强大和优雅的PEG...
-
有哪些颜值比较高的无线蓝牙耳机?性价比高的蓝牙耳机!
-
Linux路径切换的命令:
-
100行Python代码的贪吃蛇
-
【布道者】Linux极速入门
-
MySQL 函数、用户自定义函数
-
基于java网盘搜索的设计与实现
-
Galera 高可用 MySQL 集群(PXC v5.7+Hapro)
-
常用视频编码格式
-
物联网基础篇:快速玩转MQTT
-
使用 Linux 平台充当 Router 路由器
-
“ValueError: zero-size array to reduction operation maximum which has no identity”解决方法
-
2021-03-02
-
服务器托管、云主机的差别有哪些
-
下降效果
-
使用vue搭建微信H5公众号项目
-
my-first-laravel-package:学习时构建的Laravel包-源码
-
一天学完MySQL数据库
-
一种X型宽带复合左右手传输线的设计与分析
-
test
-
2021-03-02