JPA关联MyBatis

2024-09-04 02:36
文章标签 关联 mybatis jpa

本文主要是介绍JPA关联MyBatis,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

3.1 JPA 多表查询

       多表查询在 Spring Data JPA 中有两种实现方式,第一种是创建一个结果集的接口来接受多表连接查询后的结果,第二种是利用 JPA 的关联映射来实现

3.1.1 数据库表及关系

      CRM 数据库中除 sys_user(用户)表外,还包括sys_role(角色)表。

      sys_role(角色)表脚本:

CREATE TABLE `sys_role` (`role_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '编号',`role_name` varchar(50) DEFAULT NULL COMMENT '角色名称',`role_desc` varchar(50) DEFAULT NULL COMMENT '角色描述',`role_flag` int(11) DEFAULT NULL COMMENT '状态',PRIMARY KEY (`role_id`),UNIQUE KEY `role_id` (`role_id`)
) ENGINE=InnoDB AUTO_INCREMENT=34 DEFAULT CHARSET=utf8

        sys_user(用户)表与 sys_role(角色)表之间存在着主外键关系, sys_user(用户)表中的usr_role_id外键字段对应sys_role(角色)表中的主键 role_id 字段。

3.1.2 多表联接查询

        1.在 com.bdqn.crm.entity 包下创建Role实体类

@Entity
@Table(name = "sys_role")
public class Role implements Serializable {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)@Column(name = "role_id")private long roleId;@Column(name = "role_name")private String roleName;@Column(name = "role_desc")private String roleDesc;@Column(name = "role_flag")private long roleFlag;

2.在 com.bdqn.crm.vo 包下创建 UserInfo 接口,里面提供所需数据的getter方法,其中包括用户数据和角色名称(roleName)。

public interface UserInfo {Long getUsrId();String getUsrName();String getUsrPassword();Long getUsrRoleId();Integer getUsrFlag();// 角色名称String getRoleName();
}
  • 在运行中Spring会给接口(UserInfo)自动生产一个代理类来接收返回的结果,代码中使用getXX的形式来获取。

3.在UserRepository中添加查询方法,返回类型设置UserInfo:

@Query("select u.usrId as usrId, u.usrName as usrName, u.usrPassword as usrPassword,"+ "u.role.roleId as usrRoleId, u.usrFlag as usrFlag, r.roleName as roleName "+ "from User u, Role r where u.role.roleId=r.roleId and u.usrId=?1")public UserInfo getUserInfo(Long usrId);

4.测试验证:

@Testpublic void testGetUserInfo(){//测试多表联接查询UserInfo userInfo = userRepository.getUserInfo(2L);System.out.println("usrName:" + userInfo.getUsrName());System.out.println("roleName:" + userInfo.getRoleName());}

3.1.3 关联映射

具体例子来介绍如何映射以下关联关系:

  • 以 User 和 Role 为例,介绍如何映射多对一单项关联映射
  • 以 Role 和 User 为例,介绍如何映射一对多双向关联映射

3.1.3.1 单向多对一关联

        首先以 User 和 Role 为例,介绍通过使用外键来建立多对一的单向关联关系。

        1.修改 User 实体,添加关联 Role 对象:

@Entity
@Table(name = "sys_user")
//@NamedQueries(@NamedQuery(name = "User.findUsersByName",query = "select u from User u where u.usrName = ?1"))
public class User implements Serializable {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)@Column(name = "usr_id")private Long usrId;@Column(name = "usr_name")private String usrName;@Column(name = "usr_password")private String usrPassword;@ManyToOne(targetEntity = Role.class)@JoinColumn(name = "usr_role_id")private Role role;@Column(name = "usr_flag")private Integer usrFlag;
  • @ManyToOne 注解映射多对一关联关系,targetEntity 属性表示关联实体类型,可省略;
  • @JoinColumn 注解映射关联的外键字段,如不指定,则生成一张新表维护两个对象之间的关系;

2.创建 UserRepository

public interface UserRepository extends JpaRepository<User,Long>, JpaSpecificationExecutor<User> {
}

3.测试基本的CRUD

 @Testpublic void testGet(){//测试按主键查询用户,并输出关联的用户数量Role role = roleRepository.findById(1L).get();System.out.println("roleName:" + role.getRoleName());System.out.println("users.size:" + role.getUsers().size());}

3.1.3.2 双向一对多关联

在前面的实例中,已经建立了 User 类到 Role 类的单向多对一关联,下面再继续通过示例完成Role 类到 User 类的双向一对多关联。

1.修改 Role 实体类,添加关联的 User 对象集合:

@Entity
@Table(name = "sys_role")
public class Role implements Serializable {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)@Column(name = "role_id")private long roleId;@Column(name = "role_name")private String roleName;@Column(name = "role_desc")private String roleDesc;@Column(name = "role_flag")private long roleFlag;@OneToMany(targetEntity = User.class,fetch = FetchType.EAGER,cascade = CascadeType.PERSIST,mappedBy = "role")private Set<User> users = new HashSet<User>();// 省略其他代码
}
  • targetEntity 属性表示关联的实体类
  • fetch 属性表示加载策略,FetchType 取值有LAZY 及 EAGER ,LAZY 表示延迟加载,EAGER 表示立即加载,@ManyToOne 注解也包含该属性,且默认值为EAGER,表示立即加载,所以查询 User 时通过左外连接立即获取Role 数据;@OneToMany 注解表示该属性默认值为 LAZY。
  • cascade 属性表示级联操作,CascadeType 取值有 PERSIST、REMOVE、ALL ......等。
  • mappedBy 属性用来设置对象之间的关系维护方

2.创建RoleRepositoty

public interface RoleRepository extends JpaRepository<Role,Long> {
}

3.测试查询

@Testpublic void testGet(){//测试按主键查询用户,并输出关联的用户数量Role role = roleRepository.findById(1L).get();System.out.println("roleName:" + role.getRoleName());System.out.println("users.size:" + role.getUsers().size());}

4.测试级联操作:级联新增

 @Testpublic void testAdd(){ // 测试级联新增Role role = new Role("测试角色","演示级联新增角色和用户",1);User user1 = new User("测试角色1","123456",role,1);User user2 = new User("测试角色2",                                                                                                                                                                                        "123456",role,1);// 将 User 添加到 Role 的users 集合中,进行级联新增role.getUsers().add(user1);role.getUsers().add(user2);roleRepository.save((role)); // 新增角色的同时新增关联的用户}

5.测试级联操作:级联删除

        将级联属性的值改为REMOVE,再来测试级联删除,将刚刚创建的 Role 对象及关联的 User 对象一次删除。

@Testpublic void testDelete(){ // 测试级联删除// 先使用 getOne 方法获取到 Role 的应用,然后调用 delete 方法删除Role role = roleRepository.getOne(33L);userRepository.deleteByRoleId(role.getRoleId());roleRepository.delete(role);}

3.2 Spring Boot 集成 MyBaties

优点:

  • SQL 被统一提取出来,便于统一管理和优化
  • SQL 和代码解耦,将业务逻辑和数据访问逻辑分离,使系统的设计更清晰,更易维护、更易单元测试
  • 提供映射标签,支持对象与数据库的 ORM 字段关系映射
  • 提供对象关系映射标签,支持对象关系组件维护
  • 灵活书写动态 SQL,支持各种条件来动态生成不同的 SQL 

缺点:

  • 编写 SQL 语句时工作量很大,尤其是字段多、关联表多时,更是如此
  • SQL 语句依赖于数据库,导致数据库移植性差

3.2.2.2 xml 配置版集成

        XML 版本保持映射文件的方式,且最佳的开发方式不需要实现 Dao 的实现层,系统会自动根据方法名在映射文件中找到对应的SQL。

        接下来给大家介绍一下如何使用XML 配置版集成 Spring Boot。

1.创建项目:

2.添加关键依赖包:

        任何使用方式都需要首先在 pox.xml 中引入 mybatis-spring-boot-starter 的启动器,我们使用项目向导添加的依赖如下:

        <dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>3.0.3</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.18</version></dependency>

3.application.properties 配置相关信息:

spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql:///crm?useUnicode=true&characterEncoding=utf-8
spring.datasource.username=root
spring.datasource.password=liuyuhanmybatis.config-location=classpath:mybatis/mybatis-config.xml
mybatis.mapper-locations=classpath:mybatis/mapper/*.xml
mybatis.type-aliases-package=com.bdqn.crm.pojo

5.启动类:

        在启动类中添加对Mapper包扫描@MapperScan,Spring Boot 启动的时候会自动加载包路径下的 Mapper。

@SpringBootApplication
@MapperScan("com.bdqn.crm.mapper")
public class MybatiesXmlApplication {public static void main(String[] args) {SpringApplication.run(MybatiesXmlApplication.class, args);}}

6.编码:

resource/mybatis 目录下添加mybatis-config.xml,配置一些全局属性:

    <!-- 全局配置文件 --><settings><!-- 开启二级缓存 --><setting name="cacheEnabled" value="true" /><!-- 开启控制台日志 --><!-- <setting name="logImpl" value="STDOUT_LOGGING" />--><setting name="lazyLoadingEnabled" value="true" /><!--全自动映射级别--><setting name="autoMappingBehavior" value="FULL" /></settings>

        编写实体类 User.java:

public class User implements Serializable {private long usrId;private String usrName;private String usrPassword;private long usrRoleId;private long usrFlag;// 省略 setter&getter
}

编写 Mapper 接口:

这篇关于JPA关联MyBatis的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


原文地址:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.chinasem.cn/article/1134753

相关文章

Mybatis嵌套子查询动态SQL编写实践

《Mybatis嵌套子查询动态SQL编写实践》:本文主要介绍Mybatis嵌套子查询动态SQL编写方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录前言一、实体类1、主类2、子类二、Mapper三、XML四、详解总结前言MyBATis的xml文件编写动态SQL

Mybatis Plus JSqlParser解析sql语句及JSqlParser安装步骤

《MybatisPlusJSqlParser解析sql语句及JSqlParser安装步骤》JSqlParser是一个用于解析SQL语句的Java库,它可以将SQL语句解析为一个Java对象树,允许... 目录【一】jsqlParser 是什么【二】JSqlParser 的安装步骤【三】使用场景【1】sql语

mybatis的mapper对应的xml写法及配置详解

《mybatis的mapper对应的xml写法及配置详解》这篇文章给大家介绍mybatis的mapper对应的xml写法及配置详解,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,... 目录前置mapper 对应 XML 基础配置mapper 对应 xml 复杂配置Mapper 中的相

MyBatis分页插件PageHelper深度解析与实践指南

《MyBatis分页插件PageHelper深度解析与实践指南》在数据库操作中,分页查询是最常见的需求之一,传统的分页方式通常有两种内存分页和SQL分页,MyBatis作为优秀的ORM框架,本身并未提... 目录1. 为什么需要分页插件?2. PageHelper简介3. PageHelper集成与配置3.

关于Mybatis和JDBC的使用及区别

《关于Mybatis和JDBC的使用及区别》:本文主要介绍关于Mybatis和JDBC的使用及区别,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、JDBC1.1、流程1.2、优缺点2、MyBATis2.1、执行流程2.2、使用2.3、实现方式1、XML配置文件

MySQL复合查询从基础到多表关联与高级技巧全解析

《MySQL复合查询从基础到多表关联与高级技巧全解析》本文主要讲解了在MySQL中的复合查询,下面是关于本文章所需要数据的建表语句,感兴趣的朋友跟随小编一起看看吧... 目录前言:1.基本查询回顾:1.1.查询工资高于500或岗位为MANAGER的雇员,同时还要满足他们的姓名首字母为大写的J1.2.按照部门

慢sql提前分析预警和动态sql替换-Mybatis-SQL

《慢sql提前分析预警和动态sql替换-Mybatis-SQL》为防止慢SQL问题而开发的MyBatis组件,该组件能够在开发、测试阶段自动分析SQL语句,并在出现慢SQL问题时通过Ducc配置实现动... 目录背景解决思路开源方案调研设计方案详细设计使用方法1、引入依赖jar包2、配置组件XML3、核心配

MyBatis模糊查询报错:ParserException: not supported.pos 问题解决

《MyBatis模糊查询报错:ParserException:notsupported.pos问题解决》本文主要介绍了MyBatis模糊查询报错:ParserException:notsuppo... 目录问题描述问题根源错误SQL解析逻辑深层原因分析三种解决方案方案一:使用CONCAT函数(推荐)方案二:

SQL表间关联查询实例详解

《SQL表间关联查询实例详解》本文主要讲解SQL语句中常用的表间关联查询方式,包括:左连接(leftjoin)、右连接(rightjoin)、全连接(fulljoin)、内连接(innerjoin)、... 目录简介样例准备左外连接右外连接全外连接内连接交叉连接自然连接简介本文主要讲解SQL语句中常用的表

如何高效移除C++关联容器中的元素

《如何高效移除C++关联容器中的元素》关联容器和顺序容器有着很大不同,关联容器中的元素是按照关键字来保存和访问的,而顺序容器中的元素是按它们在容器中的位置来顺序保存和访问的,本文介绍了如何高效移除C+... 目录一、简介二、移除给定位置的元素三、移除与特定键值等价的元素四、移除满足特android定条件的元