Framework Java MyBatis
Bibliothèques de classes Java courantes
MyBatis est un excellent framework de persistance qui simplifie l'interaction entre les applications Java et les bases de données relationnelles. MyBatis mappe les requêtes SQL vers des objets Java via XML ou des annotations, évitant ainsi une grande quantité de code répétitif dans la programmation JDBC traditionnelle.
Fonctionnalités clés de MyBatis
1. Séparation du SQL et du code
MyBatis permet aux développeurs de séparer les requêtes SQL du code Java, en les stockant dans des fichiers XML ou des annotations, ce qui rend le code plus clair et plus facile à maintenir.2. Mappage automatique
MyBatis peut automatiquement mapper les résultats des requêtes de base de données vers des objets Java, réduisant considérablement la charge de conversion des données.3. SQL dynamique
MyBatis fournit de puissantes capacités de SQL dynamique, permettant de générer différentes instructions SQL en fonction de différentes conditions.4. Mécanisme de mise en cache
MyBatis dispose de caches de premier et de second niveau intégrés, qui peuvent améliorer efficacement les performances des applications.Architecture de base de MyBatis
1. Composants principaux
- SqlSessionFactoryClasse de fabrique pour créer SqlSession
- SqlSessionInterface principale pour exécuter des commandes SQL
- Interface MapperDéfinit les méthodes pour les opérations de base de données
- Mapper XMLFichier de configuration contenant des instructions SQL
2. Flux de travail
- L'application crée SqlSessionFactory via SqlSessionFactoryBuilder.
- SqlSessionFactory crée SqlSession.
- SqlSession obtient une instance de l'interface Mapper.
- Appeler les méthodes du Mapper pour effectuer des opérations sur la base de données.
- Valider la transaction et fermer SqlSession.
Configuration MyBatis
1. Fichier de configuration principal (mybatis-config.xml)
Exemple
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<environments default="development">
<environment>
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis_db"/>
<property name="username" value="root"/>
<property name="password" value="password"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="com/example/mapper/UserMapper.xml"/>
</mappers>
</configuration>
2. Exemple de fichier Mapper
Exemple
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.mapper.UserMapper">
<select id="getUserById" parameterType="int" resultType="com.example.model.User">
SELECT * FROM users WHERE id = #{id}
</select>
<insert id="insertUser" parameterType="com.example.model.User">
INSERT INTO users(name, email) VALUES(#{name}, #{email})
</insert>
</mapper>
Utilisation de base de MyBatis
1. Obtention de SqlSession
Exemple
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession session = sqlSessionFactory.openSession();
2. Exécution d'une requête
Exemple
User user = session.selectOne("com.example.mapper.UserMapper.getUserById", 1);
// Méthode 2 : via l'interface Mapper
UserMapper mapper = session.getMapper(UserMapper.class);
User user = mapper.getUserById(1);
3. Exécution d'une insertion
Exemple
newUser.setName("Zhang San");
newUser.setEmail("[email protected]");
int rows = mapper.insertUser(newUser);
session.commit(); // Valider la transaction
SQL dynamique dans MyBatis
MyBatis fournit une variété d'éléments SQL dynamiques, qui peuvent générer dynamiquement des instructions SQL en fonction de différentes conditions :
1. L'élément if
Exemple
SELECT * FROM users
WHERE 1=1
<if test="name != null">
AND name = #{name}
</if>
<if test="email != null">
AND email = #{email}
</if>
</select>
2. Les éléments choose/when/otherwise
Exemple
SELECT * FROM users
WHERE status = 'ACTIVE'
<choose>
<when test="name != null">
AND name like #{name}
</when>
<when test=" != null">
AND email = #{email}
</when>
<otherwise>
AND 1=1
</otherwise>
</choose>
</select>
3. L'élément foreach
Exemple
SELECT * FROM users
WHERE id IN
<foreach item="id collection="list" open="(" separator="," close=")">
#{id}
</foreach>
</select>
Requêtes d'association MyBatis
1. Association un-à-un
Exemple
<id property="id" column="user_id"/>
<result property="name" column="user_name"/>
<association property="address" javaType="Address">
<id property="id" column="address_id"/>
<result property="street" column="street"/>
<result property="city" column="city"/>
</association>
</resultMap>
<select resultMap="userWithAddress">
SELECT
u.id as user_id, u.name as user_name,
a.id as address_id, a.street, a.city
FROM users u
LEFT JOIN addresses a ON u.address_id = a.id
WHERE u.id = #{id}
</select>
2. Association un-à-plusieurs
Exemple
<id property="id" column="user_id"/>
<result property="name" column="user_name"/>
<collection property="orders" ofType="Order">
<id property="id" column="order_id"/>
<result property="orderDate" column="order_date"/>
<result property="amount" column="amount"/>
</collection>
</resultMap>
<select resultMap="userWithOrders">
SELECT
u.id as user_id, u.name as user_name,
o.id as order_id, o.order_date, o.amount
FROM users u
LEFT JOIN orders o ON u.id = o.user_id
WHERE u.id = #{id}
</select>
Mécanisme de cache MyBatis
1. Cache de premier niveau
Le cache de premier niveau est un cache de niveau SqlSession, activé par défaut. Au sein d'une même SqlSession, la même requête n'exécutera le SQL qu'une seule fois.
Fonctionnalités :
Portée :
SqlSessionNiveau (activé par défaut, ne peut pas être désactivé)Cycle de vie : avec la
SqlSessioncréation de SqlSession il est créé ; avec laSqlSessionfermeture de SqlSession il est détruit.Scénarios qui déclenchent le vidage :
Execute
INSERT/UPDATE/DELETEopérationsAppel
sqlSession.clearCache()Effectuer un rollback de transaction
Configurer un autre
Statement ID(même si le SQL est le même)
Notes :
Exemple
User user1 = sqlSession.selectOne("getUserById", 1); // Exécuter la requête SQL
User user2 = sqlSession.selectOne("getUserById", 1); // Récupéré depuis le cache
2. Cache de second niveau
Le cache de second niveau est un cache au niveau du Mapper, et plusieurs SqlSessions peuvent partager le cache. Il doit être activé dans le fichier de configuration :
<settings>
<setting name="cacheEnabled" value="true"/> <!-- 默认true可省略 -->
</settings>
Et configurez-le dans le fichier Mapper :
<cache eviction="LRU" <!-- 淘汰策略(默认LRU) --> flushInterval="60000" <!-- 刷新间隔(毫秒) --> size="512" <!-- 缓存对象数量 --> readOnly="true"/> <!-- 只读模式(性能更优) -->
Comparaison des stratégies de cache :
| Stratégie | Description | Scénario applicable |
|---|---|---|
| LRU | Moins récemment utilisé | Utilisation régulière |
| FIFO | Premier entré, premier sorti | Accès à ordre fixe |
| SOFT | Référence douce | Scénarios sensibles à la mémoire |
| WEAK | Référence faible | Extrêmement sensible à la mémoire |
Intégration de MyBatis avec Spring
1. Configuration des dépendances (recommandée pour Spring Boot moderne)
Exemple
<dependencies>
<!-- Solution d'intégration Spring Boot Starter (recommandée) -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>3.0.3</version>
</dependency>
<!-- Ou à utiliser dans les projets Spring traditionnels -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>3.0.3</version>
</dependency>
<!-- Sélectionnez le pilote de base de données en fonction de la situation réelle -->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<version>8.0.33</version>
</dependency>
</dependencies>
2. Approches de configuration (trois méthodes courantes)
Approche 1 : Auto-configuration Spring Boot (la plus simple)
Exemple
mybatis:
mapper-locations: classpath*:mapper/**/*.xml
type-aliases-package: com.example.model
configuration:
map-underscore-to-camel-case: true # Conversion automatique en camel case
Approche 2 : Configuration complète Java Config (contrôle fin)
Exemple
public class MyBatisConfig {
@Bean
@ConfigurationProperties(prefix = "spring.datasource")
public DataSource dataSource() {
return DataSourceBuilder.create().build();
}
@Bean
public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
SqlSessionFactoryBean factory = new SqlSessionFactoryBean();
factory.setDataSource(dataSource);
factory.setTypeAliasesPackage("com.example.model");
// Configuration personnalisée (exemple)
org.apache.ibatis.session.Configuration config = new Configuration();
config.setMapUnderscoreToCamelCase(true);
config.setDefaultFetchSize(100);
factory.setConfiguration(config);
// Configuration du plugin (exemple)
factory.setPlugins(
new MyBatisInterceptor(),
new PaginationInterceptor()
);
return factory.getObject();
}
@Bean
public MapperScannerConfigurer mapperScanner() {
MapperScannerConfigurer scanner = new MapperScannerConfigurer();
scanner.setBasePackage("com.example.mapper");
scanner.setAnnotationClass(Repository.class); // Restreindre l'analyse des annotations
return scanner;
}
}
Approche 3 : Configuration XML traditionnelle (compatible avec les projets hérités)
Exemple
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="configLocation" value="classpath:mybatis-config.xml"/>
</bean>
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.example.mapper"/>
</bean>
3. Configuration de la gestion des transactions
Exemple
@EnableTransactionManagement
public class TransactionConfig {
@Bean
public PlatformTransactionManager transactionManager(DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
// On peut définir un modèle de transaction
@Bean
public TransactionTemplate transactionTemplate(PlatformTransactionManager manager) {
return new TransactionTemplate(manager);
}
}
4. Directives d'utilisation et bonnes pratiques
Définition de l'interface Mapper :
Exemple
public interface UserMapper {
@Select("SELECT * FROM users WHERE id = #{id}")
User selectById(@Param("id") int id);
@Options(useGeneratedKeys = true, keyProperty = "id")
@Insert("INSERT INTO users(name) VALUES(#{name})")
int insert(User user);
}
Exemple de couche de service :
Exemple
@Transactional(readOnly = true) // En lecture seule par défaut
public class UserService {
private final UserMapper userMapper;
@Autowired // L'injection par constructeur est recommandée
public UserService(UserMapper userMapper) {
this.userMapper = userMapper;
}
@Transactional // Ouvrir des transactions séparément pour les opérations d'écriture
public User createUser(String name) {
User user = new User();
user.setName(name);
userMapper.insert(user);
return userMapper.selectById(user.getId());
}
}
5. Intégration des fonctionnalités avancées
Configuration dynamique des sources de données :
Exemple
@Primary
public DataSource dynamicDataSource() {
DynamicDataSource ds = new DynamicDataSource();
ds.setDefaultTargetDataSource(primaryDataSource());
ds.setTargetDataSources(Map.of(
"master", primaryDataSource(),
"slave", secondaryDataSource()
));
return ds;
}
Gestion des transactions multi-sources de données :
Exemple
public PlatformTransactionManager transactionManager() {
return new ChainedTransactionManager(
new JpaTransactionManager(entityManagerFactory()),
new DataSourceTransactionManager(dataSource())
);
}
Bonnes pratiques pour MyBatis
- Utilisez les interfaces Mapper au lieu d'utiliser directement SqlSession: Cela rend le code plus sûr au niveau des types et plus facile à maintenir.
- Utilisez le SQL dynamique de manière appropriée: Évitez les risques d'injection SQL et préservez la lisibilité du SQL.
- Opérations par lots: Pour les opérations sur de grands lots de données, utilisez le traitement par lots pour améliorer les performances.
- Utilisez la mise en cache de manière appropriée: Configurez des stratégies de mise en cache adaptées aux besoins métier.
- Optimisation SQL: Écrivez des instructions SQL efficaces dans le Mapper XML.
MyBatis est un framework ORM flexible et puissant. Utilisé correctement, il peut grandement améliorer l'efficacité du développement et les performances des applications. J'espère que cet article vous aidera à comprendre et à utiliser le framework MyBatis.
Autres extensions