Interpretación Detallada del Framework de Capas de Persistencia de MyBatis: Entrenamiento Práctico para Agregar, Eliminar, Modificar y Verificar Archivos de Configuración

1. Introducción

Anteriormente, aprendimos el método de desarrollo nativo del marco de capa de persistencia MyBatis y el método de desarrollo del agente Mapper, que resolvió los problemas de codificación dura y operaciones engorrosas cuando se usa el código básico JDBC para operar la base de datos. Ahora que la retroalimentación que trae el artículo no es mala, usemos el contenido aprendido anteriormente para hacer un entrenamiento de caso práctico hoy.

Mirando hacia atrás, ¿por qué usamos MyBatis para desarrollar? No es difícil entender que MyBatis, como un excelente marco de capa de persistencia, admite sql personalizado, procedimientos almacenados y mapeo avanzado, eliminando casi todos los códigos JBDC y el trabajo de establecer parámetros y obtener conjuntos de resultados. Resuelve el problema de la codificación rígida y la operación engorrosa del código Java cuando se usa el código básico JBDC para operar la base de datos, como se muestra en la figura:

El objetivo formativo del caso en este apartado: poder utilizar el archivo de configuración para realizar la operación de añadir, borrar, modificar y comprobar.

2. Preparativos

Hoy en día utilizamos MyBatis para completar la adición, eliminación, modificación y consulta de datos en la base de datos, la implementación específica es la siguiente:

  • Consulta de datos
    • consultar todos los datos
    • Detalles de los datos de la consulta
    • consulta condicional
  • agregando datos
  • cambiar los datos
    • Modificar todos los campos
    • Modificar campos dinámicos
  • borrar datos
    • Eliminación de datos individuales
    • Eliminación masiva de datos

Al caso de hoy se le entrega una tabla de datos del estudiante, incluyendo id del estudiante, nombre, género, calificaciones y otra información de campo, a través de MyBatis para agregar, borrar, modificar y consultar los datos en la base de datos. Debido a la extensión del artículo, esta serie de artículos se divide en dos artículos. El primer artículo explica la operación de consulta y el último artículo trata sobre adiciones, eliminaciones y cambios. Si está interesado en esta parte del contenido, por favor pasar al siguiente artículo.

En primer lugar, necesitamos crear una tabla de base de datos y agregar datos.Las declaraciones SQL involucradas son las siguientes:

drop table if exists student;

create table student(
	id int primary key auto_increment,
	name varchar(10),
	gender char(1),
	score_english int,
	score_math int
);

insert into student(name,gender,score_english,score_math) values
('张三','男',61,65),
('李四','女',45,38),
('王五','男',85,53),
('小王','男',56,58),
('小樊','女',85,92);

La tabla de datos es la siguiente:

imagen-20230129193400530

A continuación, cree la clase de entidad Student en el org.chengzi.pojopaquete :

public class Student{
    
    
    //id 主键
    private int id;
    //学生姓名
    private String name;
    //学生性别
    private String gender;
    //学生英语成绩
    private int scoreEnglish;
    //学生数学成绩
    private int scoreMath;
    
    //这里省略了Getter and Setter方法和重写的Object中的toString方法
}

A continuación, escriba el caso de prueba, escriba el código de prueba de la unidad en Prueba aquí y cree la clase MyBatisTest en el directorio de archivos Java del código de prueba. Como se muestra en la imagen:

imagen-20230129194459753

Para mejorar la eficiencia de desarrollo de MyBatis, instalamos el complemento MyBatisX , este complemento tiene dos funciones principales, la primera es el salto mutuo entre el archivo de configuración de mapeo XML y la interfaz Mapper, y la segunda es automáticamente generar una declaración de acuerdo con el método de la interfaz Mapper, como se muestra en la figura:

imagen-20230129194834069

Busca el complemento MyBatisX en Archivo/configuración/complementos para descargarlo e instalarlo.

La imagen azul representa el archivo de interfaz de Mapper y el ícono rojo representa el archivo de configuración de mapeo de SQL. Con este complemento, puede definir métodos en la interfaz de Mapper, generar declaraciones automáticamente en el archivo de configuración y saltar rápidamente al Mapper correspondiente. interfaz en el archivo de configuración. Creo que este complemento es muy eficiente en el desarrollo de MyBatis, y lo uso desde que aprendí MyBatis.

3. Consulta todos los datos

En la página del cliente, generalmente necesitamos mostrar toda la información de los datos. En este momento, el código subyacente es usar Java para operar la base de datos, consultar toda la información y enviarla a la página del cliente.

Podemos consultar toda la información a través de los siguientes pasos:

  • Escribir la interfaz de Mapper
    • Parámetros: ninguno
    • resultado:List<Student>
  • Escribir archivo de configuración de mapeo sql
  • Escribir y ejecutar código de prueba

Al analizar los métodos en la interfaz de Mapper, es principalmente para analizar si se requieren parámetros y tipos de valores de retorno de acuerdo con los requisitos de los datos operativos.

3.1 Métodos de interfaz de escritura

Cree una interfaz StudentMapper en el org.chengzi.mapperpaquete y defina un método para consultar todos los datos de los estudiantes en esta interfaz:

public interface StudentMapper {
    
    
    /*
    需求:查询所有学生信息
     */
    List<Student> selectAll();

}

3.2 Escribir sentencia sql

Cree una estructura de directorios en la ruta de recursos org/chengzi/mappery se debe usar el separador de ruta /para asegurarse de que la interfaz del asignador y el archivo de configuración de asignación de sql correspondiente estén en el mismo directorio de archivos. Cree el archivo de configuración StudentMapper.xml en este directorio.

Después de escribir el método correspondiente en la interfaz de StudentMapper, a través del ícono del complemento MyBatisX, podemos saltar rápidamente al archivo de configuración de mapeo sql correspondiente, y la declaración se genera automáticamente. Escriba una instrucción sql para consultar toda la información de los estudiantes en el archivo de configuración de asignación de sql:

<?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="org.chengzi.mapper.StudentMapper">
    <select id="selectAll" resultType="student">
        select *
        from student;
    </select>
</mapper>

3.3 Escribir métodos de prueba

En la clase MyBatisTest, escriba el código para probar y consultar toda la información de los estudiantes, de la siguiente manera:

public class MyBatisTest {
    
    
    @Test
    public void testSelectAll() throws IOException {
    
    
        //1. 获取SqlSessionFactory
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

        //2. 获取SqlSession对象
        SqlSession sqlSession = sqlSessionFactory.openSession();

        //3. 获取Mapper接口的代理对象
        StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);

        //4. 执行方法
        List<Student> students = studentMapper.selectAll();
        System.out.println(students);

        //5. 释放资源
        sqlSession.close();
    }
}

Después de aprender el marco SSM en el futuro, esta parte del código será muy simple. El enfoque aquí está en la línea de código que ejecuta el método.

resultado de la operación:

imagen-20230129202650613

Aquí se encuentra que la información de algunos campos en la base de datos no está encapsulada en el objeto Java. La razón del problema es muy simple, porque los nombres de las columnas de las tablas en la base de datos son inconsistentes con los nombres de los atributos de las clases de entidades. en el código Java Por ejemplo, las puntuaciones de matemáticas de los estudiantes, en MySQL El método llamado score_math se usa en Java, pero se llama scoreMath en Java, y no hay problema con los dos métodos de nomenclatura.

Hay dos formas de resolver este problema :

  1. Nombres de campo de la tabla de datos de alias
  2. Use resultMap para definir la relación de mapeo entre nombres de campos y nombres de atributos

Por ejemplo:

<mapper namespace="org.chengzi.mapper.StudentMapper">
    <select id="selectAll" resultType="student">
        select id,name,gender,score_english as scoreEnglish,score_Math as scoreMath
        from student;
    </select>
</mapper>

En este punto, se ha solucionado el problema de que los datos no se pueden encapsular en objetos, pero al consultar toda la información de los estudiantes, necesitamos enumerar todos los nombres de los campos, lo que obviamente es ineficiente y no es recomendable. MyBatis proporciona fragmentos de sql para solucionar este problema.

Por ejemplo:

<mapper namespace="org.chengzi.mapper.StudentMapper">
    <!--
	sql片段
	-->
    <sql id="student_column">
        select id,name,gender,score_english as scoreEnglish,score_Math as scoreMath
    </sql>
    
    <select id="selectAll" resultType="student">
        <include refid="student_column"/>
        from student;
    </select>
</mapper>

El id se usa como el identificador único del fragmento sql, y es suficiente usar la <include>referencia de la etiqueta en la instrucción sql original cuando se usa.

Este es otro problema, si operas en algunos campos de la tabla de datos, habrá una gran cantidad de fragmentos de sql, lo que obviamente no es recomendable, All MyBatis usa el método resultMap para resolver este problema.

3.4 Uso de mapa de resultados

Al resolver el problema de que algunos campos en la tabla de datos no se pueden encapsular en objetos Java, el método de usar alias es ineficiente y el método de fragmentos sql no es flexible.MyBatis proporciona el método resultMap para definir la relación de mapeo entre nombres de campo y nombres de atributos.

Al usar, solo necesita usar el siguiente método para definir en el archivo de configuración de mapeo sql:

<mapper namespace="org.chengzi.mapper.StudentMapper">

    <resultMap id="studentResultMap" type="student">
        <result column="score_english" property="scoreEnglish"/>
        <result column="score_math" property="scoreMath"/>
    </resultMap>
    
    <select id="selectAll" resultMap="studentResultMap">
     select *
        from student;
    </select>
</mapper>

Al usar este método, solo es necesario asignar la parte del nombre del campo en la tabla de datos que es diferente del atributo en la clase de entidad de Java, lo que mejora enormemente la eficiencia. La identificación en la etiqueta resultMap se usa como un identificador único y se usa en la declaración.

En resultMap, hay dos etiquetas disponibles, para mapear a datos generales y para mapear a datos de clave principal.

Ejecuta el programa:

imagen-20230129210333422

Todos los datos de la tabla de datos se han encapsulado en objetos Java.

4. Detalles de la consulta

En el cliente, los datos a menudo no se muestran en su totalidad, sino en parte, y la otra parte generalmente debe verse en la forma de ver los detalles. En este momento, cuando el usuario selecciona al estudiante especificado y verifica la información, la identificación del estudiante se envía al código Java y toda la información del estudiante se consulta a través de la identificación del usuario.

Podemos implementar la función de detalles de la consulta a través de los siguientes pasos:

  • Escriba la interfaz de Mapper:
    • Parámetro: identificación
    • Valor de retorno: Estudiante
  • Escribir archivo de mapeo sql
  • Ejecutar el método de prueba

Al consultar detalles, a menudo es necesario pasar un parámetro, como id, para consultar toda la información del estudiante de acuerdo con la id, y el resultado devuelto es solo un registro de datos, por lo que solo debe encapsularse en un objeto.

4.1 Métodos de interfaz de escritura

Defina el método de consulta de datos basado en id en la interfaz de StudentMapper:

/**
  * 查看详情:根据Id查询
  */
Student selectById(int id);

4.2 Escribir sentencia sql

A través de la función de salto rápido de MyBatisX, salta al archivo de configuración del mapeo sql correspondiente, en este momento, la declaración se ha generado automáticamente y se puede usar directamente el resultMap definido anteriormente.

<select id="selectById"  resultMap="studentResultMap">
    select *
    from student where id = #{id};
</select>

Lo anterior es #{id}un marcador de posición de parámetro, similar al que se usó antes , que se explicará más adelante.

4.3 Escritura de métodos de prueba

En la clase MyBatisTest, escriba el código para probar y consultar toda la información de los estudiantes, de la siguiente manera:

@Test
    public void testSelectById() throws IOException {
    
    
        //接收参数
        int id =2;
        //1. 获取SqlSessionFactory
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

        //2. 获取SqlSession对象
        SqlSession sqlSession = sqlSessionFactory.openSession();

        //3. 获取Mapper接口的代理对象
        StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);

        //4. 执行方法
        Student students = studentMapper.selectById(id);
        System.out.println(students);

        //5. 释放资源
        sqlSession.close();
    }

En este punto, a diferencia de la consulta anterior de toda la información de los alumnos, los parámetros y valores de retorno de este método son diferentes. Solo necesitamos pasar los parámetros recibidos por el código Java, y luego podemos encapsular los datos consultados en un objeto de clase Student.

resultado de la operación:

imagen-20230129212902381

4.4 Marcadores de posición de parámetros

Como se mencionó anteriormente, la instrucción sql se usa #{xx}como marcador de posición de parámetro, y puede ver en el registro en ejecución que, de hecho, Java reemplaza automáticamente la posición del marcador de posición de parámetro durante el proceso en ejecución , lo que resuelve la inyección de sql causada por la pregunta de ortografía de cadenas de sql . Como se muestra en la imagen:

imagen-20230129213409241

De hecho, el marcador de posición en MyBatis #{xx}también ${xx}, lo que es fácil de causar problemas de inyección de sql al deletrear cadenas, por lo que generalmente se usa después de la declaración de sql cuando el nombre de la tabla de la consulta es incierto.

No es difícil encontrar que la diferencia entre los dos es que #{xx}la capa inferior del marcador de posición es una declaración preparada, mientras que ${xx}la es una declaración, que tiene el problema de la inyección de sql. Por lo tanto, se recomienda utilizar el primero como marcador de posición de parámetro en el desarrollo de MyBatis.

4.5 uso de tipo de parámetro

Si hay parámetros en el método de la interfaz del asignador, el tipo de parámetro debe configurarse en el archivo de asignación de sql correspondiente para especificar el tipo de datos del parámetro, pero este atributo se puede omitir. No es difícil entender que la razón por la que se puede omitir es porque el tipo de datos de este parámetro se ha definido en el archivo de interfaz de Mapper.

como sigue:

<mapper>   
	<select id="selectById" parameterType="int" resultMap="studentResultMap">
select * from student where id=#{id};
    </select>
</mapper>

4.6 Manejo de caracteres especiales

Cuando MyBatis escribe sql en el archivo de configuración de mapeo de sql correspondiente, aparecerán algunos caracteres especiales, por ejemplo, cuando se usa el signo menor que, se confundirá con la <parte de . Como se muestra en la imagen:

imagen-20230129233235106

MyBatis también proporciona un método correspondiente para resolver este problema, puede utilizar estos dos métodos:

  1. Carácter de escape: se utiliza cuando hay pocos caracteres especiales
  2. CDATE: se usa cuando hay muchos caracteres especiales confusos

Por ejemplo, usando caracteres de escape:

imagen-20230129234459723

O use el método CDATA:

imagen-20230129234642325

Cuando se utiliza un IDE con la función de autocompletado de código, solo se requiere una parte de la entrada para el autocompletado.Este método se usa cuando hay muchos caracteres especiales.

5. Consulta de condiciones múltiples

En la operación real del cliente, a menudo consultamos datos basados ​​en la satisfacción simultánea de múltiples condiciones, como consultar la información de todos los estudiantes cuyas calificaciones en inglés y matemáticas son superiores a 60 en el caso de la consulta.

El enfoque aquí es cómo escribir sentencias sql.

Podemos implementar la función de detalles de la consulta a través de los siguientes pasos:

  • Escribir la interfaz de Mapper
    • Parámetros: todas las condiciones de consulta
    • resultado:List<Student>
  • Escribir archivo de configuración de mapeo sql
  • Ejecutar el método de prueba

5.1 Métodos de interfaz de escritura

Para definir el método de consulta multicondición en la interfaz de StudentMapper, también se deben definir parámetros al definir la interfaz.MyBatis tiene múltiples métodos de implementación para múltiples parámetros de consulta multicondición.

Método uno :

Úselo para @Param("参数名称")marcar cada parámetro, que debe usarse en el archivo de configuración de asignación como #{参数名称}marcador de posición

List<Student> selectByCondition(@Param("scoreEnglish") int scoreEnglish, @Param("scoreMath") int scoreMath);

Método dos :

Encapsule varios parámetros en un objeto de entidad y utilice el objeto de entidad como parámetro de método de la interfaz. Este método requiere que #{内容}cuando , el contenido interno debe ser consistente con el nombre del atributo de la clase de entidad.

List<Student> selectByCondition(Student student);

Método tres :

Encapsule varios parámetros en la colección de mapas y utilice la colección de mapas como parámetro de método de la interfaz. Este método requiere que #{内容}cuando , el contenido interno debe ser coherente con el nombre de la clave en la colección de mapas.

List<Student> selectByCondition(Map map);

5.2 Escribir sentencia sql

Escriba la declaración correspondiente en el archivo StudentMapper.xml, donde también se usa resultMap. Ejemplo:

<mapper> 
	<select id="selectByCondition" resultMap="studentResultMap">
        select * from student 
                 where score_english > #{scoreEnglish} and score_math > #{scoreMath};
    </select>
</mapper>

5.3 Escritura de métodos de prueba

En la consulta de múltiples condiciones, debido a que existen tres métodos diferentes para establecer parámetros al definir la interfaz del Mapeador, los métodos de ejecución específicos aquí también se dividen en tres métodos diferentes.

    @Test
    public void testSelectByCondition() throws IOException {
    
    
        //接收参数
        int scoreEnglish=60;
        int scoreMath=60;
        //1. 获取SqlSessionFactory
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

        //2. 获取SqlSession对象
        SqlSession sqlSession = sqlSessionFactory.openSession();

        //3. 获取Mapper接口的代理对象
        StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);

        //4. 执行方法
        //方法1.使用第一种方法定义参数时使用
        List<Student> students = studentMapper.selectByCondition(scoreEnglish,scoreMath);
        System.out.println(students);
        
        //方法2.使用第二种方法定义参数时使用
        Student student = new Student();
        student.setScoreEnglish(scoreEnglish);
        student.setScoreMath(scoreMath);

        List<Student> students = studentMapper.selectByCondition(student);
        System.out.println(students);
        
        //方法3.使用第三种方法定义参数时使用
        Map map = new HashMap();
        map.put("scoreEnglish" , scoreEnglish);
        map.put("scoreMath" , scoreMath);
        
        List<Student> students = studentMapper.selectByCondition(map);
        System.out.println(students);
        //5. 释放资源
        sqlSession.close();
    }
}

Usando tres métodos para ejecutar el programa, los resultados son los mismos, como se muestra en la figura:

imagen-20230129224312015

5.4 SQL dinámico

Arriba, configuramos tres parámetros en la consulta de múltiples condiciones y pasamos tres parámetros al ejecutar el programa de prueba. Sin embargo, la realidad es que es posible que el usuario no ingrese un valor para cada parámetro, y en este momento hay un problema con el sql anterior.

Cuando el usuario ingresa dos parámetros, la declaración SQL es la siguiente:

select * from student where score_english > #{scoreEnglish} and score_math > #{scoreMath};

Cuando el usuario solo ingresa una condición, la declaración sql es la siguiente:

select * from student where score_english > #{scoreEnglish} ;

Para este problema, MyBatis tiene una potente solución:

  • si
  • elegir (cuando, de lo contrario)
  • recortar (dónde, establecer)
  • para cada

Por ejemplo, use el siguiente método para resolver:

<select id="selectByCondition" resultMap="studentResultMap">
     select * from student 
     where
        <if test="scoreEnglish !=null">
              score_english > #{scoreEnglish}
        </if>
		<if test="scoreMath !=null">
              and score_math > #{scoreMath}
        </if>

</select>

Con este método, las cadenas se empalmarán dinámicamente cuando se ejecute el programa. Si se pasan ambos datos, el empalme de la instrucción sql es el siguiente:

imagen-20230129231539021

Y si el usuario no pasa el último valor, entonces el programa también se ejecuta normalmente, la cadena sql en este momento:

imagen-20230129231659101

Pero si el primero no tiene datos de entrada y solo el segundo ha dado datos, el programa tendrá un error, porque al empalmar cadenas de sql, y aparecerá después de donde, y el error de sintaxis de sql ocurrirá en este momento. como sigue:

select * from student where and scoreMath > ? ;//语法错误

Este problema se puede resolver mediante el uso de la etiqueta where, que puede reemplazar la palabra clave where, y el y después de la primera condición se eliminará dinámicamente.Si todos los parámetros no tienen un valor determinado, la palabra clave where no se utilizará.

Nota: En este punto, debe agregar la palabra clave y a cada condición, y la y <where>después de la primera condición se eliminará dinámicamente.

En este punto, el programa se ejecuta con éxito y resuelve el problema de que el usuario no puede ingresar valores para todos los parámetros. Como se muestra en la imagen:

imagen-20230129232606376

6. Consulta de condición única de SQL dinámico

En el cliente, a veces el usuario puede elegir una consulta condicional, pero el código Java no sabe qué condición elegir, por lo que es necesario utilizar la consulta condicional única de sql dinámico.

Tal requisito se puede implementar usando la choose(when,otherwise)etiqueta , y el uso de la etiqueta de elección es similar a la instrucción Switch en Java.

6.1 Métodos de interfaz de escritura

El método de consulta de condición única para escribir sql dinámico en la interfaz de Mapper:

List<Student> selectByConditionSingle(Map map);

6.2 Escribir sentencia sql

Escriba instrucciones sql en el archivo de configuración de mapeo sql, de la siguiente manera:

<mapper>    
    <select id="selectByConditionSingle" resultMap="studentResultMap">

        select * from student
        <where>
            <choose>
                <when test="scoreEnglish !=null">
                    score_english > #{scoreEnglish}
                </when>
                <when test="scoreMath !=null">
                    score_math > #{scoreMath}
                </when>
                <otherwise>
                    1=1
                </otherwise>
            </choose>
        </where>
    </select>
</mapper>

6.3 Escritura de métodos de prueba

Escriba el código de la prueba unitaria en la clase MyBatisTest, de la siguiente manera:

@Test
    public void testSelectByConditionSingle() throws IOException {
    
    
        //接收参数
        int scoreEnglish=60;
        int scoreMath=60;
        //1. 获取SqlSessionFactory
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

        //2. 获取SqlSession对象
        SqlSession sqlSession = sqlSessionFactory.openSession();

        //3. 获取Mapper接口的代理对象
        StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);

        Map map = new HashMap();
        map.put("scoreEnglish" , scoreEnglish);
        //map.put("scoreMath" , scoreMath);

        List<Student> students = studentMapper.selectByConditionSingle(map);
        System.out.println(students);
        //5. 释放资源
        sqlSession.close();
    }

El resultado de la ejecución es correcto, como se muestra en la figura:

imagen-20230130013053973

7. Resumen

Este artículo es un ejercicio práctico del desarrollo de MyBatis y el uso de archivos de configuración para implementar operaciones de adición, eliminación, modificación y consulta. Debido a la extensión del artículo, este artículo solo involucra operaciones de consulta. Como el método más común para operar bases de datos, Las operaciones de consulta deben practicarse continuamente para llegar a ser competentes. Al escribir SQL, aunque no se enfatizan las mayúsculas, se recomienda usar mayúsculas, porque las mayúsculas son un método SQL más estandarizado.

Terminé de escribir, revisé la hora, ahora son las dos de la mañana, acabo de terminar de escribir este artículo y afuera estaba extraordinariamente tranquilo. La creación no es fácil, espero que te pueda ayudar. Me gusta primero, míralo después, conviértelo en un hábito y nos vemos en el próximo número.

imagen-20230130001121015

Supongo que te gusta

Origin blog.csdn.net/zhangxia_/article/details/128796222
Recomendado
Clasificación