Do you really know Mybatis of $ # {} and {} do? Whether you understand the application scenario?

Transfer: https: //www.cnblogs.com/mytzq/p/9321526.html

Dynamic sql is one of the main characteristics of mybatis. After the parameters defined in the mapper xml passed in, mybatis will be dynamically resolved before the query.

mybatis provides two support dynamic sql syntax: # {}, $ {}.

select * from t_user where username = '${username}';

select * from t_user where username = #{username};

username parameter passing is consistent, then the result of the implementation of both is the same, but the two handles in the dynamic sql parsing stage is not the same.

1、#{}

It resolves to a JDBC prepared statement (prepared statement) parameter markers, the parameters section with a placeholder? instead. Dynamic resolves to:

select * from t_user where username = ? ;

The argument passed will pass mandatory inspection and safety inspection PreparedStatement methods, and finally as a legitimate string passed.

2、${}

In this way only do simple string replacement, it will be variable substitution dynamic SQL parsing stage, if the parameters passed to Alice, final processing results are as follows:

select * from t_user where username = 'Alice' ;

Such prior precompiled sql statement does not already contain a variable, $ {} can therefore be seen that the stages of the replacement variable dynamic SQL parsing stage.

3, # {}, {} $ two ways Comparative

1) Are prevent SQL Injection

Or more different approach can be seen, after the preprocessing} # {SQL injection can be prevented; $ {} and has been replaced before the pre-compiled, the risk of being injected, the following example:

If the incoming username is a 'or' 1 = 1, then the direct replacement string $ {} after processing to resolve to sql:

select * from t_user where username = a' or '1=1' ;

In this case all user data is checked out, so it belongs to SQL injection.

If # {}, after dynamic resolution and precompiled sql, single quote will escape as \ "sql then ultimately be resolved to:

select * from t_user where username = "a \ 'or \' 1 = 1"; // This will not find any data, effectively prevent sql injection

Some business scenarios frequently used fuzzy query, that is, like processing, recommends the following approach:

t_user.username like #username#

java code:

if (!StringUtil.isEmpty(this.username)) {

table.setUsername("%" + this.username + "%");

}

Or you may use the database connection processing function:

select  * from t_user u where username  like CONCAT('%', #username#, '%')

Note: The above can be found in certain scenarios can only $ {}, such as the order by sort field, table names, column names, because of the need to replace the same constant. If # {}, then the table name, becomes as follows:

select * from # {tablename} -> tablename parameter passing is t_user ---> workup into select * from 't_user', no such table, the error will be so, order by the same token.

2) Performance Considerations

Because the pre-compiled statement object can be reused to generate sql PreparedStatement object after a pre-compiled cached, the next for the same sql, can directly use the cached PreparedStatement object, mybatis default, precompiled for all sql, # {} in this case the handling performance is relatively higher.

to sum up:

{#} Can be used when possible to use # {}

Table, order by sort fields as variables, using the $ {}.

Guess you like

Origin www.cnblogs.com/l3306/p/11465961.html