iBATIS多表查询之N+1 Select

简介:


1 数据表

book,user表。一对多关系,一本书有多个作者。

CREATE TABLE book (
  oid int(10) NOT NULL ,
  name varchar(50) DEFAULT NULL,
  PRIMARY KEY (oid)
);

CREATE TABLE user (
  id int(10) unsigned NOT NULL,
  name varchar(50) DEFAULT NULL,
  book_oid int(10) DEFAULT NULL,
  PRIMARY KEY (id),
  KEY FK_user_1 (book_oid),
  CONSTRAINT FK_user_1 FOREIGN KEY (book_oid) REFERENCES book (oid)
);


2 Pojo类(getter,setter均省略)

package com.pojo;

public class User
{
 private Integer id;
 private String name;
 private Integer book_oid;
}


package com.pojo;
import java.util.List;
public class Book
{
 private Integer oid;
 private String name;
 private List users;
}

必须定义个list ,ibatis在实现多表关联查询时。


3 配置文件

对应pojo的book.xml

<sqlMap namespace="test"> 
  <typeAlias alias="User" type="com.pojo.User"/> 
  <typeAlias alias="Book" type="com.pojo.Book"/> 

  <resultMap id="BookResult" class="Book"> 
   <result property="oid" column="oid"/> 
   <result property="name" column="name"/> 
   <result property="users" column="oid" select="getUsersByBookId"/> 
  </resultMap>
 
  <select id="selectAllBooks" resultMap="BookResult"> 
   <![CDATA[ 
   select oid,b.name from book b
   ]]> 
  </select> 
  
  <select id="getUsersByBookId" parameterClass="int" resultClass="User"> 
   <![CDATA[ 
   select id,book_oid,u.name from user u where book_oid = #value# 
   ]]> 
  </select>
</sqlMap> 

通过book的oid实现的一对多关联,ibatis会使用getKeysByLockId(id)得到的List填充users属性

 

4 测试类

package com.test;
import java.io.IOException;
import java.io.Reader;
import java.util.Iterator;
import java.util.List;
import com.crfss.MainDb;
import com.crfss.Un;
import com.ibatis.common.resources.Resources;
import com.ibatis.sqlmap.client.SqlMapClient;
import com.ibatis.sqlmap.client.SqlMapClientBuilder;
import com.pojo.Book;
import com.pojo.User;


public class TestDB {

 public static void main(String[] args) {
        String resource = "sql-map-config.xml";
        try {
            Reader reader = Resources.getResourceAsReader(resource);
            SqlMapClient mapClient = SqlMapClientBuilder.buildSqlMapClient(reader);
            reader.close();
            List<Book> books=mapClient.queryForList("selectAllBooks");
            Book book=(Book)books.get(0);
            List users=(List) book.getUsers();
      
           for (Iterator iterator = users.iterator(); iterator.hasNext();) {
            User user = (User) iterator.next();
            System.out.println(user.getBook_oid());
            System.out.println(user.getName());
            System.out.println(user.getId());
        }  
        catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

5 总结

这就叫 N+1 Select。因为每查一次book,就要调用两次sql语句(一次查book,一次查user)。实际应用中要避免。

我们可以用dto的形式,避免了对象中间套对象。还可以有其它一些方法,大家上网查阅。

 

 

原帖地址:http://blog.sina.com.cn/s/blog_6b30a46b0100qgi5.html

 

 

 

 

目录
相关文章
|
7月前
|
SQL 数据库
SQL 查询优化指南:SELECT、SELECT DISTINCT、WHERE 和 ORDER BY
SQL的SELECT语句用于从数据库中选择数据。SELECT语句的基本语法如下:
112 1
|
7月前
|
SQL 关系型数据库 MySQL
六、SQL多表查询
六、SQL多表查询
64 0
|
7月前
|
SQL 缓存
IBATIS别名SELECT(缓存字段)引起的问题(动态sql)
IBATIS别名SELECT(缓存字段)引起的问题(动态sql)
|
7月前
|
SQL
SQL语句多表查询练习
SQL语句多表查询练习
35 0
|
7月前
SQL-分组查询
SQL-分组查询
|
7月前
|
SQL
四、SQL分组查询
四、SQL分组查询
88 0
|
SQL 关系型数据库 Serverless
深入理解 SQL 分组查询
SQL 是结构化查询语言(Structured Query Language)的缩写,是用于管理关系型数据库的标准语言。在 SQL 中,查询是其中最重要的部分之一,通过查询,我们可以从数据库中检索所需的数据。分组查询是 SQL 查询中的一项重要功能,它允许我们对数据进行分组、聚合和汇总,以便更好地理解数据的特征和趋势。 在本文中,我们将深入探讨 SQL 中的分组查询,包括其基本语法、常用聚合函数、分组筛选条件、多重分组、分组排序等方面的内容。无论您是初学者还是有一定 SQL 基础的开发者,都将从本文中获得有关 SQL 分组查询的详细信息。
695 0
|
SQL JSON Java
JPA的EntityManager来实现SQL或者HQL语句查询
JPA的EntityManager来实现SQL或者HQL语句查询
160 0
|
SQL Java 数据格式
结合mybatis-plus 实现个简单的不需要写sql 的多表查询
项目地址 multipleselect java mybatis 多表查询 简介 实现简单的实体类操作多表, 首先你的项目是使用了mybatis-plus 才可以使用 设计说明 如何关联表? 找第一张表注解为 TableId (mybatis-plus 注解)的属性名, 到每二张表找同样的属性名, 如果没找到,反过来找,如果还没找到,挨个属性找。
|
SQL 程序员 数据库
SQL的几种连接查询
SQL的几种连接查询
170 0
SQL的几种连接查询