Rumah > Soal Jawab > teks badan
Contohnya:
Terdapat dua kelas entiti Pengguna dan Alamat
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...
}
Pangkalan data:
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)
);
konfigurasi pemetaan 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>
Hubungan antara pengguna dan alamat ialah: seorang pengguna mempunyai berbilang alamat, satu alamat hanya boleh dimiliki oleh seorang pengguna, satu-dengan-banyak
Andaikan permintaan semasa adalah untuk menanyakan pengguna dalam halaman, memaparkannya dalam jadual dan memaparkan semua alamat setiap pengguna Keluar
Kemudian masalah datang
Tiada masalah dengan data paging yang dikembalikan mengikut pertanyaan di atas, tetapi jumlah rekod paging adalah salah.
Sebagai contoh, data yang ditemui (data pangkalan data, bukan paparan halaman) adalah seperti berikut:
u_id | nama pengguna | a_id | perincian |
---|---|---|---|
1 | pengguna1 | 1 | Daerah Haidian, Beijing |
1 | pengguna1 | 2 | Daerah Chaoyang, Beijing |
2 | pengguna2 | 3 | Bandar Tianjin |
Oleh kerana keperluan saya adalah untuk memaparkan pengguna dalam halaman, jadi pengguna adalah sekeping data yang dipaparkan pada halaman, yang kelihatan seperti ini, secara teori, ia adalah dua keping data,
ID Pengguna | Nama pengguna | Alamat |
---|---|---|
1 | pengguna1 | 1. Daerah Haidian, Beijing 2. Daerah Chaoyang, Beijing |
2 | pengguna2 | 1. Bandar Tianjin |
1 halaman kesemuanya, 2 keping data keseluruhannya, 10 keping dipaparkan pada setiap halaman |
Namun, mengikut konfigurasi find_count mybatis, didapati terdapat 3 item Bagaimana untuk menyelesaikan masalah ini?
Apabila menanyakan count(*), adakah semua jadual yang dikaitkan dengan gabungan kiri perlu dialih keluar? Adakah ini akan menyebabkan data yang dikembalikan menjadi tidak tepat?
Penjelasan tambahan: Saya merasakan bahawa semua orang telah salah faham apa yang saya maksudkan, sebenarnya, masalah saya terutamanya pada SQL, bukan mybatis, kerana selepas data yang saya pertanyaan dipetakan, tidak ada masalah sama sekali, ia hanya paging adalah masalah dengan jumlah rekod, mengakibatkan halaman muka surat yang salah
漂亮男人2017-06-10 09:51:39
Saya hanya menulis contoh dan mengujinya
`
Dua kelas entiti
Pengguna kelas awam {
private int id;
private String username; // 用户名
private List<Address> addresses;
Alamat kelas awam {
private int id;
private String detail; // 详细地址
private int user_id; // 所属用户
Fail pemetaan
<resultMap type="com.atguigu.mybatis.entity.User" id="userMap" autoMapping="true">
<result property="id" column="u_id"/>
<collection property="addresses" ofType="com.atguigu.mybatis.entity.Address" autoMapping="true">
<result property="id" column="a_id"/>
<result property="user_id" column="u_id"/>
</collection>
</resultMap>
<select id="select_all_user_address" resultMap="userMap" >
<!-- pilih tu.,ta., -->
<!-- ta.id sebagai 'a_id', -->
<!-- tu.id sebagai 'u_id' -->
<!-- daripada t_user tu , -->
<!-- t_address ta mana ta.user_id=tu.id -->
select tu.*,ta.*,
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
</select>
Hasil ujian
Saiz Senarai terkapsul<Pengguna> tiada masalah
欧阳克2017-06-10 09:51:39
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;
Anda berharap mahukan dua item, tetapi sql anda menjumpai tiga item, jadi ralat dipaparkan
Anda harus membahagikan logik:
Anda harus mengetahui pengguna yang anda mahukan dahulu
<select id="find" resultType="User" parameterType="map">
select *
from t_user tu
<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>
Kemudian dalam
<resultMap type="User" id="userMap" autoMapping="true">
<id property="id" column="u_id"/>
<collection " property="addresses" javaType= "ArrayList" column="u_id"
ofType="Address" select= "??" />
</resultMap>
??Ini kaedah menyemak Senarai<Alamat> menggunakan userId sendiri
欧阳克2017-06-10 09:51:39
Dalam kes ini, paging tidak boleh dilakukan seperti ini. Anda perlu menomborkan data jadual utama.
Pada asalnya, 100 keping data telah ditanya, tetapi kerana satu-ke-banyak akan melipat dan menyahduplikasi banyak data, hasil sebenar adalah kurang daripada 100 keping.
Dalam kes ini, pertanyaan bersarang boleh digunakan untuk menyelesaikan masalah, yang memerlukan pelaksanaan N+1 dan boleh dimuatkan dengan malas.
Atau lihat di sini: https://my.oschina.net/flags/...
Untuk kandungan MyBatis, sila layari: http://mybatis.tk
扔个三星炸死你2017-06-10 09:51:39
<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>
Ubah:
<select id="find_count" resultType="int" parameterType="map">
select count(*)
from t_user tu
<where>
<if test="name != null">
(username like #{name})
</if>
</where>
group by username
</select>
曾经蜡笔没有小新2017-06-10 09:51:39
Tiada masalah jika anda menggunakan subquery
select count(*) from (
// query 在这里即使关联100张表, 也不可能存在问题
)
Pengarang boleh melihat Mybatis-PageHelper
pelaksanaan penukaran sql count
Adalah disyorkan bahawa pengarang terus menggunakan Mybatis-PageHelper untuk melaksanakan paging