java - masalah halaman berkaitan berbilang jadual pangkalan data Mybatis
黄舟
黄舟 2017-06-10 09:49:39
0
6
1505

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

黄舟
黄舟

人生最曼妙的风景,竟是内心的淡定与从容!

membalas semua(6)
漂亮男人

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

左手右手慢动作

Kumpulkan kata kunci mengikut dan semak sendiri operasi khusus

学霸
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

学霸

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

扔个三星炸死你
<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> 
曾经蜡笔没有小新

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

Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan
Tentang kita Penafian Sitemap
Laman web PHP Cina:Latihan PHP dalam talian kebajikan awam,Bantu pelajar PHP berkembang dengan cepat!