Java';什么是准备好的报表工作?

Java';什么是准备好的报表工作?,java,jdbc,prepared-statement,Java,Jdbc,Prepared Statement,我计划用PreparedStatement对象替换重复执行的语句对象,以提高性能。我使用的参数包括MySQL函数now(),以及字符串变量 我看到的大多数PreparedStatement查询都包含常量值(如10,以及“New York”等字符串)作为查询中?的参数。我将如何使用函数,如now(),以及变量作为参数?是否需要在查询中使用?而不是实际值?我很困惑。如果有变量,请使用“?” int temp = 75; PreparedStatement pstmt = con.prepareSta

我计划用
PreparedStatement
对象替换重复执行的语句对象,以提高性能。我使用的参数包括MySQL函数
now()
,以及字符串变量


我看到的大多数
PreparedStatement
查询都包含常量值(如
10
,以及
“New York”
等字符串)作为查询中
的参数。我将如何使用函数,如
now()
,以及变量作为参数?是否需要在查询中使用
而不是实际值?我很困惑。

如果有变量,请使用“?”

int temp = 75;
PreparedStatement pstmt = con.prepareStatement(
    "UPDATE test SET num = ?, due = now() ");
pstmt.setInt(1, temp); 
pstmt.executeUpdate():
生成如下所示的sql语句:

UPDATE test SET num = 75, due = now();

如果您有一个来自用户输入的变量,则必须使用?而不是串接字符串。用户可能恶意输入字符串,如果您将字符串直接放入SQL,它可能会运行您不希望的命令

我意识到这一个被过度使用了,但它完美地说明了这一点:


您不必在PreparedStatement中使用占位符。比如:

PreparedStatement stmt = con.prepareStatement("select sysdate from dual");
这样就行了。但是,不能使用占位符,然后将函数调用绑定到占位符。类似的内容不能用于调用sysdate函数:

PreparedStatement stmt = con.prepareStatement("select ? from dual");
stmt.setSomethingOrOther(1, "sysdate");

如果要调用SQL server的内置函数,请使用

如果要调用已加载到SQL server上的存储过程,请使用


将问号用作您正在传递的函数/过程参数和您正在接收的函数返回值的占位符。

我开发了一个函数,允许您在SQL查询中使用命名参数:

private PreparedStatement generatePreparedStatement(String query, Map<String, Object> parameters) throws DatabaseException
    {
        String paramKey = "";
        Object paramValue = null;
        PreparedStatement statement = null;
        Pattern paramRegex = null; 
        Matcher paramMatcher = null;
        int paramIndex = 1;

        try
        {
            //Create the condition
            paramRegex = Pattern.compile("(:[\\d\\w_-]+)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE);
            paramMatcher = paramRegex.matcher(query);
            statement = this.m_Connection.prepareStatement(paramMatcher.replaceAll("?"),
                                ResultSet.TYPE_FORWARD_ONLY,
                                ResultSet.CONCUR_READ_ONLY, 
                                ResultSet.HOLD_CURSORS_OVER_COMMIT);

            //Check if there are parameters
            paramMatcher = paramRegex.matcher(query);
            while (paramMatcher.find()) 
            {
                paramKey = paramMatcher.group().substring(1);
                if(parameters != null && parameters.containsKey(paramKey))
                {
                    //Add the parameter 
                    paramValue = parameters.get(paramKey);
                    if (paramValue instanceof Date) 
                    {
                        statement.setDate(paramIndex, (java.sql.Date)paramValue);                 
                    } 
                    else if (paramValue instanceof Double) 
                    {
                        statement.setDouble(paramIndex, (Double)paramValue);                  
                    } 
                    else if (paramValue instanceof Long) 
                    {
                        statement.setLong(paramIndex, (Long)paramValue);                  
                    } 
                    else if (paramValue instanceof Integer) 
                    {
                        statement.setInt(paramIndex, (Integer)paramValue);                
                    } 
                    else if (paramValue instanceof Boolean) 
                    {
                        statement.setBoolean(paramIndex, (Boolean)paramValue);                
                    } 
                    else 
                    {
                        statement.setString(paramIndex, paramValue.toString());     
                    }
                }
                else
                {
                    throw new DatabaseException("The parameter '" + paramKey + "' doesn't exists in the filter '" + query + "'");
                }

                paramIndex++;
            }
        }
        catch (SQLException  l_ex) 
        {
            throw new DatabaseException(tag.lib.common.ExceptionUtils.getFullMessage(l_ex));
        }

        return statement;
    }
private PreparedStatement generatePreparedStatement(字符串查询、映射参数)引发DatabaseException
{
字符串paramKey=“”;
对象参数值=null;
PreparedStatement=null;
Pattern paramRegex=null;
Matcher参数Matcher=null;
int参数索引=1;
尝试
{
//创造条件
paramRegex=Pattern.compile((:[\\d\\w-]+),Pattern.CASE|u不区分| Pattern.MULTILINE);
paramMatcher=paramRegex.matcher(查询);
语句=this.m_Connection.prepareStatement(paramMatcher.replaceAll(“?”),
ResultSet.TYPE_FORWARD_ONLY,
ResultSet.CONCUR\u只读,
ResultSet.HOLD\u游标\u OVER\u提交);
//检查是否有参数
paramMatcher=paramRegex.matcher(查询);
while(paramMatcher.find())
{
paramKey=paramMatcher.group().substring(1);
if(parameters!=null&¶meters.containsKey(paramKey))
{
//添加参数
paramValue=parameters.get(paramKey);
if(参数值instanceof Date)
{
语句.setDate(paramIndex,(java.sql.Date)paramValue);
} 
else if(参数值instanceof Double)
{
语句.setDouble(paramIndex,(Double)paramValue);
} 
else if(paramValue instanceof Long)
{
语句.setLong(paramIndex,(Long)paramValue);
} 
else if(参数值instanceof Integer)
{
语句.setInt(paramIndex,(Integer)paramValue);
} 
else if(布尔值的参数值实例)
{
语句.setBoolean(paramIndex,(布尔)paramValue);
} 
其他的
{
语句.setString(paramIndex,paramValue.toString());
}
}
其他的
{
抛出新的DatabaseException(“过滤器“+”查询“”)中不存在参数“'+paramKey+””;
}
paramIndex++;
}
}
捕获(SQLException l_ex)
{
抛出新的DatabaseException(tag.lib.common.ExceptionUtils.getFullMessage(l_ex));
}
返回语句;
}
您可以这样使用它:

Map<String, Object> pars = new HashMap<>();
pars.put("name", "O'Really");
String sql = "SELECT * FROM TABLE WHERE NAME = :name";
Map pars=newhashmap();
帕斯·普特(“名字”、“真的”);
String sql=“从表中选择*,其中NAME=:NAME”;

您是否在询问是否可以使用字符串值函数代替字符串文本?您是否在问是否可以使用int值函数代替文字整数?你能提供一个代码片段吗?我相信,你指的是SQL注入。对于大多数数据库系统来说,这是不正确的。大多数数据库系统将准备查询文本,然后在执行时发送参数值。这将永远不会生成一个包含参数值的语句。