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文件内 ...
随机推荐
- babel在项目里的使用
1.手动在项目里创建文件 .babelrc 2.安装 $ npm install --save-dev babel-cli # ES2015转码规则 $ npm install --save-dev ...
- angular ng-file-upload
传送门:https://github.com/danialfarid/ng-file-upload#install <script src="angular(.min).js" ...
- es6 语法 (模块化)
//export export let A=123; //导出 //导出函数 export function test(){ console.log('test'); } //导出类 export c ...
- JavaScript之Number、String、Array常用属性与方法手册
Number isFinite函数 Number.isFinite() 方法用来检测传入的参数是否是一个有穷数(finite number). 语法: Number.isFinite(value) 例 ...
- 求二叉树第n层节点数
在知乎看到今日头条的一个面试题“求二叉树第n层节点数”:https://zhuanlan.zhihu.com/p/25671699,想到了这样一个解法,欢迎大家交流 我的解法采用递归的思想,从0层开始 ...
- power designer的安装
PowerDesigner的安装 原由:新学期要开概要设计(软件设计与体系结构)这门课,老师推荐了两个CASE工具. Rational Rose Power Designer 本来想找rose的资源, ...
- (后端)mybatis 模糊查询 mapper.xml的写法(转)
原文地址:https://blog.csdn.net/sc6231565/article/details/46412765 1. sql中字符串拼接 SELECT * FROM tableName W ...
- 实现wc部分功能 java
GitHub地址:https://github.com/carlylewen/ruangong 相关要求 基本功能 wc.exe -c file.c //返回文件 file.c 的字符数(实现 ...
- Spark操作parquet文件
package code.parquet import java.net.URI import org.apache.hadoop.conf.Configuration import org.apac ...
- mssql sqlserver 可以存储二进制数据的字段类型详解
转自: http://www.maomao365.com/?p=6738 摘要: 下文将从数据库的数据类型着手,剖析在sqlserver数据库中可以存储二进制数据的数据类型,如下所示: mssql s ...