MyBatis-Plus不写任何resultMap和SQL执行一对一、一对多、多对多关联查询

这篇具有很好参考价值的文章主要介绍了MyBatis-Plus不写任何resultMap和SQL执行一对一、一对多、多对多关联查询。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

MyBatis-Plus不写任何resultMap和SQL执行一对一、一对多、多对多关联查询

MyBatis-Plus不写任何resultMap和SQL执行一对一、一对多、多对多关联查询

com.github.dreamyoung mprelation 0.0.3.2-RELEASE

注解工具使用优缺点:

优点:

使用简单,通过在实体类上添加@OneToOne / @OneToMany / @ManyToOne / @ManyToMany 等注解即可。

注解命名参考了Hibernate命名,如果使用过Hibernate则即刻可上手。

1对1、1对多、多对1、多对多映射时,可以不再写SQL及XML配置文件,免去配置冗长的的麻烦。

Service层及Mapper层不需要再添加 getLinkById 、 selectLinkById 之类的方法来关联映射

重写过的ServiceImpl各种内置的查询方法都自动关联查询,非内置方法可以调用autoMapper相关方法进行自动或手动关联

所有执行采用非join方式查询,同时解决关联处理的1+n问题

1
2
3
4
5
6
7
8
9
10
11

缺点:

目前只针对SqlSession/Mappe形式有效(ActiveRecord形式暂未涉及修改,也没有测试)

非事务下, 1个连接(1个SqlSession)只执行一条SQL,而自动获取每个关联属性的sql都会创建12个SqlSession(并执行12条SQL)。如果需要使用非内置方法(即除ServiceImpl外的方法),必须配置只读事务来减少SqlSession创建。

如果有多个延迟加载的关联属性,类上可注解@AutoLazy(false)或没有标注该注解(默认),之后通过initialize方法在事务范围内的一个SqlSession中同时加载需要的多个延迟加载的属性。

1
2
3
4
5

使用注意点:

非ServiceImpl内置的业务查询,配置事务管理,减少SqlSession的创建。

实体上可用注解@AutoLazy(true/false)来标注是否自动触发延迟加载,该注解只针对需要延迟的属性。

       ★  true或无值的话,则获取延迟的关联属性时自动关联。但每一个延迟属性的获取都消耗一个SqlSession。适合于只有一个延迟属性的情况。

       ★  false或者不标注该注解的话,需要手动通过initialize()方法对延迟的关联属性进行获取,否则不会自动关联获取,此时关联为空。适合于有多个延迟属性的情况。

如果可以,不使用延迟加载(延迟加载的使用是在SqlSession关闭后执行的,需要重新创建SqlSession)。

如果确实需要延迟加载,可使用ServiceImpl 或 AutoMapper 相关的initialize方法一次性加载所有需要的被延迟的属性(只需要创建额外的一个SqlSession,毕竟SqlSession之前已经关闭)

1
2
3
4
5
6
7
8
9
10
11

注解使用:

一对多(多对一) :

Company实体类中配置:

复制代码
@Data
public class Company {
@TableId(value = “company_id”)
private Long id;
private String name;

//一对多
@TableField(exist = false)
@OneToMany //一对多默认为延迟加载,即@Lazy/@Lazy(true)/或此时不标注
@JoinColumn(name=“company_id”,referencedColumnName = “company_id”)//@TableId与一方相关属性中@TableField名称保持一致时@JoinColumn可省略
private Set employees;

1
2
3
4
5

}

Man实体类中配置:

@Data
public class Man {

@TableId(value = “man_id”)
private Long id;
private String name;

//多对一
@TableField(“company_id”)
private Long companyId;

@TableField(exist = false)
@ManyToOne //多对一默认为立即加载,即@Lazy(false)或此时不标注
@JoinColumn(name = “company_id”, referencedColumnName = “company_id”) //相关的@TableField与多方的@TableId名称一致时@JoinColumn可省略
private Company company;

1
2
3
4
5
6
7
8
9
10
11
12

}

一对多(多对一)表结构: company: (compnay_id, name) man: (man_id, name, company_id)

一对一:

Woman实体类配置:

@Data
public class Woman {
@TableId(value = “woman_id”)
private Long id;
private String name;

//一对一
@TableField(“lao_gong_id”)
private Long laoGongId;

@TableField(exist = false)
@OneToOne //一对一默认为立即加载,即@Lazy(false)或此时不标注
@JoinColumn(name = “lao_gong_id”, referencedColumnName = “man_id”)
private Man laoGong;

1
2
3
4
5
6
7
8

}

Man实体类配置:

@Data
public class Man {
@TableId(value = “man_id”)
private Long id;
private String name;

//一对一
@TableField(“lao_po_id”)
private Long laoPoId;

@TableField(exist = false)
@OneToOne
@JoinColumn(name = “lao_po_id”, referencedColumnName = “woman_id”)
private Woman laoPo;

1
2
3
4
5
6
7
8

}

一对一表结构:(实际可以减少一方) woman: (woman_id, name, lao_gong_id) man: (man_id, name, lao_po_id)

多对多:

Course实体类配置:

@Data
public class Course {
@TableId(value = “course_id”)
private Long id;
private String name;

//多对多
@TableField(exist = false)
@ManyToMany //多对多默认为延迟加载,即@Lazy(true)或此时不标注
@JoinTable(targetMapper = StudentCourseMapper.class) //第三方命名为StudentCourseMapper或CourseStudentMapper时@JoinTable注解一般可省略
@JoinColumn(name = “course_id”, referencedColumnName = “course_id”)
@InverseJoinColumn(name = “child_id”, referencedColumnName = “student_id”)
private List students;

1
2
3
4
5
6
7

}

Child实体类配置:

@Data
public class Child {
@TableId(“child_id”)
private Long id;
private String name;

//多对多
@TableField(exist = false)
@ManyToMany
@JoinTable(targetMapper=StudentCourseMapper.class)
@JoinColumn(name = “child_id”, referencedColumnName = “student_id”)
@InverseJoinColumn(name = “course_id”, referencedColumnName = “course_id”)
private List courses;

1
2
3
4
5
6
7

}

StudenCourse中间类(多对多必须要有,如果命名为StudentCourse或CourseStudent,则上边的@JoinTable可省略):

@Data
public class StudentCourse {
//可以有也可以无此ID
private Long id;

@TableField(“student_id”)
private Long studentId;

@TableField(“course_id”)
private Long courseId;

1
2
3
4
5

}

多对多表结构:course: (course_id, name) child: (child_id, name) student_course:(id, student_id, course_id)

mprelation 关联查询,使用过程:

POM中引入mprelation:

com.github.dreamyoung mprelation 0.0.3.2-RELEASE

配置 AutoMapper (只要是扫描被注解的实体类)

@Configuration
public class AutoMapperConfig {
@Bean
public AutoMapper autoMapper() {
return new AutoMapper(new String[] { “demo.entity”,“demo.bean” }); //配置实体类所在目录(可多个,暂时不支持通过符*号配置)
}
}

在实体类中配置注解(更多的注解配置见上边注解部分,这里只列出其中一个)

@Data
@AutoLazy //不需要手动触发加载延迟属性,当延迟属性被调用时自动创建Session进行获取。可见如果有多个延迟属性需要被使用时,会造成多次创建Session,此时可以标注为AutoLazy(false)或不标注,然后采用initialze方法手动一次性加载需要的属性
public class Man {
@TableId(value = “man_id”)
private Long id;
private String name;

private Long laoPoId;

@TableField(exist = false)
@OneToOne
@JoinColumn(name = “lao_po_id”, referencedColumnName = “woman_id”)
private Woman laoPo;

@TableField(“company_id”)
private Long companyId;

@TableField(exist = false)
@ManyToOne
@JoinColumn(name = “company_id”, referencedColumnName = “company_id”)
private Company company;

@TableField(exist = false)
@OneToMany
@JoinColumn(name = “man_id”, referencedColumnName = “lao_han_id”)
@Lazy(false)
private List waWa;

@TableField(exist = false)
@OneToMany
@JoinColumn(name = “man_id”, referencedColumnName = “man_id”)
@Lazy(false)
private Set tels;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

}

在Service层、Mapper层的使用,见下面:

以下是基于Mybatis-Plus官方示例修改而来的测试程序:

通过继承工具类重写过的IService / ServiceImpl 会自动执行关联映射, 无须再写gettLinkById之类的方法(可以使得各实现类没有任何方法):

mapper接口:

public interface ManMapper extends BaseMapper {}
service接口:

public interface IManService extends IService {} // IService为重写过的同名接口
Service实现:

@Service
public class ManServiceImpl extends ServiceImpl<ManMapper, Man> implements IManService {} // ServiceImpl为重写过的同名接口

测试调用:

public class ServiceTest {
@Autowired
ManService manService;

@Test
public void t_man_serviceImpl() {
Man man = manService.getById(1); // 原Mybatis-Plus的ServiceImpl的各种查询,被重写过后,都可以自动关联,
System.out.println(man);
}

1
2
3
4
5

}

结果输出:

Man(
id=1,
name=程序猿小明,
laoPoId=1,
laoPo=Woman(id=1, name=程序猿小明老婆, laoGongId=1, laoGong=null, waWa=null),
companyId=1,
company=Company(id=1, name=百度, employees=null),
waWa=[
Child(id=1,name=xxx1,lao_han_id=null, laoHan=null, lao_ma_id=null, laoMa=null, courses=null),
Child(id=2,name=xxxx2, lao_han_id=null, laoHan=null, lao_ma_id=null, laoMa=null, courses=null)
],
tels=[
Tel(id=1, tel=139xxxxxx, manId=1, laoHan=null),
Tel(id=4, tel=159xxxxxx, manId=1, laoHan=null),
Tel(id=2, tel=137xxxxxx, manId=1, laoHan=null)
]
)

如需需要对其关联属性对象的关联属性进行自动加载,可以继续使用AutoMapper对象的mapperEntity、mapperEntityList、mapperEntitySet、mapperEntityPage来操作:

比如想获取(填充)waWas 的关联,则:

List waWas=man.getWaWas();
autoMapper.mapperEntityList(waWas);

AutoMapper类中的几个常用方法说明:

mapperEntity(entity)                                            可以对一个实体类,实现自动关联。

mapperEntityList(entity_list) 可以对一个实体类List,实现自动关联。

mapperEntitySet(entity_set) 可以对一个实体类Set,实现自动关联。

mapperEntityCollection(entity_list_or_set) 可以对一个实体类Set或List,实现自动关联。

mapperEntityPage(entity_page) 可以对一个实体类Page,实现自动关联。

mapper(entity_entityListOrSet_entityPage) 统一上边的各种方法,直接对实体类,列表,分页都可以实现自动关联。

initialize(entity/entityList/entitySet/entityPage, OneOrMoreLazyPropertyName …)

可以对一个实体类/实体类List/实体类Set/实体类Page,在事务范围内,手动立即触发其各个被@Lazy(true)标注的关联属性。

该方法在重写过的ServiceImpl内也存在(供Controller层调用来加载延迟关联的属性)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

AutoMapper在重写过的ServiceImpl类中已经自动注入可用(名为autoMapper),其它情况也可以手动注入:

public class MPRTest2 {
@Autowired
AutoMapper autoMapper;

@Resource
private ManMapper manMapper;

@Test
public void t_man() {
Man man = manMapper.selectById(1L);
autoMapper.mapperEntity(man);
System.out.println(man);
}

1
2
3
4
5
6
7
8
9

}
————————————————
版权声明:本文为CSDN博主「He少年」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/vsmybits/article/details/123995224文章来源地址https://www.toymoban.com/news/detail-809351.html

到了这里,关于MyBatis-Plus不写任何resultMap和SQL执行一对一、一对多、多对多关联查询的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Mybatis-Plus如何自定义SQL注入器?

    有关Mybatis-Plus常用功能之前有做过一篇总结: MyBatisPlus常用功能总结!(附项目示例) 我们在使用Mybatis-Plus时,dao层都会去继承BaseMapper接口,这样就可以用BaseMapper接口所有的方法, BaseMapper中每一个方法其实就是一个SQL注入器 在Mybatis-Plus的核心(core)包下,提供的默认可注入方

    2023年04月12日
    浏览(51)
  • Mybatis-Plus使用Wrapper自定义SQL

    简要说明:Mybatis-Plus使用Wrapper自定义SQL,主要的代码说明,详情可以往后看。 假设有三张表(这三张表在: SpringBoot整合mybatis-plus-CSDN博客,有 )的关系如图所示 对应的UserMapper.java的主要代码如下 对应的UserMapper.xml如下所示 大概结果如下所示: 联表查询,Mybatis-Plus使用Wr

    2024年01月16日
    浏览(46)
  • Mybatis ,Mybatis-plus列表多字段排序,包含sql以及warpper

    首先根据咱们返回前端的数据列来规划好排序字段 如下: 这里的字段为返回VO的字段,要转换成数据库字段然后加入到排序中 示例,穿了 surname,cerRank 多字段,然后是倒序 false 首先创建好映射,如下代码,第一个List 为前端字段VO, 第二个List 为数据库字段。Util.handle 是将两个转换

    2024年02月14日
    浏览(41)
  • mybatis-plus控制台打印sql(mybatis-Log)

    配置了mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl;但是mybatis执行的sql没有输出 需要检查点: 1、日志级别设置:请确保你的日志级别配置正确。如果日志级别设置得太低,可能导致SQL语句不会被打印出来。你可以尝试将日志级别调整为DEBUG或更高级别,以确

    2024年02月03日
    浏览(61)
  • springboot整合mybatis-plus的sql输出到日志文件上

    springboot整合mybatis-plus的sql输出到日志文件上 在平时的日常开发中,我们希望sql打印在控制台上,只要如下配置即可 但是在生产中如果希望sql输出到日志文件上,有几种方式可以实现,下面我就用项目中常用的两种方式(不引入第三方依赖) 一、修改yml文件配置即可 缺点:

    2024年02月01日
    浏览(54)
  • Mybatis-Plus的SQL注入器实现批量插入/修改,效率比较

    mysql支持一条sql语句插入多条数据。但是Mybatis-Plus中默认提供的saveBatch、updateBatchById方法并不能算是真正的批量语句,而是遍历实体集合执行INSERT_ONE、UPDATE_BY_ID语句。 mybatis-plus虽然做了分批请求、一次提交的处理。但如果jdbc不启用配置rewriteBatchedStatements,那么批量提交的s

    2024年02月11日
    浏览(49)
  • Mybatis-plus 配置自定义sql(.xml文件)查询语句的步骤

    这是使用Mybatis-plus 的自动生成实体类代码生成.xml文件, 所以他会在java目录下,不在resources目录下 如果在java目录下的xml文件,需要分别配置application.yml和pom.xml文件 type-aliases-package:java目录下边的第一级包名 mapper-locations: classpath:映射器的地址: 类路径:也就是.xml所在的包名

    2024年02月16日
    浏览(59)
  • Mybatis-plus解析sql发生异常:net.sf.jsqlparser.JSQLParserException

    问题描述 在使用mybatis-plus的过程中,有一个jsonb字段使用了jsonb_exists_any (field_name, text[])作为where条件查询,执行sql如下: SELECT * FROM table_name  WHERE  jsonb_exists_any (field_name, ARRAY[\\\'110544709344\\\', \\\'12564892357\\\']) 上面的sql在navicat中执行正常,所以sql没有问题,但是在mybatis-plus的xml文件

    2024年02月02日
    浏览(34)
  • springboot 下mybatis-plus 如何打印sql日志和参数到日志文件

    网上很多说法打印sql日志的方法在application.properties配置文件中 但是上述配置只能将sql日志打印到控制台,无法打印到日志文件中 参考下面这个文档,将sql日志打印到日志文件中 https://www.ius7.com/a/305 1:设置mybatisplus包下的日志级别为DEBUG; 2:设置项目mapper目录的日志级别为DE

    2024年02月14日
    浏览(52)
  • 【每日小bug】——mybatis-plus拼接sql空格报错,根据时间聚合查询

    mybatis-plus拼接sql报错 复制报错sql语句到navicat,字段之间缺少空格,补上就可以了 聚合sql 根据时间 结果

    2024年01月22日
    浏览(42)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包