Par exemple :
Il existe deux classes d'entités Utilisateur et Adresse
public class User {
private int id;
private String username; // 用户名
private List<Address> addresses;
// getter setter...
}
public class Address {
private int id;
private String detail; // 详细地址
private User user; //所属用户
// getter setter...
}
Base de données :
create table t_user(
id int(10) primary key auto_increment,
username varchar(50)
);
create table t_address(
id int(10) primary key auto_increment,
detail varchar(255),
user_id int(10),
CONSTRAINT FOREIGN KEY (user_id) REFERENCES t_user(id)
);
Configuration de la cartographie mybatis :
<?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.mkh.shop.model.User">
<resultMap type="User" id="userMap" autoMapping="true">
<id property="id" column="u_id"/>
<collection property="address" ofType="Address">
<id property="id" column="a_id"/>
<result property="detail" column="detail"/>
</collection>
</resultMap>
<select id="find" resultType="User" parameterType="map">
select *,
ta.id as 'a_id',
tu.id as 'u_id'
from t_user tu
left join t_address ta on ta.user_id=tu.id
<where>
<if test="name != null">
(username like #{name})
</if>
</where>
<if test="sort != null">
order by ${sort}
<choose>
<when test="order != null">${order}</when>
<otherwise>asc</otherwise>
</choose>
</if>
limit #{pageOffset},#{pageSize}
</select>
<select id="find_count" resultType="int" parameterType="map">
select count(*)
from t_user tu
left join t_address ta on ta.user_id=tu.id
<where>
<if test="name != null">
(username like #{name})
</if>
</where>
</select>
</mapper>
La relation entre les utilisateurs et les adresses est la suivante : un utilisateur a plusieurs adresses, une adresse ne peut appartenir qu'à un seul utilisateur, une à plusieurs
Supposons que la demande actuelle soit d'interroger les utilisateurs dans des pages, de les afficher dans un tableau et de tous les afficher. adresses de chaque utilisateur Sortez
Ensuite, le problème survient
Il n'y a aucun problème avec les données de pagination renvoyées selon la requête ci-dessus, mais le nombre total d'enregistrements de pagination est erroné.
Par exemple, les données trouvées (données de la base de données, pas affichage de la page) sont les suivantes :
u_id | nom d'utilisateur | a_id | détail |
---|---|---|---|
1 | utilisateur1 | 1 | District de Haidian, Pékin |
1 | utilisateur1 | 2 | District de Chaoyang, Pékin |
2 | utilisateur2 | 3 | Ville de Tianjin |
Parce que mon exigence est d'afficher les utilisateurs dans des pages, un utilisateur est donc une donnée affichée sur la page, qui ressemble à ceci. En théorie, il s'agit de deux données,
.ID utilisateur | Nom d'utilisateur | Adresse |
---|---|---|
1 | utilisateur1 | 1. District de Haidian, Pékin 2. District de Chaoyang, Pékin |
2 | utilisateur2 | 1. Ville de Tianjin |
1 page au total, 2 éléments de données au total, 10 éléments affichés sur chaque page |
Cependant, d'après la configuration find_count de mybatis, on constate qu'il y a 3 éléments. Comment résoudre ce problème ?
Lors de l'interrogation de count(*), toutes les tables associées à la jointure gauche doivent-elles être supprimées ? Cela rendra-t-il les données renvoyées inexactes ?
Explication supplémentaire : j'ai l'impression que tout le monde a mal compris ce que je voulais dire. En fait, mon problème concerne principalement SQL, pas mybatis, car une fois les données que j'ai interrogées ont été mappées, il n'y a eu aucun problème, c'était juste une pagination. il y a un problème avec le nombre total d'enregistrements, entraînant une pagination incorrecte
Je viens d'écrire un exemple et de le tester
`
Deux classes d'entités
classe publique Utilisateur {
Adresse de classe publique {
Fichier de cartographie
<resultMap type="com.atguigu.mybatis.entity.User" id="userMap" autoMapping="true">
<!-- sélectionnez tu.,ta., -->
<!-- ta.id comme 'a_id', -->
<!-- tu.id comme 'u_id' -->
<!-- de t_user tu , -->
<!-- t_address ta où ta.user_id=tu.id -->
Résultats des tests
La taille de la liste encapsulée<Utilisateur> ne pose aucun problème
Regroupez les mots clés par et vérifiez vous-même l'opération spécifique
Vous espérez vouloir deux éléments, mais votre SQL trouve trois éléments, donc une erreur s'affiche
.Vous devez diviser la logique :
Vous devez d'abord trouver l'utilisateur que vous souhaitez
Puis dans
??C'est une méthode pour vérifier List<Address> en utilisant l'ID utilisateur par vous-même
Dans ce cas, la pagination ne peut pas être effectuée de cette manière. Vous devez paginer les données de la table principale.
À l'origine, 100 éléments de données ont été interrogés, mais comme un vers plusieurs pliera et dédupliquera un grand nombre de données, les résultats réels étaient inférieurs à 100 éléments.
Dans ce cas, une requête imbriquée peut être utilisée pour résoudre le problème, qui nécessite N+1 exécutions et peut être chargée paresseusement.
Ou regardez ici : https://my.oschina.net/flags/...
Pour le contenu MyBatis, veuillez visiter : http://mybatis.tk
Modifier :
Il n'y aura aucun problème si vous utilisez une sous-requête
L'auteur peut jeter un œil à
Mybatis-PageHelper
implémentation de la conversion SQLIl est recommandé à l'auteur d'utiliser directement Mybatis-PageHelper pour implémenter la pagination