mybatis之一对多
今天主要话题围绕这么几个方面?
- mybatis一对多示例
- sql优化策略
一、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,namespace的值习惯上设置成包名+sql映射文件名,这样保证了namespace的值是唯一的-->
<mapper namespace="com.yc.mybatis.test.classMapper"> <!--
方式一:嵌套结果:使用嵌套结果映射来处理重复的联合结果的子集
封装联表查询的数据(去除重复的数据)
select * from class c, teacher t where c.teacher_id=t.t_id and c.c_id=
--> <select id="getClass" parameterType="int" resultMap="getClassMap">
select * from class c, teacher t where c.teacher_id = t.t_id and c.teacher_id=#{id}
</select> <!-- resultMap:映射实体类和字段之间的一一对应的关系 -->
<resultMap type="Classes" id="getClassMap">
<id property="id" column="c_id"/>
<result property="name" column="c_name"/>
<association property="teacher" javaType="Teacher">
<id property="id" column="t_id"/>
<result property="name" column="t_name"/>
</association>
</resultMap> <!--
方式二:嵌套查询:通过执行另外一个SQL映射语句来返回预期的复杂类型
SELECT * FROM class WHERE c_id=;
SELECT * FROM teacher WHERE t_id= //1 是上一个查询得到的teacher_id的值
property:别名(属性名) column:列名 -->
<!-- 把teacher的字段设置进去 -->
<select id="getClass1" parameterType="int" resultMap="getClassMap1">
select * from class where c_id=#{id}
</select> <resultMap type="Classes" id="getClassMap1">
<id property="id" column="c_id"/>
<result property="name" column="c_name"/>
<association property="teacher" column="teacher_id" select="getTeacher"/>
</resultMap>
<select id="getTeacher" parameterType="int" resultType="Teacher">
select t_id id,t_name name from teacher where t_id =#{id}
</select>
</mapper>
顺便对association标签的属性进行解释:
property:对象属性名称
javaType:对象属性类型
column:所对应的外键字段名称
一对多,以我博客为例,比如今天我写的一个近期评论的接口就是一个一对多的体现(一个评论者可以对应多篇文章,相反,多篇文章也能对应一个评论者,从中可以体现一对多,多对一,甚至多对多的关系)
关于一对一、一对多或者多对多,可以参考Mybatis 一对一,一对多,多对一,多对多的理解
话不多说,看xml代码:
<?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="com.blog.springboot.dao.CommentsDao"> <!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="com.blog.springboot.entity.Comments"> <id column="comment_ID" property="commentId" />
<result column="comment_post_ID" property="commentPostId" />
<result column="comment_author" property="commentAuthor" />
<result column="comment_author_email" property="commentAuthorEmail" />
<result column="comment_author_url" property="commentAuthorUrl" />
<result column="comment_author_IP" property="commentAuthorIp" />
<result column="comment_date" property="commentDate" />
<result column="comment_date_gmt" property="commentDateGmt" />
<result column="comment_content" property="commentContent" />
<result column="comment_karma" property="commentKarma" />
<result column="comment_approved" property="commentApproved" />
<result column="comment_agent" property="commentAgent" />
<result column="comment_type" property="commentType" />
<result column="comment_parent" property="commentParent" />
<result column="user_id" property="userId" /> <collection property="posts" ofType="Posts">
<result column="post_title" property="postTitle"/>
</collection> </resultMap> <!-- 通用查询结果列 -->
<sql id="Base_Column_List">
comment_ID AS commentId, comment_post_ID AS commentPostId, comment_author AS commentAuthor, comment_author_email AS commentAuthorEmail, comment_author_url AS commentAuthorUrl, comment_author_IP AS commentAuthorIp, comment_date AS commentDate, comment_date_gmt AS commentDateGmt, comment_content AS commentContent, comment_karma AS commentKarma, comment_approved AS commentApproved, comment_agent AS commentAgent, comment_type AS commentType, comment_parent AS commentParent, user_id AS userId
</sql> <select id="recentComments" resultMap="BaseResultMap">
SELECT comments.comment_author,posts.post_title FROM wp_comments AS comments LEFT JOIN wp_posts AS posts ON(comments.comment_post_ID=posts.ID) WHERE comments.comment_approved='' AND posts.post_status='publish' ORDER BY comments.comment_date_gmt DESC LIMIT ,
</select> </mapper>
相关属性我就不做多的解释,关于MyBatis相关的教程,除了参考官网之外,还可以参考我的博客系列文章,地址为:https://www.cnblogs.com/youcong/category/1144041.html
关于ofType还是要说的,如果你的mybatis-config.xml或者是springboot中的application.yml或application.properties没有配置对应的别名,那么请将类的完整路径填写上去,假定我没有做出相关的配置的话,那么我需要这么写 ofType=”com.blog.springboot.entity.Posts”。
collection的property要包含在com.blog.springboot.entity.Comments类里面
我贴出我的Comments类,大家可以做一个参考:
package com.blog.springboot.entity; import java.io.Serializable;
import java.util.Date;
import java.util.List; import com.baomidou.mybatisplus.activerecord.Model;
import com.baomidou.mybatisplus.annotations.TableField;
import com.baomidou.mybatisplus.annotations.TableId;
import com.baomidou.mybatisplus.annotations.TableName;
import com.baomidou.mybatisplus.enums.IdType; /**
* <p>
*
* </p>
*
* @author youcong
* @since 2019-02-12
*/
@TableName("wp_comments")
public class Comments extends Model<Comments> { private static final long serialVersionUID = 1L; @TableId(value = "comment_ID", type = IdType.AUTO)
private Long commentId;
@TableField("comment_post_ID")
private Long commentPostId;
@TableField("comment_author")
private String commentAuthor;
@TableField("comment_author_email")
private String commentAuthorEmail;
@TableField("comment_author_url")
private String commentAuthorUrl;
@TableField("comment_author_IP")
private String commentAuthorIp;
@TableField("comment_date")
private Date commentDate;
@TableField("comment_date_gmt")
private Date commentDateGmt;
@TableField("comment_content")
private String commentContent;
@TableField("comment_karma")
private Integer commentKarma;
@TableField("comment_approved")
private String commentApproved;
@TableField("comment_agent")
private String commentAgent;
@TableField("comment_type")
private String commentType;
@TableField("comment_parent")
private Long commentParent;
@TableField("user_id")
private Long userId; @TableField(exist=false)
private List<Posts> posts; public List<Posts> getPosts() {
return posts;
} public void setPosts(List<Posts> posts) {
this.posts = posts;
} public Long getCommentId() {
return commentId;
} public void setCommentId(Long commentId) {
this.commentId = commentId;
} public Long getCommentPostId() {
return commentPostId;
} public void setCommentPostId(Long commentPostId) {
this.commentPostId = commentPostId;
} public String getCommentAuthor() {
return commentAuthor;
} public void setCommentAuthor(String commentAuthor) {
this.commentAuthor = commentAuthor;
} public String getCommentAuthorEmail() {
return commentAuthorEmail;
} public void setCommentAuthorEmail(String commentAuthorEmail) {
this.commentAuthorEmail = commentAuthorEmail;
} public String getCommentAuthorUrl() {
return commentAuthorUrl;
} public void setCommentAuthorUrl(String commentAuthorUrl) {
this.commentAuthorUrl = commentAuthorUrl;
} public String getCommentAuthorIp() {
return commentAuthorIp;
} public void setCommentAuthorIp(String commentAuthorIp) {
this.commentAuthorIp = commentAuthorIp;
} public Date getCommentDate() {
return commentDate;
} public void setCommentDate(Date commentDate) {
this.commentDate = commentDate;
} public Date getCommentDateGmt() {
return commentDateGmt;
} public void setCommentDateGmt(Date commentDateGmt) {
this.commentDateGmt = commentDateGmt;
} public String getCommentContent() {
return commentContent;
} public void setCommentContent(String commentContent) {
this.commentContent = commentContent;
} public Integer getCommentKarma() {
return commentKarma;
} public void setCommentKarma(Integer commentKarma) {
this.commentKarma = commentKarma;
} public String getCommentApproved() {
return commentApproved;
} public void setCommentApproved(String commentApproved) {
this.commentApproved = commentApproved;
} public String getCommentAgent() {
return commentAgent;
} public void setCommentAgent(String commentAgent) {
this.commentAgent = commentAgent;
} public String getCommentType() {
return commentType;
} public void setCommentType(String commentType) {
this.commentType = commentType;
} public Long getCommentParent() {
return commentParent;
} public void setCommentParent(Long commentParent) {
this.commentParent = commentParent;
} public Long getUserId() {
return userId;
} public void setUserId(Long userId) {
this.userId = userId;
} @Override
protected Serializable pkVal() {
return this.commentId;
} @Override
public String toString() {
return "Comments{" +
", commentId=" + commentId +
", commentPostId=" + commentPostId +
", commentAuthor=" + commentAuthor +
", commentAuthorEmail=" + commentAuthorEmail +
", commentAuthorUrl=" + commentAuthorUrl +
", commentAuthorIp=" + commentAuthorIp +
", commentDate=" + commentDate +
", commentDateGmt=" + commentDateGmt +
", commentContent=" + commentContent +
", commentKarma=" + commentKarma +
", commentApproved=" + commentApproved +
", commentAgent=" + commentAgent +
", commentType=" + commentType +
", commentParent=" + commentParent +
", userId=" + userId +
"}";
}
}
也许大家发现我的mybatis与你们的mybatis不一样,实际上我用的是mybatis-plus,mybatis-plus可以说跟mybatis几乎没有什么区别,我多次强调过,mybatis-plus是mybatis的增强版,意味着mybatis原有的功能,mybatis-plus可以毫无顾忌的拿来即用。
关于mybatis-plus的学习教程,感兴趣的朋友可以参考我的这篇博客(包含从入门到使用):https://www.cnblogs.com/youcong/category/1213059.html
sql优化策略
sql优化的策略有很多,大家可以参考如下:
(1)任何地方都不要使用select from table_name,请使用具体的字段列表代替”“ ,不要返回用不到的任何字段;
(2)对查询进行优化,应尽量避免全表扫描,首先应考虑在where及order by涉及的列建立索引;
(3)应尽量避免在where子句中使用or来连接条件,否则将导致引擎放弃使用索引而进行全表扫描;
(4)应尽量避免在where子句中使用!=或<>操作符,否则将导致引擎放弃使用索引而进行全表扫描;
(5)int和not in慎用,否则会导致全表扫描;
(6)应尽量避免在where子句中对字段进行表达式操作,这将导致引擎放弃使用索引而进行全表扫描;
(7)很多时候使用exists代替in是一个好的选择;
(8)尽量使用数字型字段,若只含数值信息的字段设计为字符型,这将会降低查询和连接的性能,并会增加存储开销,这是因为引擎在处理查询和连接时会逐个比较字符串职工的每一个字符,而对于数字型而言只需要比较一次就够了;
(9)尽可能使用varchar代替char,因为首先变长字段存储空间小,可以节省存储空间,其次对于查询来说,在一个相对较小的字段内搜索效率显然要高些;
当然远远不止这么多,知识的海洋是无穷的,探索的乐趣亦如此。
关于sql优化思路,大家可以参考SQL优化思路大全
mybatis之一对多的更多相关文章
- mybatis的一对多,多对一,以及多对对的配置和使用
1.本文章是无意中看见易百教程的Mybatis教程才注意到这个问题,平时都仅仅是在用CRUD,忽略了这方面的问题,真实十分羞愧 2.首先我们开始对mybatis的一对多的探究 根据这个应用场景 ...
- Mybatis配置一对多的关联关系(五)
问题:是查询一个部门中的员工? 一.web项目构架 二.lib文件的jar 三.配置大小配置和该工具类 1大配置mybatis-config.xml <?xml version="1. ...
- Mybatis学习——一对多关联表查询
1.实体类 public class Student { private int id; private String name; } public class Classes { private i ...
- Mybatis 中一对多,多对一的配置
现在有很多电商平台,就拿这个来说吧.顾客跟订单的关系,一个顾客可以有多张订单,但是一个订单只能对应一个顾客. 一对多的顾客 <?xml version="1.0" encod ...
- Mybatis【一对多、多对一、多对多】知识要点
Mybatis[多表连接] 我们在学习Hibernate的时候,如果表涉及到两张的话,那么我们是在映射文件中使用<set>..<many-to-one>等标签将其的映射属性关联 ...
- mybatis进行一对多时发现的问题总结
1.定义一对多xml文件时,所有的resultMap中的column的值一定不要重复,否则mybatis会发生错误,如果有重名,定义别名,column中的名字一定要与查询出的名字一致,如: 52行的别 ...
- mybatis 中一对多、多对一、多对多、父子继承关系
mybatis 中处理一对多.多对一.多对多.父子继承关系的有关键词:association .collection .discriminator id – 一个 ID 结果:标记出作为 ID 的结果 ...
- MyBatis:一对多关联查询
MyBatis从入门到放弃四:一对多关联查询 前言 上篇学习了一对一关联查询,这篇我们学习一对多关联查询.一对多关联查询关键点则依然是配置resultMap,在resultMap中配置collecti ...
- mybatis实现一对多连接查询
问题:两个对象User和Score,它们之间的关系为一对多. 底层数据库为postgresql,ORM框架为mybatis. 关键代码如下: mybatis配置文件如下: mybatis.xml文件内 ...
随机推荐
- react-conponent-hellocynthia
<!DOCTYPE html> <html> <head> <script src="../../build/react.js">& ...
- BZOJ1101: [POI2007]Zap(莫比乌斯反演)
1101: [POI2007]Zap Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 2951 Solved: 1293[Submit][Status ...
- 2018-06-21 中文代码示例视频演示Python入门教程第五章 数据结构
知乎原链 续前作: 中文代码示例视频演示Python入门教程第四章 控制流 对应在线文档: 5. Data Structures 这一章起初还是采取了尽量与原例程相近的汉化方式, 但有些语义较偏(如T ...
- loadrunner 脚本优化-检查点设置
脚本优化-检查点设置 by:授客 QQ:1033553122 VuGen判断脚本是否执行成功是根据服务器返回的状态来确定的,如果服务器返回的是HTTP状态为200 OK,那么VuGen就认为脚本正确地 ...
- SpringBoot集成Swagger接口管理工具
手写Api文档的几个痛点: 文档需要更新的时候,需要再次发送一份给前端,也就是文档更新交流不及时. 接口返回结果不明确 不能直接在线测试接口,通常需要使用工具,比如postman 接口文档太多,不好管 ...
- Bullet3的一些理解
Bullet3应该是第三大物理引擎了,拥有宽松的授权方式,开源.在我的项目中将采用它. 碰撞世界(btCollisionWorld)是最基本的环境类. 动态世界(btDynamicsWorld)从碰撞 ...
- 《高性能JavaScript》--读书笔记
第一章 加载和运行 延迟脚本 defer 该属性表明脚本在执行期间不会影响到页面的构造,脚本会先下载但被延迟到整个页面都解析完毕后再运行.只适用于外部脚本 <script src="j ...
- oracle中print_table存储过程介绍
一直以来,觉得MySQL中使用\G参数改变输出结果集的显示方式非常好用,尤其是在命令行界面.但是ORACLE数据库没有这个功能,今天在搜索到Tom大师的一篇博文时,发现大师用一个存储过程print_t ...
- Greenplum启动失败Error occurred: non-zero rc: 1的修复
某日开发反馈测试环境的集群启动失败 报错内容如下: [gpadmin@hadoop-test2:/root]$ gpstart :::: gpstart:hadoop-test2:gpadmin-[I ...
- Android ConstraintLayout 布局警告
使用 ConstraintLayout 布局出现警告: 此视图不受垂直约束.在运行时,除非添加垂直约束,否则它将跳转到左侧 解决办法: 从Android Studio v3及更高版本开始,从下拉列表中 ...