MyBatis String as Parameter

2019-02-06 20:37发布

问题:

I want to use a String parameter for a Select Statement in MyBatis. My mapper.xml:

<select id="selectAll" parameterType="String" resultMap="fastXMLResultMap">
        SELECT CREATIONDATE, DOCUMENTID, TITEL, REGTITEL, INFORCEDATE, DOCTYPE
        FROM #{databBaseTable}
</select>

And the calling function:

public List<FastXMLObject> selectAll(String databBaseTable) {

    SqlSession session = sqlSessionFactory.openSession();

    System.out.println("Table: "+databBaseTable);

    try {
        List<FastXMLObject> list = session.selectList("FastXMLObject.selectAll",databBaseTable);
        return list;
    } finally {
        session.close();
    }
}

The string dataBaseTable is the name of the table of my database (who would have thought that) because I want to get data dynamically from verious tables.

But unfortunatelly this does not work: Error: ORA-00903: Ungültiger Tabellenname (invalid table name) but it isnt. When I print out the value of "databBaseTable" it is the exact name of the table. And when I write the name of the table to my mapper.xml without a variable it works. What do I do wrong?

回答1:

Use ${dataBaseTable} instead of '#'. The difference is that '#' is used for PreparedStatement substitution. '$' is for direct String substitution.

However, if you do this, you can't pass the table name in as a parameter to the selectList() call. You need to set the table name as a property. Properties can be set by using the <properties> element in the MyBatis config.xml or directly in code by using Configuration.getVariables().

See the 'String Substitution' section in the MyBatis Docs.



回答2:

Ok I definitely do not know why this works but I just used the following to solve the problem:

<select id="selectAll" parameterType="String" resultMap="fastXMLResultMap">
        SELECT CREATIONDATE, DOCUMENTID, TITEL, REGTITEL, INFORCEDATE, DOCTYPE
        FROM ${value}
</select>

I did not set any properties or something else, it was just the change from FROM #{databBaseTable} to FROM ${value}

I someone could answer why this works would be nice. But for now this really helped me.



回答3:

With the #{..} syntax MyBatis uses a jdbc PreparedStatement object upon which you cannot specify the table name as a parameter. With #{..} you can only parameterize the parameters of the sql statement.

When you use ${..} syntax MyBatis does plain old string substition so your free to parameterize pretty much any part of the sql you desire.

Note: as a by the way: with #{..} you are pretty safe from sql injection, but with ${..} it does open the door to such attacks