精华内容
下载资源
问答
  • 一、根据传入的参数动态替换SQL参数 1、需求:以新增insert语句为例 2、实现类 package test.util; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; public class ...

    一、根据传入的参数动态替换SQL的参数

    1、需求:以新增insert语句为例

    2、实现类

    package test.util;
    
    import java.util.Map;
    import java.util.regex.Matcher;
    import java.util.regex.Pattern;
    
    public  class SqlUtils{
    	public static String getSavesql(String sql, Map<String, String> map) {
    		StringBuffer rsql = new StringBuffer(); //接口对应的sql
    		Pattern p = Pattern.compile(rge); //编译对象
    		Matcher m = p.matcher(sql); //进行匹配
    		int index=0;
    		int length=sql.length();
    		while(m.find()) {
    			int start=m.start();
    			String text=m.group();
    			System.out.println("参数信息:"+text); //一定要先find(),然后才能group()
    			if(index<start) {
    				rsql.append(sql.substring(index,start));
    			}
    			//三元表达式 (expr1)?(expr2):(expr3) 在 expr1 求值为 true 时的值为 expr2,在 expr1 求值为 false 时的值为 expr3
    			//当传入的参数等于null时,该参数对应的值为null
    			rsql.append(map.get(text.substring(text.indexOf("#{")+2,text.indexOf("}")).trim())==null?null:"'"+map.get(text.substring(text.indexOf("#{")+2,text.indexOf("}")).trim())+"'");
    			index=m.end();
    		}
    		if(index<length) {
    			rsql.append(sql.substring(index,length));
    		}
    		System.out.println("————————————————————————————————————————————————————————————\n最终的SQL语句:"+rsql.toString());
    		return rsql.toString();
    	}
    }

    3、实现类

    package test.main;
    
    import java.util.HashMap;
    import java.util.Map;
    
    import test.util.SqlUtils;
    
    public class TestSqL {
    	public static void main(String[] args) {
    		String sql="insert into user(id,name,sex,phone,createDate)values(#{id},#{name},#{sex},#{phone},#{createDate})";
    		Map<String, String> map = new HashMap<>();
    		map.put("id","202011030001");
    		map.put("name","来福");
    		map.put("sex","男");
    		map.put("createDate","2020-11-30");
    		String sql1 = SqlUtils.getSavesql(sql,map);
    	}
    	

    4、控制台输出

    参数信息:#{id}
    参数信息:#{name}
    参数信息:#{sex}
    参数信息:#{phone}
    参数信息:#{createDate}
    ————————————————————————————————————————————————————————————
    最终的SQL语句:insert into user(id,name,sex,phone,createDate)values('202011030001','来福','男',null,'2020-11-30')

    二、在修改语句时,如果没有传入某参数,则该参数的值为null,导致数据错误

    1、情况如:修改语句中只想修改name参数,于是没有传入其他参数,导致sex、phone等参数被动修改为null

    2、方案:修改前先查询该数据,并将查询结果作为参数传入修改语句

    3、逻辑:修改语句中id为必传参数,此刻我们可以根据id去查询相关数据,将查询结果作为参数重新传入,根据put的相同key值会被覆盖原则,我们可以实现新值替换原有值

    4、实现:需要注意的是,必须先赋值,再put新参数,根据java自上而下的执行顺序,值会被最后添加的覆盖

    String sql="update user set name = #{name},sex = #{sex},phone = #{phone} where id = #{id}";
    Map<String,String> map =new HashMap(); //参数
    Map<String,String> obj =userDao.get(map); //根据传入的参数去查询结果(主要用到id参数)
    map=obj;//将查询出来的值,作为参数,赋值给原参数对象
    map.put("id","202011030002");
    map.put("sex","保密");//map的put方法,遇到相同的key值会被覆盖
    String sql1 = SqlUtils.getSavesql(sql,map);

     

    展开全文
  • java预编译SQL参数替换 更新····PSF 源代码下载地址:http://www.zuidaima.com/share/1550463668718592.htm

    原文:java预编译SQL和参数替换 更新····PSF

    源代码下载地址:http://www.zuidaima.com/share/1550463668718592.htm

    功能为将项目中输出的预编译SQL语句,转换为带实际参数的SQL语句。

    代码为javaSwing,启动类为AppStart.java。

    界面如下图:

    java预编译SQL和参数替换 更新····PSF



    展开全文
  • 软件介绍: SQL拼接替换程序能够替换Java开发...直接将参数替换SQL中的问号。填写要替换的SQL语句及参数,能够生成SQL代码。需要Java中写好的SQL填写上,直接将参数逗号隔开依次写入,直接可替换生成可执行SQL语句。
  • [框架]Mybatis中预编译sql参数替换

    千次阅读 2019-01-29 20:40:12
    在回顾@Param注解时,发现自己并不理解mepper.xml里sql语句的参数设置。之前认为的是,如果参数类型为Bean,那么语句内填写的参数名应与Bean中get方法名对应。例如: UserMapper.xml &lt;insert id="...

    一、前言

    在回顾@Param注解时,发现自己并不理解mepper.xml里sql语句的参数设置。之前认为的是,如果参数类型为Bean,那么语句内填写的参数名应与Bean中get方法名对应。例如:

    UserMapper.xml

    
    <insert id="addOne" parameterType="com.demo.pojo.User">
    	insert into user values(null,#{name},#{addr},#{age})
    </insert>

    那么按我之前的想法,User类中必须存在getName()、getAddr()、getAge()三个方法,User.java

    public class User {
    
        private Integer id;
        private String name;
        private String addr;
        private Integer age;
    
        // setters and getters
        public Integer getId() {
            return id;
        }
    
        public void setId(Integer id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getAddr() {
            return addr;
        }
    
        public void setAddr(String addr) {
            this.addr = addr;
        }
    
        public Integer getAge() {
            return age;
        }
    
        
        public void setAge(Integer age) {
            this.age= age;
        }
    
    }
    

    但是在我后面的测试中,发现如果将get方法名或属性名中任意一个改成与xml中需要的参数名不对应,也能完成插入操作。也就是说,只有在get方法名与属性名都与xml中参数名不对应时,如:方法名为getAgg()、属性名为ag、xml中#{age},才会抛异常,异常信息为:

    There is no getter for property named 'age' in 'class com.demo.pojo.User'

    二、探究 

    在发现实际运行结果与理解出了偏差后,第一时间去Mybatis官网查看了下xml中对参数的要求,其中写到:

    <insert id="insertUser" parameterType="User">
      insert into users (id, username, password)
      values (#{id}, #{username}, #{password})
    </insert>

    If a parameter object of type User was passed into that statement, the id, username and password property would be looked up and their values passed to a PreparedStatement parameter.

    大概意思是,id、username和password三个属性将被寻找。但是没说怎么寻找,在哪寻找,也没说如果参数名不匹配会发生什么。在尝试了百度、询问老师、debug跟踪后,最后将目光锁定在DefaultParameterHandler类中的setParameters()方法上:

    // DefaultParameterHandler类
    public void setParameters(PreparedStatement ps) throws SQLException {
        ErrorContext.instance().activity("setting parameters").object(mappedStatement.getParameterMap().getId());
        List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
        if (parameterMappings != null) {
            for (int i = 0; i < parameterMappings.size(); i++) {
                ParameterMapping parameterMapping = parameterMappings.get(i);
                if (parameterMapping.getMode() != ParameterMode.OUT) {
                    Object value;
                    // 获取需要的参数名,如 #{name},propertyName = "name"
                    String propertyName = parameterMapping.getProperty();
                    if (boundSql.hasAdditionalParameter(propertyName)) { // issue #448 ask first for additional params
                        value = boundSql.getAdditionalParameter(propertyName);
                    } else if (parameterObject == null) {
                        value = null;
                    } else if (typeHandlerRegistry.hasTypeHandler(parameterObject.getClass())) {
                        value = parameterObject;
                    } else {
                        // 如果xml中paramType为简单Bean类,将执行此句,通过传入User的对象构建元对象
                        MetaObject metaObject = configuration.newMetaObject(parameterObject);
                        // 通过反射,调用get方法,获得存放在对象中的参数值
                        value = metaObject.getValue(propertyName);
                    }
                    TypeHandler typeHandler = parameterMapping.getTypeHandler();
                    JdbcType jdbcType = parameterMapping.getJdbcType();
                    if (value == null && jdbcType == null)
                        jdbcType = configuration.getJdbcTypeForNull();
                    typeHandler.setParameter(ps, i + 1, value, jdbcType);
                }
            }
        }
    }

    当我们在xml中写到#{age}、User类中方法为getAgg()时,上述方法中的propertyName="age"。MetaObject(元对象)又是如何根据“age”执行User类中getAgg()方法呢?继续跟踪,发现MetaObject对象通过调用了Reflector对象的getGetInvoker()方法拿到get方法:

    // Reflector类
    public Invoker getGetInvoker(String propertyName) {
       Invoker method = getMethods.get(propertyName);
       if (method == null) {
         throw new ReflectionException("There is no getter for property named '" + propertyName + "' in '" + type + "'");
       }
       return method;
     }

     目标一下明朗起来,只要知道这个叫getMethods的map里到底存了什么东西,什么时候存了东西,问题就好解决了。

    三、原因

    原来,在准备连接前,Mybatis会新建多个Reflector类的对象,其中一个就是用来保存User中属性的get方法的。类中getMethods属性为HashMap<String, Invoker>,用于存放get方法的映射,键为User中所有属性名与getXXX()方法名的XXX。类中涉及到向getMethods添加的主要方法有:

    // Reflector类
    private void addGetMethod(String name, Method method) {
       if (isValidPropertyName(name)) {
         getMethods.put(name, new MethodInvoker(method));
         getTypes.put(name, method.getReturnType());
       }
    }
    
    private void addGetField(Field field) {
       if (isValidPropertyName(field.getName())) {
         getMethods.put(field.getName(), new GetFieldInvoker(field));
         getTypes.put(field.getName(), field.getType());
       }
    }

    当执行addGetField()方法时,发现属性age没有与之匹配的get方法(之前添加的是getAgg(),键为“agg”),在这Mybatis会为该属性新建get方法,存入getMethods中!这也就是为什么即便修改了User中的get方法名或属性名,只要保证其中有一项与xml中的参数名相同,就可获取User对象中的相应属性值,完成对预编译sql语句的拼接。

    四、总结

    对于下面这条xml中的语句,只要User类中存在与参数名对应的属性名或get方法名,Mybatis即可完成对sql语句的拼接。

    <insert id="addOne" parameterType="com.demo.pojo.User">
    	insert into user values(null,#{name},#{addr},#{age})
    </insert>

    对于参数 #{name} 来说:

    • 只要User类中存在名叫name的属性,不存在getName()方法也可执行成功;
    • 或者User类中存在getName()方法,不存在名为name属性也可完成拼接;
    • 当User类中既没有名叫name的属性,又没有getName()方法,抛出异常。 

    在Mybatis将从数据库中查询的结果封装到VO对象时,也遵循类似规则。即,数据库表字段名和VO对象的属性名、set方法其中一者存在对应关系便可完成该属性的赋值,否则对象的该属性值为null。

    但是在以后的开发中,VO对象的编写还是要遵循规范。因为不仅是Mybatis在使用,Spring的依赖注入对VO的set方法名有严格要求。

     

    参考:

    MyBatis主流程分析之(三)-准备SQL语句和参数替换、执行

    《深入理解mybatis原理》 MyBatis的架构设计以及实例分析

    Mybatis参数变量替换流程

    展开全文
  • SQL拼接替换程序

    2018-06-14 10:46:21
    程序可以替换Java开发中SQL语句中参数的替换拼接,便于在数据库中执行Java开发中SQL语句。直接将参数替换SQL中的问号。将Java中写好的SQL拿出来,直接将参数逗号隔开依次写入,直接可替换生成可执行SQL语句。
  • 前端传到后台两个参数,1,张三,需要用前端传递的两个参数替换SQL中参数 假如两个参数在一个String[] parameterList ={“1”,“张三”}; 实现方式:sql = sql.format(sql, parameterList); 执行上面代码后sql=...

    Java根据id从数据库查询到SQL,SQL中需要传参的地方用%s表示,

    例如 String sql = "SELECT * FROM a WHERE a.id ='%s' AND a.name LIKE '%s%' ";

    前端传到后台两个参数,1,张三,需要用前端传递的两个参数替换SQL中参数

    假如两个参数在一个String[] parameterList ={“1”,“张三”};

    实现方式:sql = sql.format(sql, parameterList);

    执行上面代码后sql="SELECT * FROM a WHERE a.id ='1' AND a.name LIKE '%张三%' ";

    到此,参数替换成功。

     

     

    注意:如果参数不需要模糊查询,在数据库中的sql定义参数的时候,a.id='%s'即可,如果是模糊查询需要前后都模糊,需要参数定义为:a.name LIKE '%%%s%%'。因为%在format中使用时是特殊字符。

    展开全文
  • 参数如果要替换sql中的关键字怎么办啊,不是占位符,是替换,像mybati中的#
  • java原生sql操作数据库

    千次阅读 2012-06-23 08:15:30
    import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.SQLExcep
  • java封装sql查询

    千次阅读 2010-08-11 11:22:00
    import java.lang.reflect.Field;...import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException;import java.util.ArrayList;import
  • Linux命令参数防注入 java实现

    万次阅读 2020-08-28 09:20:58
    在最近一个项目中,需要在java平台上调用Linux命令,实现对Linux系统的操作。 命令参数注入说明 比如获取某个目录下面的文件信息,Linux命令如下: ls /opt/test 其中/opt/test是传入的参数值 传入的参数如果不...
  • mybatis输出执行sql替换?

    千次阅读 2019-09-07 15:32:07
    mybatis输出执行sql替换? mybatis.xml允许用户进行自定义插件plugins 插件需要实现Interceptor接口 代码如下: MyBatisSQLMonitorPlugin.java import org.apache.ibatis.executor.Executor; import org.apache....
  • 1. 工具类方法 ... * 替换sql中的占位参数 */ public static String getSql(String indexImpl, LinkedHashMap<String, String> params) { //匹配#{*}格式的占位参数 // Pattern pattern = Pattern....
  • Java防止SQL注入

    千次阅读 2014-09-23 17:32:56
    Java防止SQL注入 SQL 注入简介:  SQL注入是最常见的攻击方式之一,它不是利用操作系统或其它系统的漏洞来实现攻击的,而是程序员因为没有做好判断,被不法 用户钻了SQL的空子,下面我们先来看下...
  • SQL注入是比较常见的网络攻击方式之一,它不是利用操作系统的BUG来实现攻击,而是针对程序员编程时的疏忽,通过SQL语句,实现无帐号登录,甚至篡改数据库。 二、SQL注入攻击的总体思路 1.寻找到SQL注入的位置 2....
  • 在 MyBatis主流程分析之(二)-打开会话和数据库操作 中我们只讲了一个主流程,没有深入了解mybatis是如何准备sql语句,如何替换参数,最后查询,新增和删除数据的。这里再补充一下,深入了解。一、JDBC方式新增数据...
  • java.sql.SQLException错误

    万次阅读 2015-09-20 13:26:28
    java.sql.SQLException错误!ORA-00904: –invalid column name 无效列名ORA-00942: –table or view does not exist 表或者视图不存在ORA-01400: –cannot insert NULL into () 不能将空值插入ORA-00936: –缺少...
  • java处理SQL特殊字符转义 防止sql注入

    千次阅读 2016-06-29 18:14:10
    SQL特殊字符转义 应 该说,您即使没有处理 HTML 或 JavaScript 的特殊字符,也不会带来灾难性的后果,但是如果不在动态构造 SQL 语句时对变量中特殊字符进行处理,将可能导致程序漏洞、数据盗取、数据破坏等严重...
  • JAVA获取执行sql

    千次阅读 2017-08-25 11:31:46
    java获取执行SQL
  • JavaSQL注入问题

    千次阅读 2009-08-20 10:31:00
    随着B/S模式应用开发的发展,使用这种模式编写应用...用户可以提交一段数据库查询代码,根据程序返回的结果,获得某些他想得知的数据,这就是所谓的SQL Injection,即SQL注入。SQL注入是从正常的WWW端口访问,
  • 某位小伙伴,就称为小明,小明写爬虫程序喜欢将搜索框参数直接输入一个“%”,于是就可以爬取到所有结果,这样的小技巧其实是有理有据的。 我们都知道SQL的模糊匹配查询like,比如select * from table where field ...
  • Java连接SQL Server 2000的问题二

    千次阅读 2006-10-24 09:46:00
    java自身提供了对各类主流数据库系统的支持,通过java.sql 库,提供了统一的接口,使得可以在java环境下不必对程序作大规模的修改,只要更改相应的驱动程序,即可实现对各类数据库的操作,从而提高软件的生存周期和...
  • org.springframework.dao.TransientDataAccessResourceException: Error attempting to get column 'create_time' from result set. Cause: java.sql.SQLException: Value '0000-00-00' can not be represented as
  • 以下转自:http://kummy.itpub.net/post/17165/172850 本文在原文基础上有增减。 本概述是从《JDBCTM Database Access from Java
  • 1.linux搭建Java和Scala环境搭建 2. linux搭建hadoop+spark+hive分布式集群 hadoop分布式集群搭建:hadoop分布式集群搭建 spark分布式集群搭建:spark分布式集群搭建 hive分布式集群搭建:待完善 二.项目代码...
  • java.sql.SQLSyntaxErrorException: ORA-00971: 缺失 SET 关键字

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 82,316
精华内容 32,926
关键字:

java实现sql参数替换

java 订阅