当前位置: 首页 > news >正文

卖花网站源码长沙专业网站设计平台

卖花网站源码,长沙专业网站设计平台,网站策划做啥,wordpress 春菜文章目录 问题简述场景描述问题描述问题原因解决办法 问题简述 笔者在使用 MyBatis 进行一对多查询的时候遇到一个奇怪的问题。对于笔者的一对多的查询结果,出现了这样的一个现象:原来每个组里有多个元素,查询目标是查询所查的组,…

文章目录

  • 问题简述
  • 场景描述
  • 问题描述
  • 问题原因
  • 解决办法

问题简述

  笔者在使用 MyBatis 进行一对多查询的时候遇到一个奇怪的问题。对于笔者的一对多的查询结果,出现了这样的一个现象:原来每个组里有多个元素,查询目标是查询所查的组,以及每个组中的元素。但查询的结果却是变成了这样:每组元素变得只有一个,且总组数与元素数总数相等。举个例子,假设一共有 3 个组,每组 4 个元素。而现在的查询结果却是,显示出了 12 个组,每组 1 个元素。

场景描述

  笔者原来的表的情况比这要复杂很多,这里为了便于说明,简单抽象出这样一个情景。数据库中有很多用户(User),每个用户有他的好友分组(Folder),每个分组下面有该用户的好友(Contact)。现在需要查找这个用户所有的分组及好友,返回的数据结构需要是一个一个 List 分组,且一个分组中包含一个 List 好友。(List 指的是 Java 的一个内置的数据结构。)

  • User 表建表示例代码如下:

    CREATE TABLE User (id VARCHAR(64) NOT NULL,name VARCHAR(64) NOT NULL,# ...为了简化说明,此表省略其它字段...PRIMARY KEY (id)
    );
  • Folder 表建表示例代码如下:

    CREATE TABLE Folder (id VARCHAR(64) NOT NULL,userId VARCHAR(64) NOT NULL,name VARCHAR(64) NOT NULL,# ...为了简化说明,此表省略其它字段...PRIMARY KEY (userId, id),# 因为上面的是复合主键,所以自动创建的是联合索引,而其它表的外键引用需要的是单个索引INDEX idIndex (id),FOREIGN KEY (userId) REFERENCES User (id)
    );
  • Contact 表建表示例代码如下:

    CREATE TABLE Contact (id VARCHAR(64) NOT NULL,# 表示此联系人属于谁的好友userId VARCHAR(64) NOT NULL,# 表示此联系人对应 User 中的 idlinkedUserId VARCHAR(64) NOT NULL,folderId VARCHAR(64) NOT NULL,# ...为了简化说明,此表省略其它字段...PRIMARY KEY (userId, id),# 因为上面的是复合主键,所以自动创建的是联合索引,而其它表的外键引用需要的是单个索引INDEX idIndex (id),# 同一个用户,不能拥有两个相同 ID 的 ContactUNIQUE (userId, linkedUserId),# 当复合主键成为外键时,必须整个复合主键一起作为外键,不能只引用复合主键其中的某个属性FOREIGN KEY (userId) REFERENCES Folder (userId),FOREIGN KEY (folderId) REFERENCES Folder (id),FOREIGN KEY (linkedUserId) REFERENCES User (id)
    );
    
  • 建表示意图如下:

    在这里插入图片描述

    在这里插入图片描述

  • 查询之后的 Java 数据结构如下:

    @Getter
    @Setter
    @ToString
    @NoArgsConstructor
    @AllArgsConstructor
    @EqualsAndHashCode(callSuper = false)
    @Accessors(chain = true)
    public class FolderWithContacts {private Folder folder;private List<Contact> contacts;
    }
    

    其中,

    @Setter
    @Getter
    @ToString
    @NoArgsConstructor
    @AllArgsConstructor
    @EqualsAndHashCode(callSuper = false)
    @Accessors(chain = true)
    public class Folder {private String id;private String userId;private String name;
    }
    
    @Setter
    @Getter
    @ToString
    @NoArgsConstructor
    @AllArgsConstructor
    @EqualsAndHashCode(callSuper = false)
    @Accessors(chain = true)
    public class Contact {private String id;private String userId;private String linkedUserId;private String folderId;
    }
    
  • DAO 类代码如下:

    public interface ContactDao {List<FolderWithContacts> getFolderWithContacts(String userId);
    }
    
    <?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="XXX.xxx.ContactDao"><resultMap id="folderResultMap" type="XXX.xxx.Folder"><!-- property 指的是 Java 的字段名,column 指的是 SQL 的属性名 --><id property="id" column="folder_id"/><id property="userId" column="folder_user_id"/><result property="name" column="folder_name"/></resultMap><resultMap id="contactResultMap" type="XXX.xxx.Contact"><id property="id" column="contact_id"/><id property="userId" column="contact_user_id"/><result property="folderId" column="contact_folder_id"/><result property="name" column="contact_name"/></resultMap><resultMap id="folderWithContactsResultMap" type="XXX.xxx.FolderWithContacts"><!-- association 表示这是一个普通 Java 对象,而不是 Java 内置类型 --><association property="folder" resultMap="folderResultMap"/><!-- collection 表示这是一个 Java 集合。javaType 指的是 Java 集合的类型 --><collection property="contacts" javaType="java.util.ArrayList" resultMap="contactResultMap"/></resultMap><select id="getFolderWithContacts" resultMap="folderWithContactsResultMap">SELECT Folder.id           AS folder_id,Folder.userId       AS folder_user_id,Folder.name         AS folder_name,Folder.sequence     AS folder_sequence,Contact.id          AS contact_id,Contact.userId      AS contact_user_id,Contact.folderId    AS contact_folder_id,Contact.name        AS contact_name,Contact.description AS contact_descriptionFROM Contact,FolderWHERE Contact.folderId = Folder.idAND Contact.userId = #{userId}AND Folder.userId = #{userId}ORDER BY folder_sequence ASC</select></mapper>
    

问题描述

  以上就是笔者用于某个用户的好友分组及每个分组下的好友的示例代码。但使用上面的代码的查询会出现问题。如果一个用户有 3 个好友,每组 4 个好友,则上述代码的查询结果会变成,该用户有 12 个好友分组,每个分组 1 个好友。而且,上面的整个查询过程在运行中都是正常的,不会发生报错。而且返回结果的每个字段都没有出现 null 值。

  可以看出,上面的代码会导致无法区分好友与分组,把好友当成分组返回了。

问题原因

  是什么原因出现上述问题呢?由于上面的整个查询过程都没有发生报错,且返回数据没有 null 值。因此不会是笔者的语法编写出现问题。

  于是,笔者将上面的 SQL 单独在 MySQL 客户端命令行运行了一下,运行输出是正常的,确实是一个一对多查询的输出。一个一对多查询的输出,输出结果的数量应该和元素总个数相等,且同一个分组的所有元素关于这个分组的属性列的值应该也都是相等的

  这就说明并不是笔者 SQL 代码的问题,所以问题出现在 MyBatis 对 MySQL 输出结果的解析上。笔者非常确定,MyBatis 是肯定支持一对多查询的,因此一定是笔者关于 MyBatis 的 mapper 文件的编写出现问题。

  笔者之后在不断地建新的更基本的表,进行一对多查询,终于让笔者发现了问题所在。

  MyBatis 对于多表查询,要求组元素的字段必须是基本类型,而笔者编程时非常喜欢隔离、封装、解耦,擅自在上面将组元素的字段封装成了一个单独的类,然后把这个类的对象作为组元素的字段。在这种情况下,虽然 MyBatis 注入数据没有出问题,但它却没能识别出这是一对多查询的数据,因此将其当成一对一的数据来注入了。

  可以看出,笔者在上面使用了 <association.../> 来映射一个 Java 对象,因此引发了上述问题。

解决办法

  知道原因就好办了。可以直接将上面类 Folder 的字段合并在类 FolderWithContacts,然后去掉类 Folder。

  改进后的相关代码如下:

@Getter
@Setter
@ToString
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
public class FolderWithContacts {private String id;private String userId;private String name;private List<Contact> contacts;
}
<?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="XXX.xxx.ContactDao"><resultMap id="contactResultMap" type="XXX.xxx.Contact"><id property="id" column="contact_id"/><id property="userId" column="contact_user_id"/><result property="folderId" column="contact_folder_id"/><result property="name" column="contact_name"/></resultMap><resultMap id="folderWithContactsResultMap" type="XXX.xxx.FolderWithContacts"><id property="id" column="folder_id"/><id property="userId" column="folder_user_id"/><result property="name" column="folder_name"/><!-- collection 表示这是一个 Java 集合。javaType 指的是 Java 集合的类型 --><collection property="contacts" javaType="java.util.ArrayList" resultMap="contactResultMap"/></resultMap><select id="getFolderWithContacts" resultMap="folderWithContactsResultMap">SELECT Folder.id           AS folder_id,Folder.userId       AS folder_user_id,Folder.name         AS folder_name,Folder.sequence     AS folder_sequence,Contact.id          AS contact_id,Contact.userId      AS contact_user_id,Contact.folderId    AS contact_folder_id,Contact.name        AS contact_name,Contact.description AS contact_descriptionFROM Contact,FolderWHERE Contact.folderId = Folder.idAND Contact.userId = #{userId}AND Folder.userId = #{userId}ORDER BY folder_sequence ASC</select></mapper>

  现在,这段代码运行起来,查询到的数据就是正常的了。

http://www.yayakq.cn/news/632835/

相关文章:

  • 食品科技学校网站模板赣县区建设局网站
  • 免费php外贸网站模板免费 网站 如何做
  • 邢台网站建设网站做招聘图片的网站
  • 安康市城市建设局网站东莞微信网站建设更好
  • 家具网站首页设计网页视频下载不了怎么办
  • 站长网站提交wordpress网站聊天插件
  • 做百度推广需要有网站吗公司网站制作风格
  • 备案号注销了 新网站怎么备案群晖 卸载wordpress
  • 丹徒网站建设信息wordpress淘客采集
  • 建设网站需要学习什么语言河南省网站制作公司
  • 公司网站建设开发济南兴田德润优惠吗工商企业年报查询入口
  • 黄页营销网站视频免费大全网站广告基本防护怎么做
  • 无极磁铁网站酒店管理专业建设规划
  • 安徽品质网站建设创新网站备案登陆用户名是什么
  • 东莞网站建设免费服务器昆明网站建设要多少钱
  • 品牌网站推广软件做ppt的模板的网站有哪些
  • 广州建站优化公司没有网站做推广
  • 自己做网站优化wordpress rss 采集
  • 找公司做网站注意什么个人电子商务网站建设
  • 沈阳高端网站建设公司沈阳建设工程管理中心
  • 天津建设网站需要的费用房地产管理系统
  • 常州网站建设公司平台网站开发如何设置视频教程
  • 网站的内容策略做网站dw
  • 手机商城网站建设网站安全怎么做
  • 网站ui设计是什么电话销售做网站打官司
  • 手机网站定制咨询网站备案 登录名
  • 网站建设营销排名方案poedit wordpress
  • 做标书经验分享网站南宁网站排名优化公司
  • 企业网站布局960关键词优化快速排名
  • 江南大学做网站商务网站开发的基本流程