Rumah  >  Soal Jawab  >  teks badan

java - masalah halaman berkaitan berbilang jadual pangkalan data Mybatis

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

黄舟黄舟2660 hari yang lalu1463

membalas semua(6)saya akan balas

  • 漂亮男人

    漂亮男人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

    balas
    0
  • ringa_lee

    ringa_lee2017-06-10 09:51:39

    Kumpulkan kata kunci mengikut dan semak sendiri operasi khusus

    balas
    0
  • 欧阳克

    欧阳克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

    balas
    0
  • 欧阳克

    欧阳克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

    balas
    0
  • 扔个三星炸死你

    扔个三星炸死你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> 
    

    balas
    0
  • 曾经蜡笔没有小新

    曾经蜡笔没有小新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

    balas
    0
  • Batalbalas