MyBatisのは、$#{}とを区別し、{A}
主に相違このセクションでは、$#{}とをMyBatisの{A}
まず、コード例を介して2つ下の違いを参照してください。
EmployeeMapperインタフェースのような方法があります:
Employee getEmpByIdAndLastName(@Param("id")Integer id, @Param("lastName") String lastName);
対応するEmployeeMapper.xmlマッピングファイルのSQL構文で:
<select id="getEmpByIdAndLastName" resultType="employee">
select id,last_name ,email,gender from tbl_employee where id = ${id} and last_name = #{lastName}
</select>
テストコード:
public class MybatisTest {
public SqlSessionFactory sessionFactory = null;
@BeforeEach
public void test()throws Exception{
// 根据全局配置文件(xml)创建一个SqlSessionFactory对象
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
sessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
}
@Test
public void selectTest(){
// 获取 SqlSession 的实例 。SqlSession 完全包含了面向数据库执行 SQL 命令所需的所有方法。通过 SqlSession 实例来直接执行已映射的 SQL 语句
SqlSession sqlSession = null;
try {
sqlSession = sessionFactory.openSession();
// 通过获取接口代理对象来执行sql语句
EmployeeMapper mapper = sqlSession.getMapper(EmployeeMapper.class);
Employee employee = mapper.getEmpByIdAndLastName(2,"BB");
System.out.println(employee.getLastName()); // AA
} finally {
// 资源关闭,放在finally中确保一定会执行
sqlSession.close();
}
}
}
実装の最終的な結果は以下の通り:
DEBUG 05-07 22:52:42,700 ==> Preparing: select id,last_name ,email,gender from tbl_employee where id = 2 and last_name = ? (BaseJdbcLogger.java:145)
DEBUG 05-07 22:52:42,801 ==> Parameters: BB(String) (BaseJdbcLogger.java:145)
DEBUG 05-07 22:52:42,823 <== Total: 1 (BaseJdbcLogger.java:145)
BB
注意:ログレコード内のSQLステートメントがあります
select id,last_name ,email,gender from tbl_employee where id = 2 and last_name = ?
ここで、$ {ID}直接受信パラメータに置き換え、そして#{lastNameの}になるようにプリコンパイルされた方法に基づいているのですか?
要約:
同じポイント:
- #{}:POJO値または値は、マップオブジェクトのプロパティで得ることができます。
- $ {}:POJO値または値がマップオブジェクトのプロパティで得ることができます。
違い:
- #{}:フォームは、SQLステートメントにパラメータを設定し、プリコンパイルされ、PreparedStatementの、SQLインジェクションを防止します
- $ {}は:直接撮影したSQL文で組み立て値は、セキュリティ上の問題を提起します。
注意:ほとんどの場合、パラメータの値は、我々は#{}を使用することを行く必要があります。
どのような状況下で、$ {}を使用します。
ネイティブJDBCは、我々はそのような列名として、値の$ {}を使用することができますローカルプレースホルダをサポートするテーブルを指して、ソートされません。。。
// 按照年份分表
select * from ${year}_salary where xxx;
// 排序
select * from tbl_employee order by ${f_name} ${order}
......................................................
以下は、拡張したものです
#{}豊かな使用
まず、MyBatisの同じパラメータの他の部分と同様に、特定のデータ型を指定することができます。
#{property,javaType=int,jdbcType=NUMERIC}
オブジェクトはHashMapのでない限り、同じMyBatisの他の部分と同様、JavaTypeがダウンほとんど常にパラメータオブジェクトの種類に応じて決まります。今回は、明示的にプロセッサの正しいタイプ(TypeHandler)が使用されていることを確認するためにのJavaTypeを指定する必要があります。
列がnull値を許容し、パラメータがnull値を渡すとJDBCは、JDBCタイプを指定する必要があり、プロンプトが必要です。PreparedStatement.setNull()詳細については、Javadocドキュメントを読んでください。
さらなる処理の種類をカスタマイズするには、プロセッサベースの(または別名)、などの特定のタイプを指定することができます。
#{age,javaType=int,jdbcType=NUMERIC,typeHandler=MyTypeHandler}
それは複雑に見えますが、構成はより多くなるが、実際には、めったにこのような複雑な設定を必要としません。
数値型のために、ビット数を指定するために小数点以下予約桁が提供されます。
#{height,javaType=double,jdbcType=NUMERIC,numericScale=2}
最後に、モード属性を使用すると、IN、OUT、またはINOUTパラメーターを指定することができます。モードパラメータがOUTまたはINOUTである場合、あなたは、プロパティのパラメータオブジェクトの実際の値として出力パラメータ必要な動作を指定するとき、それは変更されますが好きです。モードがOUT(またはINOUT)で、かつjdbcTypeのCURSOR(つまり、OracleのREFCURSOR)の場合は、結果にこのresultMap参照がこのresultMapは、パラメータの型にマッピングされた設定を指定する必要があります。ここに注意を払うためにJavaTypeがプロパティはオプションで、左の空白jdbcTypeがCURSORである場合には、自動的にこのresultMapに設定されます。
#{department, mode=OUT, jdbcType=CURSOR, javaType=ResultSet, resultMap=departmentResultMap}
MyBatisのも、このような構造(構造体)などのより高度なデータ型をサポートしていますが、outパラメータを使用している場合は、明示的に名前のタイプを設定する必要があります。例えば(再び、実際に変更するには、このような何かをしません)。
#{middleInitial, mode=OUT, jdbcType=STRUCT, jdbcTypeName=MY_TYPE, resultMap=departmentResultMap}
これらのオプションのすべては非常に強力ですが、ほとんどの時間は、あなたは、単にプロパティ名を指定している間、jdbcTypeとして指定するために、最大で、推測するための独自のMyBatisの他のものは、空の列かもしれません。
-
#{ファーストネーム}
-
#{middleInitial、jdbcType = VARCHAR}
-
#{苗字}