LindormTable est compatible avec le protocole MySQL. Vous pouvez donc utiliser le framework de mappage objet-relationnel (ORM) MyBatis pour créer des applications Java. MyBatis sépare le SQL du code applicatif en permettant de définir la logique d'accès aux données dans des interfaces de mappage, ce qui évite d'intégrer du SQL dans la logique métier.
À l'issue de ce tutoriel, vous aurez :
Ajouté les dépendances MyBatis et le pilote JDBC MySQL à un projet Maven
Configuré
mybatis-config.xmlpour vous connecter à LindormTableDéfini une interface de mappage avec des opérations de création, lecture, upsert et suppression
Exécuté une démonstration fonctionnelle sur LindormTable
Prérequis
Avant de commencer, assurez-vous que :
La fonctionnalité de compatibilité MySQL est activée sur votre instance LindormTable. Pour plus de détails, consultez Activer la fonctionnalité de compatibilité MySQL.
Le JDK 1.8 ou une version ultérieure est installé
L'adresse IP de votre client figure dans la liste blanche de votre instance Lindorm. Pour plus de détails, consultez Configurer les listes blanches.
Configurer le projet
Étape 1 : Ajouter les dépendances
Dans votre projet Maven, ajoutez les dépendances suivantes au bloc dependencies du fichier 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>
Étape 2 : Configurer la connexion
Dans le dossier resources, créez le fichier mybatis-config.xml avec les paramètres de connexion pour 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&allowPublicKeyRetrieval=true&useServerPrepStmts=true&useLocalSessionState=true&rewriteBatchedStatements=true&cachePrepStmts=true&prepStmtCacheSize=100&prepStmtCacheSqlLimit=50000000"/>
<property name="username" value="<username>"/>
<property name="password" value="<password>"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper class="org.example.UserMapper"/>
</mappers>
</configuration>
Remplacez les espaces réservés suivants :
| Espace réservé | Description |
|---|---|
<MySQL-compatible endpoint> |
Le point de terminaison compatible MySQL de votre instance. Pour obtenir cette valeur, consultez Afficher les points de terminaison. |
<database> |
Le nom de la base de données à laquelle se connecter. Si cet élément est omis, le client se connecte à la base de données par défaut. |
<username> |
Le nom d'utilisateur de la base de données. |
<password> |
Le mot de passe de la base de données. Pour le réinitialiser, consultez Modifier le mot de passe d'un utilisateur. |
Choisir le bon point de terminaison
| Type d'accès | Point de terminaison à utiliser |
|---|---|
| Depuis une instance Elastic Compute Service (ECS) située dans le même VPC (Virtual Private Cloud) | Adresse VPC du point de terminaison compatible MySQL |
| Depuis Internet | Adresse publique du point de terminaison compatible MySQL |
Si votre application s'exécute sur une instance ECS, utilisez le point de terminaison VPC pour une sécurité accrue et une latence réduite. Pour vous connecter via Internet, activez d'abord le point de terminaison public : dans la console, accédez à Database Connection > Wide Table Engine, puis cliquez sur Enable Public Endpoint.
Pour plus de détails sur les paramètres de la chaîne de connexion et leur impact sur les performances, consultez Configuration de la connexion.
Étape 3 : Définir le modèle de données
Créez une classe User pour représenter les lignes de la table de démonstration :
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) + '}';
}
}
Étape 4 : Créer le mapper
Créez une interface UserMapper. Chaque méthode est annotée avec l'instruction SQL qu'elle exécute sur 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();
}
Toutes les opérations d'écriture utilisent upsert plutôt que insert : il s'agit de la syntaxe privilégiée par LindormTable pour insérer ou mettre à jour des lignes en une seule instruction.
Étape 5 : Écrire le code de l'application
Chargez la configuration, ouvrez une session SqlSession et exécutez les opérations CRUD via le mapper :
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();
}
}
}
Exemple complet
Téléchargez l'exemple de projet complet : mybatis-demo.zip.
Après une exécution réussie, la sortie ressemble à ceci :
[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}]
FAQ
Pourquoi selectAllUser() génère-t-il l'erreur « ExecutionPlaceholder cannot be cast to java.util.List » ?
L'erreur complète est la suivante :
### Cause: java.lang.ClassCastException: class org.apache.ibatis.executor.ExecutionPlaceholder cannot be cast to class java.util.List
Les objets SqlSession et Mapper de MyBatis ne sont pas thread-safe. Cette erreur survient lorsque plusieurs threads accèdent simultanément à la même SqlSession ou au même Mapper. Assurez-vous que chaque thread crée sa propre SqlSession et obtient son propre mapper à partir de celle-ci.
Quelle est la différence entre les espaces réservés #{} et ${} ?
**#{}** |
**${}** |
|
|---|---|---|
| Implémentation | Liaison de paramètres précompilés JDBC PreparedStatement |
Remplacement direct de chaînes |
| Risque d'injection SQL | Aucun | Oui |
| Performance | Élevée — le plan d'exécution est réutilisable | Faible — chaque instruction est analysée à nouveau |
| À utiliser pour | Lier des valeurs dynamiques telles que les conditions WHERE |
Injecter des fragments SQL tels que des noms de table ou des colonnes ORDER BY |
Utilisez #{} pour toutes les valeurs de paramètre. Réservez ${} aux structures SQL dynamiques où la liaison paramétrée n'est pas possible.
#{} ne produit une véritable requête paramétrée que si useServerPrepStmts=true est défini dans la chaîne de connexion. Sans cela, le pilote JDBC MySQL réécrit l'instruction sous forme de littéral de chaîne au moment de l'exécution, contournant ainsi la précompilation. Pour plus de détails, consultez Configuration de la connexion.
Étapes suivantes
Documentation MyBatis — syntaxe XML des mappers, SQL dynamique et configuration avancée
Connexion via Java JDBC — paramètres de chaîne de connexion et optimisation des performances pour LindormTable