Todos los productos
Search
Centro de documentos

Lindorm:Desarrollo de aplicaciones con el framework ORM de Java MyBatis

Última actualización: Sep 05, 2026

LindormTable es compatible con el protocolo MySQL, por lo que puede usar el framework de mapeo objeto-relacional (ORM) MyBatis para construir aplicaciones en Java. MyBatis separa el código SQL del código de la aplicación y le permite definir la lógica de acceso a datos en interfaces de mapeo. De este modo, la lógica de negocio queda libre de instrucciones SQL incrustadas.

Al finalizar este tutorial, habrá logrado lo siguiente:

  • Agregó las dependencias de MyBatis y del controlador JDBC de MySQL a un proyecto de Maven.

  • Configuró mybatis-config.xml para conectarse a LindormTable.

  • Definió una interfaz de mapeo con operaciones de creación, lectura, upsert y eliminación.

  • Ejecutó una demostración funcional contra LindormTable.

Requisitos previos

Antes de empezar, asegúrese de contar con lo siguiente:

Configuración del proyecto

Paso 1: Agregar las dependencias

En su proyecto de Maven, agregue a continuación las dependencias dentro del bloque dependencies del archivo pom.xml:

<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.5.14</version>
</dependency>
<dependency>
    <groupId>com.mysql</groupId>
    <artifactId>mysql-connector-j</artifactId>
    <version>8.3.0</version>
</dependency>

Paso 2: Configurar la conexión

En la carpeta resources, cree el archivo mybatis-config.xml con los parámetros de conexión para LindormTable:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://<MySQL-compatible endpoint>:33060/<database>?sslMode=disabled&amp;allowPublicKeyRetrieval=true&amp;useServerPrepStmts=true&amp;useLocalSessionState=true&amp;rewriteBatchedStatements=true&amp;cachePrepStmts=true&amp;prepStmtCacheSize=100&amp;prepStmtCacheSqlLimit=50000000"/>
                <property name="username" value="<username>"/>
                <property name="password" value="<password>"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper class="org.example.UserMapper"/>
    </mappers>
</configuration>

Reemplace los siguientes marcadores de posición:

Marcador de posición

Descripción

<MySQL-compatible endpoint>

El endpoint compatible con MySQL de su instancia. Para obtener este valor, consulte View endpoints.

<database>

El nombre de la base de datos a la que se conectará. Si se omite, el cliente se conecta a la base de datos predeterminada.

<username>

El nombre de usuario de la base de datos.

<password>

La contraseña de la base de datos. Para restablecerla, consulte Change a user password.

Selección del endpoint adecuado

Tipo de acceso

Endpoint recomendado

Desde una instancia de Elastic Compute Service (ECS) en la misma virtual private cloud (VPC)

Dirección VPC del endpoint compatible con MySQL

Desde Internet

Dirección pública del endpoint compatible con MySQL

Si su aplicación se ejecuta en una instancia de ECS, use el endpoint de VPC para mejorar la seguridad y reducir la latencia. Para conectarse por Internet, primero habilite el endpoint público: en la consola, vaya a Database Connection > Wide Table Engine y haga clic en Enable Public Endpoint.

Para conocer los detalles sobre los parámetros de la cadena de conexión y cómo mejoran el rendimiento, consulte Connection configuration.

Paso 3: Definir el modelo de datos

Cree una clase User para representar las filas de la tabla de demostración:

package org.example;

import java.nio.charset.StandardCharsets;
import java.sql.Date;
import java.sql.Timestamp;

public class User {
  private int userId;
  private String userName;
  private double height;
  private long score;
  private Timestamp createTime;
  private Date birthday;
  private byte[] digest;

  public User(int userId, String userName, double height, long score,
      Timestamp createTime, Date birthday, byte[] digest) {
    this.userId = userId;
    this.userName = userName;
    this.height = height;
    this.score = score;
    this.createTime = createTime;
    this.birthday = birthday;
    this.digest = digest;
  }

  public int getUserId() { return userId; }
  public void setUserId(int userId) { this.userId = userId; }

  public String getUserName() { return userName; }
  public void setUserName(String userName) { this.userName = userName; }

  public double getHeight() { return height; }
  public void setHeight(double height) { this.height = height; }

  public long getScore() { return score; }
  public void setScore(long score) { this.score = score; }

  public Timestamp getCreateTime() { return createTime; }
  public void setCreateTime(Timestamp createTime) { this.createTime = createTime; }

  public Date getBirthday() { return birthday; }
  public void setBirthday(Date birthday) { this.birthday = birthday; }

  public byte[] getDigest() { return digest; }
  public void setDigest(byte[] digest) { this.digest = digest; }

  @Override
  public String toString() {
    return "User{" + "userId=" + userId + ", userName='" + userName + '\'' +
        ", height=" + height + ", score=" + score + ", createTime=" + createTime +
        ", birthday=" + birthday + ", digest=" + new String(digest, StandardCharsets.UTF_8) + '}';
  }
}

Paso 4: Crear el mapeador

Cree una interfaz UserMapper. Cada método lleva una anotación con la instrucción SQL que se ejecuta contra LindormTable:

package org.example;

import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;

import java.util.List;

public interface UserMapper {

  @Update("create table if not exists demo_user(`id` INT, `name` VARCHAR, `height` DOUBLE, `score` BIGINT, `createtime` TIMESTAMP, `birthday` DATE, digest VARBINARY, primary key(id))")
  void createUserTable();

  @Update("drop table if exists demo_user")
  void dropUserTable();

  @Insert("upsert into demo_user(`id`,`name`,`height`,`score`,`createtime`,`birthday`,`digest`) values(#{userId},#{userName},#{height},#{score},#{createTime},#{birthday},#{digest})")
  int upsertUser(User user);

  @Delete("delete from demo_user where `id` = #{userId}")
  int deleteUser(@Param("userId") int userId);

  @Select("select * from demo_user where `id` = #{userId}")
  User selectOneUser(@Param("userId") int userId);

  @Select("select * from demo_user")
  List<User> selectAllUser();
}

Todas las operaciones de escritura usan upsert en lugar de insert. Esta es la sintaxis recomendada en LindormTable para insertar o actualizar filas con una sola instrucción.

Paso 5: Escribir el código de la aplicación

Cargue la configuración, abra una SqlSession y ejecute las operaciones CRUD mediante el mapeador:

package org.example;

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 java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.sql.Date;
import java.sql.Timestamp;

public class MybatisDemo {
  public static void main(String[] args) throws Exception {
    String resource = "mybatis-config.xml";
    InputStream inputStream = Resources.getResourceAsStream(resource);
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

    try (SqlSession session = sqlSessionFactory.openSession()) {
      UserMapper mapper = session.getMapper(UserMapper.class);

      // Create the table
      mapper.createUserTable();

      // Verify the table is empty
      System.out.println(mapper.selectAllUser());

      // Insert two users
      User user1 = new User(1, "zhangsan", 1.8, 100,
          new Timestamp(System.currentTimeMillis()),
          Date.valueOf("1995-03-02"),
          "hello".getBytes(StandardCharsets.UTF_8));
      User user2 = new User(2, "lisi", 1.7, 90,
          new Timestamp(System.currentTimeMillis()),
          Date.valueOf("1996-08-02"),
          "world".getBytes(StandardCharsets.UTF_8));

      mapper.upsertUser(user1);
      mapper.upsertUser(user2);

      // Query all users and a single user
      System.out.println(mapper.selectAllUser());
      System.out.println(mapper.selectOneUser(1));

      // Delete user1 and verify
      mapper.deleteUser(1);
      System.out.println(mapper.selectAllUser());

      // Update user2's score using upsert and verify
      user2.setScore(99);
      mapper.upsertUser(user2);
      System.out.println(mapper.selectAllUser());

      // Clean up
      mapper.dropUserTable();
    }
  }
}

Ejemplo completo

Descargue el proyecto de ejemplo completo: mybatis-demo.zip.

Tras una ejecución exitosa, la salida luce de la siguiente manera:

[User{userId=1, userName='zhangsan', height=1.8, score=100, createTime=2023-12-02 09:39:17.63, birthday=1995-03-02, digest=hello}, User{userId=2, userName='lisi', height=1.7, score=90, createTime=2023-12-02 09:39:17.63, birthday=1996-08-02, digest=world}]
User{userId=1, userName='zhangsan', height=1.8, score=100, createTime=2023-12-02 09:39:17.63, birthday=1995-03-02, digest=hello}
[User{userId=2, userName='lisi', height=1.7, score=90, createTime=2023-12-02 09:39:17.63, birthday=1996-08-02, digest=world}]
[User{userId=2, userName='lisi', height=1.7, score=99, createTime=2023-12-02 09:39:17.63, birthday=1996-08-02, digest=world}]

Preguntas frecuentes

¿Por qué selectAllUser() genera el error "ExecutionPlaceholder cannot be cast to java.util.List"?

El error completo es el siguiente:

### Cause: java.lang.ClassCastException: class org.apache.ibatis.executor.ExecutionPlaceholder cannot be cast to class java.util.List

Los objetos SqlSession y Mapper de MyBatis no son seguros para subprocesos. Este error ocurre cuando varios hilos acceden al mismo SqlSession o Mapper de forma simultánea. Asegúrese de que cada hilo cree su propio SqlSession y obtenga su propio mapeador a partir de él.

¿Cuál es la diferencia entre los marcadores de posición #{} y ${}?

**#{}**

**${}**

Implementación

Vinculación de parámetros precompilados mediante PreparedStatement de JDBC

Reemplazo directo de cadenas

Riesgo de inyección SQL

Ninguna

Sí

Rendimiento

Alto: el plan de ejecución se reutiliza

Bajo: cada instrucción se analiza de nuevo

Cuándo usarlo

Al vincular valores dinámicos, como las condiciones WHERE

Al insertar fragmentos SQL, como nombres de tablas o columnas ORDER BY

Use #{} para todos los valores de parámetros. Reserve ${} para estructuras SQL dinámicas donde no sea posible la vinculación parametrizada.

Importante

#{} solo genera una consulta verdaderamente parametrizada si se establece useServerPrepStmts=true en la cadena de conexión. Sin este parámetro, el controlador JDBC de MySQL reescribe la instrucción como una cadena literal durante la ejecución y omite la precompilación. Para más información, consulte Connection configuration.

Pasos siguientes