Eighty-three, MyBatis framework dynamic SQL

Article directory

MyBatis framework dynamic SQL

Environmental preparation

Dynamic SQL if

Where is the dynamic SQL

foreach of dynamic SQL

Code snippet for dynamic SQL


 

MyBatis framework dynamic SQL

Dynamic SQL, through the various labels provided by MyBatis to judge the conditions to achieve dynamic splicing of SQL statements. The expression used in the conditional judgment here is the OGNL expression. Commonly used dynamic SQL tags are <if>, <where>, <choose/>, <foreach>, etc.

The dynamic SQL statement of MyBatis is very similar to the statement in JSTL.

Dynamic SQL is mainly used to solve the problem of uncertain query conditions: during the running of the program, the query is performed according to the query conditions submitted by the user. The submitted query conditions are different, and the executed SQL statements are different. If each possible situation is listed one by one, and all the conditions are arranged and combined, there will be a large number of SQL statements. At this point, dynamic SQL can be used to solve such a problem.

Environmental preparation

1. Create a new maven project, add mybatis, mysql driver dependencies

2. Create entity class Student, StudentDao interface, StudentDao.xml, mybatis.xml, test class

3. Use the previous table student.

In the dynamic SQL of mapper, if there are symbols such as greater than (>), less than (=), less than or equal (<=), it is better to convert them into entity symbols. Otherwise, the XML may experience parsing errors.

In particular, the less-than sign (<) must never appear in XML. Otherwise there will be an error parsing the mapper file.

Entity symbol table:

< less than <
> more than the >
>= greater or equal to >=
<= less than or equal to <=

Dynamic SQL if

For the execution of this label, when the value of test is true, the SQL fragments it contains will be spliced ​​into the SQL statement where it is located.

Syntax: <if test="condition"> part of sql statement</if>

Interface method:

List<Student> selectStudentIf(Student student);

mapper file:

<select id="selectStudentIf" resultType="com.bjpowernode.domain.Student">
 select id,name,email,age from student
 where 1=1
 <if test="name != null and name !='' ">
 and name = #{name}
 </if>
 <if test="age > 0 ">
 and age &gt; #{age}
 </if>
</select>

testing method:

@Test
public void testSelect() throws IOException {
 Student param = new Student();
 param.setName("李力");
 param.setAge(18);
 List<Student> studentList = studentDao.selectStudentIf(param);
 studentList.forEach( stu -> System.out.println(stu));
}

Where is the dynamic SQL

There is a troublesome place in the <if/> tag: you need to manually add a 1=1 clause after the where. Because, if all the <if/> conditions after where are false, and if there is no 1=1 clause after where, then there will be only one empty where left in SQL, and SQL will make an error.

So, after the where, you need to add the always true clause 1=1 to prevent this from happening. But when the amount of data is large, it will seriously affect the query efficiency.

Using the <where/> tag, when there is a query condition, the where clause can be added automatically; when there is no query condition, the where clause will not be added. It should be noted that the SQL fragment in the first <if/> tag may not contain and.

However, it is also good to write and, the system will remove the extra and. But the and of other SQL fragments in <if/> must be written. Otherwise, the SQL statement will be concatenated incorrectly.

Syntax: <where> other dynamic sql</where>

Interface method:

List<Student> selectStudentWhere(Student student);

mapper file:

<select id="selectStudentWhere" 
resultType="com.bjpowernode.domain.Student">
 select id,name,email,age from student
 <where>
 <if test="name != null and name !='' ">
 and name = #{name}
 </if>
 <if test="age > 0 ">
 and age &gt; #{age}
 </if>
 </where>
</select>

testing method:

@Test
public void testSelectWhere() throws IOException {
 Student param = new Student();
 param.setName("李力");
 param.setAge(18);
 List<Student> studentList = studentDao.selectStudentWhere(param);
 studentList.forEach( stu -> System.out.println(stu));
}

foreach of dynamic SQL

The <foreach/> tag is used to traverse arrays and collections. When using it, you need to pay attention to:

  • collection represents the type of collection to traverse, list , array, etc.
  • open, close, and separator are SQL splicing of the traversed content.

grammar:

<foreach collection="集合类型" open="开始的字符" close="结束的字符" 
 item="集合中的成员" separator="集合成员之间的分隔符">
 #{item 的值}
</foreach>

1. Traverse List<simple type>

The List in the expression is represented by list, and its size is represented by list.size.

Requirement: query student id is 1002,1005,1006

Interface method:

List<Student> selectStudentForList(List<Integer> idList);

mapper file:

<select id="selectStudentForList" 
resultType="com.bjpowernode.domain.Student">
 select id,name,email,age from student
 <if test="list !=null and list.size > 0 ">
 where id in
 <foreach collection="list" open="(" close=")" 
 item="stuid" separator=",">
 #{stuid}
 </foreach>
 </if>
</select>

testing method:

@Test
public void testSelectForList() {
 List<Integer> list = new ArrayList<>();
 list.add(1002);
 list.add(1005);
 list.add(1006);
 List<Student> studentList = studentDao.selectStudentForList(list);
 studentList.forEach( stu -> System.out.println(stu));
}

2. Traverse List<object type>

Interface method:

List<Student> selectStudentForList2(List<Student> stuList);

mapper file:

<select id="selectStudentForList2" 
resultType="com.bjpowernode.domain.Student">
 select id,name,email,age from student
 <if test="list !=null and list.size > 0 ">
 where id in
 <foreach collection="list" open="(" close=")"
 item="stuobject" separator=",">
 #{stuobject.id}
 </foreach>
 </if>
</select>

testing method:

@Test
public void testSelectForList2() {
 List<Student> list = new ArrayList<>();
 Student s1 = new Student();
 s1.setId(1002);
 list.add(s1);
 s1 = new Student();
 s1.setId(1005);
 list.add(s1);
 List<Student> studentList = studentDao.selectStudentForList2(list);
 studentList.forEach( stu -> System.out.println(stu));
}

Code snippet for dynamic SQL

The <sql/> tag is used to define SQL fragments for reuse by other SQL tags. For other tags to use this SQL fragment, the <include/> subtag is required. The <sql/> tag can define any part of the SQL statement, so the <include/> subtag can be placed anywhere in the dynamic SQL.

Interface method:

List<Student> selectStudentSqlFragment(List<Student> stuList);

mapper file:

<!--创建 sql 片段 id:片段的自定义名称--> 
<sql id="studentSql">
 select id,name,email,age from student
</sql>
<select id="selectStudentSqlFragment" 
resultType="com.bjpowernode.domain.Student">
 <!-- 引用 sql 片段 --> 
 <include refid="studentSql"/>
 <if test="list !=null and list.size > 0 ">
 where id in
 <foreach collection="list" open="(" close=")" 
 item="stuobject" separator=",">
 #{stuobject.id}
 </foreach>
 </if>
</select>

testing method:

@Test
public void testSelectSqlFragment() {
 List<Student> list = new ArrayList<>();
 Student s1 = new Student();
 s1.setId(1002);
 list.add(s1);
 s1 = new Student();
 s1.setId(1005);
 list.add(s1);
 List<Student> studentList = studentDao.selectStudentSqlFragment(list);
 studentList.forEach( stu -> System.out.println(stu));
}


 

Guess you like

Origin blog.csdn.net/m0_54925305/article/details/123607625