Marco Mybatis -----> (6) Conocimiento profundo de las sentencias SQL dinámicas de Mybatis

Una declaración SQL dinámica

  • ¿Qué es una declaración SQL dinámica?

Juzga las condiciones a través de las etiquetas <if>, <donde>, <foreach> proporcionadas por mybatis para realizar el empalme dinámico de sentencias SQL. Se utiliza principalmente para resolver la situación de condiciones de consulta inciertas. Consultará según las condiciones de consulta enviadas por el usuario. La razón principal es que la parte posterior de la declaración SQL donde la palabra clave ha cambiado.

  • Precauciones:

Si símbolos como mayor que (>), menor que (<), mayor o igual que (> =), menor o igual que (<=) aparecen en el SQL dinámico en el archivo de mapeo, es mejor convertir ellos a los símbolos de entidad. De lo contrario, XML puede tener errores de análisis.
Enfoque :Especialmente para el signo menor que (<), no debe aparecer en el archivo XML. De lo contrario, se producirán errores al analizar el archivo de asignación

  • Tabla de símbolos de entidad:
< Menos que & lt ;
> mas que el & gt ;
> = mayor o igual a & gt ; =
<= Menos que o igual a & lt ; =
  • A continuación se describen estos tipos de etiquetas:

(1) etiqueta <if>

Formato de sintaxis:
<if test="判断java对象的属性值">
    部分sql语句
</if>
  • Definir métodos en la interfaz.
List<Student> selectStudentIf(Student student);
  • Archivo de mapeo
<select id="selectStudentIf" resultType="Student">
    <include refid="studentSql"/>
    where 
    <if test="name!=null and name!=''">
        name=#{name}
    </if>
    <if test="age>0">
        or age>#{age}
    </if>
</select>

Los fragmentos de código de la declaración SQL se definen aquí para facilitar futuras llamadas y evitar la redundancia de código

Siga los pasos:
1. Primero defina <sql id = "custom name unique"> declaración sql, nombre de tabla, campo, etc. </ sql>
2. Úselo de nuevo, <include refid = "value of id" />

<sql id="studentSql" >
    select id,name,age,email from student
</sql>
  • Definir el método de prueba
@Test
public void testSelectStudenIf(){
    
    
    SqlSession sqlSession = MyBatisUtil.getSqlSession();
    StudentDao dao = sqlSession.getMapper(StudentDao.class);
    Student student = new Student();
    student.setName("李四");
    student.setAge(20);
    List<Student> studentList = dao.selectStudentIf(student);

    for (Student student1:studentList){
    
    
        System.out.println("学生if="+student1);
    }
}

Por ejemplo, comente el nombre del código en el método de prueba :

Student student = new Student();
//student.setName("李四");
student.setAge(20);
List<Student> studentList = dao.selectStudentIf(student);

Entonces la declaración SQL ejecutada será incorrecta:

SQL:select id,name,age,email from student where or age>?

Defecto :
cuando la siguiente instrucción if no se satisface o no se satisface, la instrucción SQL se empalmará en
select id,name,age,email from student where or age>?
select id,name,age,email from student where
esta instrucción SQL, lo cual obviamente es incorrecto

Sugerencia :
puede agregar una condición satisfactoria (cláusula verdadera) después de donde , por ejemplo: donde id> 0
para que la declaración SQL se convierta en una declaración ejecutable.
select id,name,age,email from student where id>0 or age>?
Pero cuando la cantidad de datos es grande, afectará seriamente la eficiencia de la consulta.

El archivo de mapeo mejorado es:

<select id="selectStudentIf" resultType="Student">
    <include refid="studentSql"/>
    where id>0
    <if test="name!=null and name!=''">
       and  name=#{name}
    </if>
    <if test="age>0">
        or age>#{age}
    </if>
</select>

Dentro de la palabra clave where se agrega un id de cláusula verdadero> 0 y se agrega antes del nombre "y"
para que la ejecución de la declaración SQL sea:
SQL:select id,name,age,email from student where id>0 or age>?

(2) etiqueta <donde>

Formato de sintaxis:
<where> 
	其他动态 sql 
</where>
<donde>: resuelve los pequeños defectos causados ​​por la etiqueta <if>

<donde> se usa para contener varios <if>
1. Cuando se establecen varios if, se agrega automáticamente una palabra clave WHERE a <donde>
2. Cuando no se establecen las siguientes condiciones, puede eliminar el redundante y en si, O etc.
3. Cuando no se cumplen las siguientes condiciones, la palabra clave WHERE también se eliminará

  • Definir métodos en la interfaz.
List<Student> selectStudentWhere(Student student);
  • Archivo de mapeo
<select id="selectStudentWhere" resultType="Student">
    <include refid="studentSql"></include>
    <where>
        <if test="name!=null and name!=''">
            name=#{name}
        </if>
        <if test="age>0">
            or age>#{age}
        </if>
    </where>
</select>
  • Definir el método de prueba
@Test
public void testSelectStudenWhere(){
    
    
    SqlSession sqlSession = MyBatisUtil.getSqlSession();
    StudentDao dao = sqlSession.getMapper(StudentDao.class);

    Student student = new Student();
    //student.setName("李四");
    student.setAge(20);
    List<Student> studentList = dao.selectStudentWhere(student);

    for (Student student1:studentList){
    
    
        System.out.println("学生where="+student1);
    }
}

(3) etiqueta <foreach>

Formato de sintaxis:
<foreach collection="" open="" close="" item="" separator=""> 
	#{item 的值} 
</foreach> 

La etiqueta <foreach> se usa para realizar el recorrido de matrices y colecciones, que se usa principalmente en la declaración in de la declaración sql

1. Empalmar declaraciones SQL sin etiquetas aquí

Por ejemplo: la identificación del estudiante de la consulta es 1001,1002,1003

select * from student where id in (1001,1002,1003)

Aquí define un método de prueba para empalmar la declaración SQL anterior

@Test
public void testfor(){
    
    
    List<Integer> list=new ArrayList<>();
    list.add(1001);
    list.add(1002);
    list.add(1003);
    //String sql = "select * from student where id in(1001,1002,1003);
    String sql ="select * from student where id in";
    StringBuilder builder = new StringBuilder(sql);
    int init=0;
    int len=list.size();
    //添加开始的(
    builder.append("(");
    for (Integer i:list){
    
    
        builder.append(i).append(",");
    }
    //将最后一个逗号删除
    builder.deleteCharAt(builder.length()-1);
    //循环结束
    builder.append(")");
    sql = builder.toString();
    System.out.println("sql=="+sql);
}

Obviamente, el código anterior es muy largo y huele mal , hagamos mejoras ...

2. Empalmar declaraciones SQL a través de la etiqueta <foreach>

Uso 1: Lista poligonal <tipo simple>

  • Definir métodos en la interfaz.
List<Student> selectStudentForeachOne(List<Integer> list);
  • Archivo de mapeo
<select id="selectStudentForeachOne" resultType="Student">
    <include refid="studentSql"/> where id in
    <foreach collection="list" item="myid" open="(" close=")" separator=",">
        #{myid}
    </foreach>
</select>

Analice los atributos en la etiqueta :
1. colección: indica el tipo de parámetros del método en la interfaz,
si es una matriz, use matriz, si es una colección de lista, use lista
2. elemento: una variable personalizada que representa una matriz y miembros de la colección, equivalente a Integer La variable i en i
para (Integer i: list) { builder.append (i) .append (",");}3. open: el carácter al principio del ciclo "("4 .cerrar: el carácter al final del ciclo ")"5. Separador: Separador entre miembros del conjunto ","




  • Definir el método de prueba
@Test
public void testSelectStudenForeachOne(){
    
    
    SqlSession sqlSession = MyBatisUtil.getSqlSession();
    StudentDao dao = sqlSession.getMapper(StudentDao.class);
    List<Integer> list=new ArrayList<>();
    list.add(1001);
    list.add(1002);
    list.add(1003);
    List<Student> studentList = dao.selectStudentForeachOne(list);
    for (Student student1:studentList){
    
    
        System.out.println("学生foreachone="+student1);
    }
}

Uso 2: Lista poligonal <tipo de objeto>

  • Definir métodos en la interfaz.
List<Student> selectStudentForeachTwo(List<Student> studentlist);
  • Archivo de mapeo
<select id="selectStudentForeachTwo" resultType="Student">
    <include refid="studentSql"/> where id in (
    <foreach collection="list" item="stu" separator=",">
        #{stu.id}
    </foreach>
    )
</select>

Nota : El valor stu del elemento aquí es solo el objeto Java correspondiente

  • Definir el método de prueba
@Test
public void testSelectStudenForeachTwo(){
    
    
    SqlSession sqlSession = MyBatisUtil.getSqlSession();
    StudentDao dao = sqlSession.getMapper(StudentDao.class);

    List<Student> stulist=new ArrayList<>();
    Student s1 = new Student();
    s1.setId(1001);
    stulist.add(s1);

    Student s2 = new Student();
    s2.setId(1002);
    stulist.add(s2);

    List<Student> studentList = dao.selectStudentForeachTwo(stulist);

    for (Student student1:studentList){
    
    
        System.out.println("学生foreachtwo="+student1);
    }
}

2. Esquema de pensamiento

Inserte la descripción de la imagen aquí

¡Por favor corríjame si hay alguna deficiencia!

Supongo que te gusta

Origin blog.csdn.net/hcz666/article/details/113132501
Recomendado
Clasificación