PrefacePreviously, MySQL was queried through static SQL, but if the business is complicated, we will encounter quotation mark problems, or an extra space, which will make the SQL code wrong. So in order to solve this problem, we have dynamic SQL. The dynamic SQL technology of the Mybatis framework is a function that dynamically assembles SQL statements according to specific conditions. Its purpose is to solve the pain point problem when splicing SQL statement strings. This is done through tags. Dynamic SQL 1. Take a look at the module directory structure firstCreate a sql.xml file in the mapper package under resources in the class path (commonality extraction) 2. Physical modeling and logical modelingThe physical modeling step is omitted here, and the database table is required to correspond to the pojo class. package pojo; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @Data @AllArgsConstructor @NoArgsConstructor public class Employee { private Integer empId; private String empName; private Double empSalary; } 3. Introducing dependenciesCopy the previous log4j to the classpath resouces. In addition, the pom.xml file after we introduce the dependency is as follows: <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.example</groupId> <artifactId>day03-mybatis02-dynamic</artifactId> <version>1.0-SNAPSHOT</version> <packaging>jar</packaging> <dependencies> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.8</version> <scope>provided</scope> </dependency> <!-- Mybatis core --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.7</version> </dependency> <!-- junit test --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> <!-- MySQL Driver --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.3</version> <scope>runtime</scope> </dependency> <!-- log4j log --> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency> </dependencies> </project> 4. Global Configuration File<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <!--CamelCase Mapping--> <settings> <setting name="mapUnderscoreToCamelCase" value="true"/> </settings> <!--Type alias mapping--> <typeAliases> <package name="pojo"/> </typeAliases> <!--Environment Configuration--> <environments default="dev"> <environment id="dev"> <transactionManager type="JDBC"></transactionManager> <dataSource type="POOLED"> <property name="username" value="root"/> <property name="password" value="888888"/> <property name="url" value="jdbc:mysql://localhost:3306/mybatis-example"/> <property name="driver" value="com.mysql.jdbc.Driver"/> </dataSource> </environment> </environments> <!--Path Mapping--> <mappers> <mapper resource="mapper/sql.xml"/> <package name="mapper"/> </mappers> </configuration> Note: There are camelCase mappings, alias mappings, path mappings and path mappings. What is different from the previous one is that we have done commonality extraction of SQL statements here, so we have to add a SQL path mapping 5. SQL common extraction files Create a sql.xml in the package mapper under the class path resources (because our sql is to be written in the mapping file, and it is also a mapping file, so it needs to be written under mapper). When you need to use it, add <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="mapper.sql"> <sql id="mySelectSql"> select emp_id,emp_name,emp_salary from t_emp </sql> </mapper> The common extraction file can also be left unconfigured. In this case, you can simply rewrite the statements to be executed in the mapping file. 6. Mapper interfaceThere are seven methods in total package mapper; import org.apache.ibatis.annotations.Param; import pojo.Employee; import java.util.List; public interface EmployeeMapper { //Query all employees whose empId is greater than the employee's empId. If empId is null, query all employees List<Employee> selectEmployeeListByEmpId(Integer empId); /** * Query the set of employees whose empId is greater than the passed in empId and whose salary is greater than the passed in empSalary. If the passed in empId is null, the empId condition is not considered. If the passed in empSalary is null, the empSalary condition is not considered. */ List<Employee> selectEmployeeListByEmpIdAndEmpSalary(@Param("empId") Integer empId, @Param("empSalary") Double empSalary); /** * Update employee information based on empId. If a value is null, this field will not be updated. */ void updateEmployee(Employee employee); /** * Query employee information based on emp_id. If 0<emp_id<6, query all employees with an emp_id greater than 6. If emp_id is greater than 6, query all employees with an emp_id less than 6. * If it is any other case, query all employee information. */ List<Employee> selectEmployeeList(Integer empId); /** * Add employee information */ void insertEmployee(Employee employee); /** * Add employee collection in batches */ void insertEmployeeList(@Param("employeeList") List<Employee> employeeList); /** * Query the employee set based on the employee ID set*/ List<Employee> selectEmployeeListByEmpIdList(List<Integer> idList); } ifObjective: Query all employees whose empId is greater than the employee's empId. If empId is null, query all employees. The methods of Dao interface are: Static sql:<select id="selectEmployeeListByEmpId" resultType="Employee"> <include refid="mapper.sql.mySelectSql"></include> where emp_id>#{empId} </select> Dynamic SQL:<select id="selectEmployeeListByEmpId" resultType="Employee"> <include refid="mapper.sql.mySelectSql"></include> <if test="empId != null"> where emp_id>#{empId} </if> </select> whereTarget:
Dao interface method: Dynamic SQL using if tag:<select id="selectEmployeeListByEmpIdAndEmpSalary" resultType="Employee"> <include refid="mapper.sql.mySelectSql"></include> where <if test="empId != null"> emp_id>#{empId} </if> <if test="empSalary != null"> and emp_salary>#{empSalary} </if> Here we can see that if empSalary is empty, the SQL statement is select * from t_emp where emp_id >#{empId}, but if empId is empty, the SQL statement is select * from t_emp where and emp_salary>#{empSalary}. Obviously this is wrong, and the if tag is not applicable here. So we use the where tag, or the trim tag. Dynamic SQL for where and if:<select id="selectEmployeeListByEmpIdAndEmpSalary" resultType="Employee"> <include refid="mapper.sql.mySelectSql"></include> <where> <if test="empId != null"> emp_id>#{empId} </if> <if test="empSalary != null"> and emp_salary>#{empSalary} </if> </where> </select> The role of the where tag:
trim Trim means to build, which actually means to remove the head and tail. Here we still follow the method above. Dynamic SQL of trim<select id="selectEmployeeListByEmpIdAndEmpSalary" resultType="Employee"> <include refid="mapper.sql.mySelectSql"></include> <trim prefix="WHERE" prefixOverrides="AND|OR"> <if test="empId != null"> emp_id>#{empId} </if> <if test="empSalary != null"> AND emp_salary>#{empSalary} </if> </trim> </select> trim tag:
setObjective: Update employee information based on empId. If a value is null, do not update this field. Dao interface method: Dynamic SQL for trim:<update id="updateEmployee" > <trim prefix="set" prefixOverrides=","> <if test="empName!=null"> emp_name=#{empName} </if> <if test="empSalary!=null"> , emp_salary=#{empSalary} </if> </trim> where emp_id=#{empId} </update> Dynamic SQL of set<update id="updateEmployee" > update t_emp <set> <if test="empName!=null"> emp_name=#{empName} </if> <if test="empSalary!=null"> , emp_salary=#{empSalary} </if> </set> It can be seen The function of the set tag:
choose, when, otherwiseTarget:
Dao interface method: Dynamic SQL<select id="selectEmployeeList" resultType="employee"> <include refid="mapper.sql.mySelectSql"></include> where <choose> <!--< is the escape character for < --> <when test="empId>0 and empId<6"> emp_id>#{empId} </when> <when test="empId>6"> emp_id<#{empId} </when> <otherwise> 1==1 </otherwise> </choose> </select> choose, when, otherwise
foreachGoal 1: Add employee information in batches Dao interface method: 1. Dynamic SQL<insert id="insertEmployeeList"> insert into t_emp(emp_name,emp_salary)values <!--The collection tag can be written as list, collection, Or define the parameter name yourself @Param("employeeList") List<Employee> employeeList--> <foreach collection="employeeList" separator="," item="emp"> (#{emp.empName},#{emp.empSalary}) </foreach> </insert> Objective 2: Query multiple employee information based on multiple IDs Dao Interface 2. Dynamic SQL<select id="selectEmployeeListByEmpIdList" resultType="employee"> <include refid="mapper.sql.mySelectSql"></include> <foreach collection="collection" item="id" separator="," open="where emp_id in (" close=")"> #{id} </foreach> </select> Batch query: foreach tag
Testing Procedureimport mapper.EmployeeMapper; import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; import org.junit.After; import org.junit.Before; import pojo.Employee; import java.io.InputStream; import java.util.ArrayList; import java.util.List; public class Test { private EmployeeMapper employeeMapper; private InputStream is; private SqlSession sqlSession; @Before public void init() throws Exception{ //Goal: Get the proxy object of the EmployeeMapper interface, use it to call the selectEmployee(1) method, and then return the Employee object //1. Convert the global configuration file into a byte input stream is = Resources.getResourceAsStream("mybatisConfig.xml"); //2. Create a SqlSessionFactoryBuilder object SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder(); //3. Use the builder pattern to create a SqlSessionFactory object SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(is); //4. Use factory mode to create a SqlSession object sqlSession = sqlSessionFactory.openSession(); //5. Use dynamic proxy mode to create a proxy object of EmployeeMapper interface employeeMapper = sqlSession.getMapper(EmployeeMapper.class); } @After public void after() throws Exception{ //Commit the transaction!!! sqlSession.commit(); //7. Close resources is.close(); sqlSession.close(); } @org.junit.Test public void testSelectEmployeeListByEmpId(){ System.out.println(employeeMapper.selectEmployeeListByEmpId(null)); } @org.junit.Test public void testSelectEmployeeListByEmpIdAndEmpSalary(){ System.out.println(employeeMapper.selectEmployeeListByEmpIdAndEmpSalary(2, 300d)); } @org.junit.Test public void testUpdateEmployee(){ Employee employee = new Employee(3,"celia", 9000d); employeeMapper.updateEmployee(employee); } @org.junit.Test public void testSelectEmployeeList(){ System.out.println(employeeMapper.selectEmployeeList(7)); } @org.junit.Test public void testInsertEmployee(){ employeeMapper.insertEmployee(new Employee(null,"tom",300d)); } @org.junit.Test public void testInsertEmployeeList(){ List<Employee> employeeList = new ArrayList<>(); for (int i = 11; i <= 20; i++) { employeeList.add(new Employee(null,"aobama"+i,2000d)); } employeeMapper.insertEmployeeList(employeeList); } @org.junit.Test public void testSelectEmployeeListByEmpIdList(){ List<Integer> idList = new ArrayList<>(); idList.add(23); idList.add(33); idList.add(32); idList.add(21); idList.add(22); System.out.println(employeeMapper.selectEmployeeListByEmpIdList(idList)); } } This is the end of this article about MyBatis dynamic SQL. For more related MyBatis dynamic SQL content, please search for previous articles on 123WORDPRESS.COM or continue to browse the following related articles. I hope everyone will support 123WORDPRESS.COM in the future! You may also be interested in:
|
<<: Function overloading in TypeScript
>>: How to use the jquery editor plugin tinyMCE
Rem layout adaptation The styles in Vant use px a...
Table of contents Preface Static scope vs. dynami...
First delete mysql: sudo apt-get remove mysql-* T...
This article shares the specific code of JS to ac...
What does linux cd mean? In Linux, cd means chang...
Carousel animation can improve the appearance and...
Table of contents Portainer manages multiple Dock...
This article shares with you the specific method ...
Character set error always exists locale: Cannot ...
Maybe everyone knows that js execution will block...
1. The first method is to use the unhup command d...
Page Description: Main page: name —> shisheng...
Download image docker pull openjdk Creating a Dat...
describe Returns the time interval between two da...
1. Multiple calls to single arrow Once a single a...