精华内容
下载资源
问答
  • System.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功能,前些日子写了一个,基本实现( [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,取数据库相关信息,链接数据库,拼接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();

    展开全文
  • 五、动态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注入问题,我们可以优先考虑使用#{}占位符,当#{}参数占位符无法满足需求时,才考虑使用${}参数占位符。

    展开全文
  • 解析注解 注解处理器解析注解的代码例子...即通过反射获取类、函数或成员上的运行时注解信息,从而实现动态控制程序运行的逻辑。 解析注解主要用到两个类库: 1.1. java.lang.annotation.Annotation Java使用An
  • 项目描述将一千万条数据,大约500M的文本文档的数据导入到数据库分析:通过Java的IO流解析txt文本文档,拼接动态sql实现insert入库,可以实现,缺点如下第一:IO流解析大文本文件对机器性能要求较高,测试大约消耗2G...
  • 在jdk中 java.sql.Driver就是使用了SPI机制。 不同的数据库服务商提供了不同的数据库驱动,为了方便第三方灵活的添加不同的实现,JDK特此提供了解决方案SPI机制,具体实现过程: 定义功能接口 各服务商提供不同的...
  •  分析:通过Java的IO流解析txt文本文档,拼接动态sql实现insert入库,可以实现,缺点如下 第一:IO流解析大文本文件对机器性能要求较高,测试大约消耗2G左右的内存 第二:拼接sql语句insert一千万条数据大约需要2...
  • 前言 之前写了一个hive业务数据ETL后导出的程序,通过通过SparkSQL实现的,当时的需求是每天导出前一天的数据。数据在hive中是有年月日分区...哈哈,果然,程序一跑在spark解析SQL的时候就报错了,错误如下: Exce...
  • 替换mybatis提供的foreach标签实现in查询,老实讲写sql的时候每次弄那个foreach挺烦的,有时候已经拿到了sql拼接字符还要拆成数组扔到sql里面,深感处理数据还是java代码更方便,于是就想着用这种方式偷懒: 但跑完出来...
  • 1. 各批量方式对比 Mybatis与JDBC批量插入MySQL数据库性能测试及解决方案 ...1)给spring jdbctemplate加上一层“华丽外衣”-动态SQL&&SQL语句以文件存放 2)Spring JDBC 常用批量操作及插入操作...
  • SQL模板引擎动态拼接SQL,替换变量,填充数据解析SQL命令动态拼接sql字符方案一:String/StringBuffer/StringBuilder缺点:Java不支持多行字符串,也不能自动解析字符串里的变量一种是利用%操作符实现,另外一种是...
  • JAVA_API1.6文档(中文)

    万次下载 热门讨论 2010-04-12 13:31:34
    javax.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:26
     Java实现的FTP连接与数据浏览程序,实现实例化可操作的窗口。  部分源代码摘录:  ftpClient = new FtpClient(); //实例化FtpClient对象  String serverAddr=jtfServer.getText(); //得到服务器地址  ...
  • java源码包2

    千次下载 热门讨论 2013-04-20 11:28:17
     Java实现的FTP连接与数据浏览程序,实现实例化可操作的窗口。  部分源代码摘录:  ftpClient = new FtpClient(); //实例化FtpClient对象  String serverAddr=jtfServer.getText(); //得到服务器...
  • 精通Java JDK

    热门讨论 2009-06-27 20:03:50
    HelloWord\JSPDemo2.jsp JSP中使用Java脚本实现动态页面 LoginDemo\JavaBeanDemo.java一个简单的JavaBean的例子 LoginDemo\Check.java Servlet控制器程序 LoginDemo\SQLQuery.java 实现数据库连接及数据验证的...
  • java源码包

    2015-12-01 16:29:37
     Java实现的FTP连接与数据浏览程序,实现实例化可操作的窗口。  部分源代码摘录:  ftpClient = new FtpClient(); //实例化FtpClient对象  String serverAddr=jtfServer.getText(); //得到服务器地址  ...
  • java源码包3

    千次下载 热门讨论 2013-04-20 11:30:13
     Java实现的FTP连接与数据浏览程序,实现实例化可操作的窗口。  部分源代码摘录:  ftpClient = new FtpClient(); //实例化FtpClient对象  String serverAddr=jtfServer.getText(); //得到服务器...
  • java开源包1

    千次下载 热门讨论 2013-06-28 09:14:34
    jSIP这个Java包目标是用Java实现SIP(SIP:Session Initiation Protocol)协议及SIP协议的其它扩展部 分。 Java表达式语法解析库 parboiled parboiled 是一个纯Java库提供了一种轻量级,易于使用,功能强大和优雅的PEG...
  • java开源包12

    热门讨论 2013-06-28 10:14:45
    jSIP这个Java包目标是用Java实现SIP(SIP:Session Initiation Protocol)协议及SIP协议的其它扩展部 分。 Java表达式语法解析库 parboiled parboiled 是一个纯Java库提供了一种轻量级,易于使用,功能强大和优雅的PEG...
  • Java资源包01

    2016-08-31 09:16:25
    jSIP这个Java包目标是用Java实现SIP(SIP:Session Initiation Protocol)协议及SIP协议的其它扩展部 分。 Java表达式语法解析库 parboiled parboiled 是一个纯Java库提供了一种轻量级,易于使用,功能强大和优雅的PEG...
  • java开源包101

    2016-07-13 10:11:08
    jSIP这个Java包目标是用Java实现SIP(SIP:Session Initiation Protocol)协议及SIP协议的其它扩展部 分。 Java表达式语法解析库 parboiled parboiled 是一个纯Java库提供了一种轻量级,易于使用,功能强大和优雅的PEG...
  • java开源包11

    热门讨论 2013-06-28 10:10:38
    jSIP这个Java包目标是用Java实现SIP(SIP:Session Initiation Protocol)协议及SIP协议的其它扩展部 分。 Java表达式语法解析库 parboiled parboiled 是一个纯Java库提供了一种轻量级,易于使用,功能强大和优雅的PEG...
  • java开源包6

    热门讨论 2013-06-28 09:48:32
    jSIP这个Java包目标是用Java实现SIP(SIP:Session Initiation Protocol)协议及SIP协议的其它扩展部 分。 Java表达式语法解析库 parboiled parboiled 是一个纯Java库提供了一种轻量级,易于使用,功能强大和优雅的PEG...
  • java api最新7.0

    千次下载 热门讨论 2013-10-26 17:34:06
    javax.sql.rowset.serial 提供实用工具类,允许 SQL 类型与 Java 编程语言数据类型之间的可序列化映射关系。 javax.sql.rowset.spi 第三方供应商在其同步提供者的实现中必须使用的标准类和接口。 javax.swing 提供一...
  • java开源包10

    热门讨论 2013-06-28 10:06:40
    jSIP这个Java包目标是用Java实现SIP(SIP:Session Initiation Protocol)协议及SIP协议的其它扩展部 分。 Java表达式语法解析库 parboiled parboiled 是一个纯Java库提供了一种轻量级,易于使用,功能强大和优雅的PEG...
  • java开源包8

    热门讨论 2013-06-28 09:55:26
    jSIP这个Java包目标是用Java实现SIP(SIP:Session Initiation Protocol)协议及SIP协议的其它扩展部 分。 Java表达式语法解析库 parboiled parboiled 是一个纯Java库提供了一种轻量级,易于使用,功能强大和优雅的PEG...
  • java开源包9

    热门讨论 2013-06-28 09:58:55
    jSIP这个Java包目标是用Java实现SIP(SIP:Session Initiation Protocol)协议及SIP协议的其它扩展部 分。 Java表达式语法解析库 parboiled parboiled 是一个纯Java库提供了一种轻量级,易于使用,功能强大和优雅的PEG...

空空如也

空空如也

1 2 3 4 5 ... 9
收藏数 161
精华内容 64
关键字:

java实现动态解析sql

java 订阅