mybatis tutorial dynamic sql statement _ Power node Java College collation
- 2020-10-31 21:46:14
- OfStack
Sometimes, sql statement in where condition, some security judgment is required, for example, if the parameter passed in according to a certain condition is empty, the result of the query is likely to be empty, maybe we need to find out all the information when the parameter is empty. Id is generated using Oracle's sequences and mysql's functions. In this case, we can use dynamic sql.
The following paragraphs use the mysql syntax and functions (such as the string linking function CONCAT).
selectKey label
In insert statements, sequences are often used in Oracle, functions are used in MySQL to automatically generate the primary key inserted into the table, and methods are required to return this generated primary key. This can be achieved using the selectKey tag of myBatis.
The following example USES the mysql database custom function nextval('student') to generate an key and set it to the studentId attribute in the incoming entity class. So after executing this method, the edge can get the generated key through the entity class.
<!-- Insert the students Automatic primary key -->
<insert id="createStudentAutoKey" parameterType="bjpowernodestudentmanagerdatamodelStudentEntity" keyProperty="studentId">
<selectKey keyProperty="studentId" resultType="String" order="BEFORE">
select nextval('student')
</selectKey>
INSERT INTO STUDENT_TBL(STUDENT_ID,
STUDENT_NAME,
STUDENT_SEX,
STUDENT_BIRTHDAY,
STUDENT_PHOTO,
CLASS_ID,
PLACE_ID)
VALUES (#{studentId},
#{studentName},
#{studentSex},
#{studentBirthday},
#{studentPhoto, javaType=byte[], jdbcType=BLOB, typeHandler=orgapacheibatistypeBlobTypeHandler},
#{classId},
#{placeId})
</insert>
Call the interface method, and get the automatic generation of key
StudentEntity entity = new StudentEntity();
entity.setStudentName(" Hello dawn ");
entity.setStudentSex(1);
entity.setStudentBirthday(DateUtil.parse("1985-05-28"));
entity.setClassId("20000001");
entity.setPlaceId("70000001");
this.dynamicSqlMapper.createStudentAutoKey(entity);
System.out.println(" The new students ID: " + entity.getStudentId());
selectKey statement property configuration details:
属性
|
描述
|
取值
|
keyProperty
|
selectKey 语句生成结果需要设置的属性。
|
|
resultType
|
生成结果类型,MyBatis 允许使用基本的数据类型,包括String 、int类型。
|
|
order
|
1:BEFORE,会先选择主键,然后设置keyProperty,再执行insert语句;
2:AFTER,就先运行insert 语句再运行selectKey 语句。
|
BEFORE
AFTER
|
statementType
|
MyBatis 支持STATEMENT,PREPARED和CALLABLE 的语句形式, 对应Statement ,PreparedStatement 和CallableStatement 响应
|
STATEMENT
PREPARED
CALLABLE
|
if label
The if tag can be used in many types of sql statements, such as queries. Let's start with a very common query:
<!-- Query students list . like The name -->
<select id="getStudentListLikeName" parameterType="StudentEntity" resultMap="studentResultMap">
SELECT * from STUDENT_TBL ST
WHERE ST.STUDENT_NAME LIKE CONCAT(CONCAT('%', #{studentName}),'%')
</select>
But at this point if studentName or studentSex for null , the statement is likely to report an error or the query result is empty. At this point we use if dynamic sql Statement to determine if the value is null Or equal to an empty string, we do not make this condition judgment, increase flexibility.
The parameter is an entity class StudentEntity . All attributes in the entity class are judged, and if they are not null, the judgment condition is executed.
<!-- 2 if( To determine parameters ) - Attribute that does not have an entity class as empty where conditions -->
<select id="getStudentList_if" resultMap="resultMap_studentEntity" parameterType="bjpowernode.student.manager.data.model.StudentEntity">
SELECT ST.STUDENT_ID,
ST.STUDENT_NAME,
ST.STUDENT_SEX,
ST.STUDENT_BIRTHDAY,
ST.STUDENT_PHOTO,
ST.CLASS_ID,
ST.PLACE_ID
FROM STUDENT_TBL ST
WHERE
<if test="studentName !=null ">
ST.STUDENT_NAME LIKE CONCAT(CONCAT('%', #{studentName, jdbcType=VARCHAR}),'%')
</if>
<if test="studentSex != null and studentSex != '' ">
AND ST.STUDENT_SEX = #{studentSex, jdbcType=INTEGER}
</if>
<if test="studentBirthday != null ">
AND ST.STUDENT_BIRTHDAY = #{studentBirthday, jdbcType=DATE}
</if>
<if test="classId != null and classId!= '' ">
AND ST.CLASS_ID = #{classId, jdbcType=VARCHAR}
</if>
<if test="classEntity != null and classEntityclassId !=null and classEntityclassId !=' ' ">
AND ST.CLASS_ID = #{classEntity.classId, jdbcType=VARCHAR}
</if>
<if test="placeId != null and placeId != '' ">
AND ST.PLACE_ID = #{placeId, jdbcType=VARCHAR}
</if>
<if test="placeEntity != null and placeEntityplaceId != null and placeEntityplaceId != '' ">
AND ST.PLACE_ID = #{placeEntity.placeId, jdbcType=VARCHAR}
</if>
<if test="studentId != null and studentId != '' ">
AND ST.STUDENT_ID = #{studentId, jdbcType=VARCHAR}
</if>
</select>
new1 such an entity class, we need to limit that condition, only need to attach the corresponding value will be where this condition, on the contrary, no assignment can not be judged in where.
public void select_test_2_1() {
StudentEntity entity = new StudentEntity();
entity.setStudentName("");
entity.setStudentSex(1);
entity.setStudentBirthday(DateUtil.parse("1985-05-28"));
entity.setClassId("20000001");
//entity.setPlaceId("70000001");
List<StudentEntity> list = this.dynamicSqlMapper.getStudentList_if(entity);
for (StudentEntity e : list) {
System.out.println(e.toString());
}
}
if + where condition judgment
This combination can cause errors when there are many if tags used conditionally in where. Let's take the query in 3.1 as an example when the java code is called as follows:
@Test
public void select_test_2_1() {
StudentEntity entity = new StudentEntity();
entity.setStudentName(null);
entity.setStudentSex(1);
List<StudentEntity> list = this.dynamicSqlMapper.getStudentList_if(entity);
for (StudentEntity e : list) {
System.out.println(e.toString());
}
}
If in the above example, the parameter studentName is null, the judgment of STUDENT_NAME column will not be performed, and the "WHERE AND" keyword redundant error SQL will be directed.
In this case, we can use the where dynamic statement to solve. The "where" tag will know that if it contains a tag with a return value, it inserts 1 'where'. In addition, if the tag returns something that starts with AND or OR, it will be removed.
The above example is modified to:
<!-- 3 select - where/if( To determine parameters ) - Attribute that does not have an entity class as empty where conditions -->
<select id="getStudentList_whereIf" resultMap="resultMap_studentEntity" parameterType="bjpowernode.student.manager.data.model.StudentEntity">
SELECT ST.STUDENT_ID,
ST.STUDENT_NAME,
ST.STUDENT_SEX,
ST.STUDENT_BIRTHDAY,
ST.STUDENT_PHOTO,
ST.CLASS_ID,
ST.PLACE_ID
FROM STUDENT_TBL ST
<where>
<if test="studentName !=null ">
ST.STUDENT_NAME LIKE CONCAT(CONCAT('%', #{studentName, jdbcType=VARCHAR}),'%')
</if>
<if test="studentSex != null and studentSex != '' ">
AND ST.STUDENT_SEX = #{studentSex, jdbcType=INTEGER}
</if>
<if test="studentBirthday != null ">
AND ST.STUDENT_BIRTHDAY = #{studentBirthday, jdbcType=DATE}
</if>
<if test="classId != null and classId!= '' ">
AND ST.CLASS_ID = #{classId, jdbcType=VARCHAR}
</if>
<if test="classEntity != null and classEntityclassId !=null and classEntityclassId !=' ' ">
AND ST.CLASS_ID = #{classEntity.classId, jdbcType=VARCHAR}
</if>
<if test="placeId != null and placeId != '' ">
AND ST.PLACE_ID = #{placeId, jdbcType=VARCHAR}
</if>
<if test="placeEntity != null and placeEntityplaceId != null and placeEntityplaceId != '' ">
AND ST.PLACE_ID = #{placeEntity.placeId, jdbcType=VARCHAR}
</if>
<if test="studentId != null and studentId != '' ">
AND ST.STUDENT_ID = #{studentId, jdbcType=VARCHAR}
</if>
</where>
</select>
Update statement for if + set
When the if tag is not used in the update statement, having one argument of null results in an error.
When using the if tag in an update statement, if the preceding if is not executed, this may result in an redundant comma error. Using the set tag, you can dynamically configure the SET keyword and weed out any irrelevant commas appended to the end of the condition.
When the if+set tag is modified, if an item is null, it is not updated, but the original value of the database is kept. Here are some examples:
<!-- 4 if/set( To determine parameters ) - Update an attribute whose entity class is not empty -->
<update id="updateStudent_if_set" parameterType="bjpowernode.student.manager.data.model.StudentEntity">
UPDATE STUDENT_TBL
<set>
<if test="studentName != null and studentName != '' ">
STUDENT_TBL.STUDENT_NAME = #{studentName},
</if>
<if test="studentSex != null and studentSex != '' ">
STUDENT_TBL.STUDENT_SEX = #{studentSex},
</if>
<if test="studentBirthday != null ">
STUDENT_TBL.STUDENT_BIRTHDAY = #{studentBirthday},
</if>
<if test="studentPhoto != null ">
STUDENT_TBL.STUDENT_PHOTO = #{studentPhoto, javaType=byte[], jdbcType=BLOB, typeHandler=org.apache.ibatis.type.BlobTypeHandler},
</if>
<if test="classId != '' ">
STUDENT_TBL.CLASS_ID = #{classId}
</if>
<if test="placeId != '' ">
STUDENT_TBL.PLACE_ID = #{placeId}
</if>
</set>
WHERE STUDENT_TBL.STUDENT_ID = #{studentId};
</update>
if + trim replaces where/set tags
trim is a more flexible way to remove redundant keyword tags, and can practice the effects of where and set.
trim where instead
<!-- 5.1 if/trim Instead of where( To determine parameters ) - Attribute that does not have an entity class as empty where conditions -->
<select id="getStudentList_if_trim" resultMap="resultMap_studentEntity">
SELECT ST.STUDENT_ID,
ST.STUDENT_NAME,
ST.STUDENT_SEX,
ST.STUDENT_BIRTHDAY,
ST.STUDENT_PHOTO,
ST.CLASS_ID,
ST.PLACE_ID
FROM STUDENT_TBL ST
<trim prefix="WHERE" prefixOverrides="AND|OR">
<if test="studentName !=null ">
ST.STUDENT_NAME LIKE CONCAT(CONCAT('%', #{studentName, jdbcType=VARCHAR}),'%')
</if>
<if test="studentSex != null and studentSex != '' ">
AND ST.STUDENT_SEX = #{studentSex, jdbcType=INTEGER}
</if>
<if test="studentBirthday != null ">
AND ST.STUDENT_BIRTHDAY = #{studentBirthday, jdbcType=DATE}
</if>
<if test="classId != null and classId!= '' ">
AND ST.CLASS_ID = #{classId, jdbcType=VARCHAR}
</if>
<if test="classEntity != null and classEntityclassId !=null and classEntityclassId !=' ' ">
AND ST.CLASS_ID = #{classEntity.classId, jdbcType=VARCHAR}
</if>
<if test="placeId != null and placeId != '' ">
AND ST.PLACE_ID = #{placeId, jdbcType=VARCHAR}
</if>
<if test="placeEntity != null and placeEntity.placeId != null and placeEntity.placeId != '' ">
AND ST.PLACE_ID = #{placeEntity.placeId, jdbcType=VARCHAR}
</if>
<if test="studentId != null and studentId != '' ">
AND ST.STUDENT_ID = #{studentId, jdbcType=VARCHAR}
</if>
</trim>
</select>
trim set instead
<!-- 2 if/trim Instead of set( To determine parameters ) - Update an attribute whose entity class is not empty -->
<update id="updateStudent_if_trim" parameterType="bjpowernode.student.manager.data.model.StudentEntity">
UPDATE STUDENT_TBL
<trim prefix="SET" suffixOverrides=",">
<if test="studentName != null and studentName != '' ">
STUDENT_TBL.STUDENT_NAME = #{studentName},
</if>
<if test="studentSex != null and studentSex != '' ">
STUDENT_TBL.STUDENT_SEX = #{studentSex},
</if>
<if test="studentBirthday != null ">
STUDENT_TBL.STUDENT_BIRTHDAY = #{studentBirthday},
</if>
<if test="studentPhoto != null ">
STUDENT_TBL.STUDENT_PHOTO = #{studentPhoto, javaType=byte[], jdbcType=BLOB, typeHandler=org.apache.ibatis.type.BlobTypeHandler},
</if>
<if test="classId != '' ">
STUDENT_TBL.CLASS_ID = #{classId},
</if>
<if test="placeId != '' ">
STUDENT_TBL.PLACE_ID = #{placeId}
</if>
</trim>
WHERE STUDENT_TBLSTUDENT_ID = #{studentId}
</update>
choose (when, otherwise)
Sometimes we don't want to apply all the conditions and just want to choose one from a number of options. With the if tag, the condition in the if tag is executed as long as the expression in test is true. MyBatis provides the choose element. The if tag is associated with (and), while choose is associated with (or).
choose tag judges whether the test condition in its internal when tag is true or not in order. If one of them is true, choose ends. When all conditions of when in choose are not satisfied, sql in otherwise is executed. Similar to Java, choose is switch, when is case, and otherwise is default.
For example, in the following example, all the conditions that can be restricted are also written down. choose selects one when tag test from top to bottom to execute sql of true. To be safe, we use where to wrap choose, placing more keywords than errors.
<!-- 6 choose( To determine parameters ) - List the entity classes in order 1 An attribute that is not null where conditions -->
<select id="getStudentList_choose" resultMap="resultMap_studentEntity" parameterType="bjpowernode.student.manager.data.model.StudentEntity">
SELECT ST.STUDENT_ID,
ST.STUDENT_NAME,
ST.STUDENT_SEX,
ST.STUDENT_BIRTHDAY,
ST.STUDENT_PHOTO,
ST.CLASS_ID,
ST.PLACE_ID
FROM STUDENT_TBL ST
<where>
<choose>
<when test="studentName !=null ">
ST.STUDENT_NAME LIKE CONCAT(CONCAT('%', #{studentName, jdbcType=VARCHAR}),'%')
</when >
<when test="studentSex != null and studentSex != '' ">
AND ST.STUDENT_SEX = #{studentSex, jdbcType=INTEGER}
</when >
<when test="studentBirthday != null ">
AND ST.STUDENT_BIRTHDAY = #{studentBirthday, jdbcType=DATE}
</when >
<when test="classId != null and classId!= '' ">
AND ST.CLASS_ID = #{classId, jdbcType=VARCHAR}
</when >
<when test="classEntity != null and classEntity.classId !=null and classEntity.classId !=' ' ">
AND ST.CLASS_ID = #{classEntity.classId, jdbcType=VARCHAR}
</when >
<when test="placeId != null and placeId != '' ">
AND ST.PLACE_ID = #{placeId, jdbcType=VARCHAR}
</when >
<when test="placeEntity != null and placeEntity.placeId != null and placeEntity.placeId != '' ">
AND ST.PLACE_ID = #{placeEntity.placeId, jdbcType=VARCHAR}
</when >
<when test="studentId != null and studentId != '' ">
AND ST.STUDENT_ID = #{studentId, jdbcType=VARCHAR}
</when >
<otherwise>
</otherwise>
</choose>
</where>
</select>
foreach
For dynamic SQL it is essential to iterate over a set, usually for IN conditions. The List instance will use "list" as the key, and the array instance will use "array" as the key.
The foreach element is very powerful in that it allows you to specify a collection, declare collection items, and index variables that can be used in the body of the element. It also allows you to specify open and closed strings, placing delimiters between iterations. This element is smart, and it doesn't accidentally append redundant delimiters.
Note: You can pass an instance of List or an array as an argument object to MyBatis. When you do this, MyBatis will automatically wrap it in 1 Map with the name as the key. An instance of List will have "list" as the key, and an array instance will have "array" as the key.
This section discusses the XML configuration file and the XML mapping file. The next section discusses Java API in detail, so you can get the most efficient mapping you've ever created.
The parameter is array example
Interface method declaration:
public List<StudentEntity> getStudentListByClassIds_foreach_array(String[] classIds);
Dynamic SQL statement:
StudentEntity entity = new StudentEntity();
entity.setStudentName(" Hello dawn ");
entity.setStudentSex(1);
entity.setStudentBirthday(DateUtil.parse("1985-05-28"));
entity.setClassId("20000001");
entity.setPlaceId("70000001");
this.dynamicSqlMapper.createStudentAutoKey(entity);
System.out.println(" The new students ID: " + entity.getStudentId());
0
Test the code and query the students in the two classes of 20000001 and 20000002:
StudentEntity entity = new StudentEntity();
entity.setStudentName(" Hello dawn ");
entity.setStudentSex(1);
entity.setStudentBirthday(DateUtil.parse("1985-05-28"));
entity.setClassId("20000001");
entity.setPlaceId("70000001");
this.dynamicSqlMapper.createStudentAutoKey(entity);
System.out.println(" The new students ID: " + entity.getStudentId());
1
The parameter is list example
Interface method declaration:
public List<StudentEntity> getStudentListByClassIds_foreach_list(List<String> classIdList);
Dynamic SQL statement:
StudentEntity entity = new StudentEntity();
entity.setStudentName(" Hello dawn ");
entity.setStudentSex(1);
entity.setStudentBirthday(DateUtil.parse("1985-05-28"));
entity.setClassId("20000001");
entity.setPlaceId("70000001");
this.dynamicSqlMapper.createStudentAutoKey(entity);
System.out.println(" The new students ID: " + entity.getStudentId());
2
Test the code and query the students in the two classes of 20000001 and 20000002:
@Test
public void test7_2_foreach() {
ArrayList<String> classIdList = new ArrayList<String>();
classIdList.add("20000001");
classIdList.add("20000002");
List<StudentEntity> list = this.dynamicSqlMapper.getStudentListByClassIds_foreach_list(classIdList);
for (StudentEntity e : list) {
System.out.println(e.toString());
}
}