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

JPA关联mybatis

一、JPA 关联

  1. 实体关系映射

    • JPA 支持多种实体间的关联关系,如一对一、一对多、多对一和多对多。通过使用注解可以清晰地定义实体之间的关系,方便进行数据库操作时自动处理关联数据的加载和保存。
    • 例如,使用 @OneToOne@OneToMany@ManyToOne 和 @ManyToMany 注解来分别表示不同的关联关系。

单向多对一关联:
@Entity
@Table(name = "sys_user")
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_role_id")
    private Long usrRoleId;
    @Column(name = "usr_flag")
    private Integer usrFlag;

 @OneToMany:注解映射多对一关联关系,targetEntity属性表示关联实体类型;可省略

 @JoinColumn:注解映射关联的外键字段,如不指定,则生成一张新表维护俩个对象之间的关系

双向一对多关联:
@Entity
@Table(name="sys_role")
@Data
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 Integer roleFlag;

        @OneToMany(targetEntity = User.class,fetch = FetchType.EAGER,cascade = CascadeType.REMOVE,mappedBy = "role")
    private Set<User> users = new HashSet<>();

 targetEntity :属性表示关联的实体类型

fetch :属性表示加载策略,FetchType 取值有 LAZY及 EAGER,LAZY 表示延迟加载EAGER表示立即加载。@ManyTo0ne注解也包含该属性,且默认值为EAGER,表示立即加载,所以查询 User 时通过左外关联立即获取 Role 数据;@OneToMany 注解该属性默认值为 LAZY。

cascade: 属性表示级联操作,CascadeType取值有PERSIST、REMOVE、ALL…等PERSIST 表示级联持久化(保存)操作,REMOVE级联删除,ALL级联所有操作@ManyToOne 注解也包含该属性,但一般不在多的一方进行级联操作。

mappedBy: 属性用来设置对象之间的关系维护方(关系维护通过操作外键完成)。如不指定 mappedBy 属性,则对象均由自己维护关系(外键),操作一方对象时,会额外产生更新外键的SQL语句。所以一般在@OneToMany注解中指定 mappedBy 属性且属性值为多方对象中关联的一方属性名,并且此时一方实体中不能添加@JoinColumn 注解。

二、MyBatis

  • 灵活的 SQL 映射

MyBatis 以 SQL 为中心,允许开发者编写灵活的 SQL 语句来进行数据库操作。可以根据具体的业务需求定制复杂的查询、插入、更新和删除操作。

通过 XML 配置文件或注解的方式,将 SQL 语句与 Java 方法进行映射,使得数据库操作更加直观和易于维护。

  • 结果映射

MyBatis 提供了强大的结果映射功能,可以将数据库查询结果映射到 Java 对象中。可以通过自定义结果映射器或使用自动映射功能来简化对象的创建和数据的填充。

例如,可以使用 resultMap 标签来定义复杂的结果映射规则,将数据库表中的列映射到 Java 对象的属性上。

  • 动态 SQL

MyBatis 支持动态 SQL,可以根据不同的条件生成不同的 SQL 语句。这在处理复杂的查询条件和动态生成 SQL 时非常有用。

使用 <if><choose><when><otherwise> 等标签可以根据条件动态地拼接 SQL 语句,提高 SQL 的灵活性和可维护性。

  • 插件扩展

MyBatis 提供了插件机制,可以方便地扩展其功能。开发者可以编写自定义插件来实现诸如分页、缓存、日志记录等功能。

通过实现 Interceptor 接口,可以在 MyBatis 的执行过程中插入自定义的逻辑,增强框架的功能。

  • 优点:

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

  1. 提供对象关系映射标签,支持对象关系组件维护
  2. SQL语句依赖于数据库,导致数据库移植性差

三.MyBatis 与 Spring Boot 集成

集成 MyBatis 和 Spring Boot 可以利用 Spring Boot 提供的自动配置功能,使得配置和使用 MyBatis 更加便捷。以下是集成的步骤和要点:

2.1 添加依赖

在 Spring Boot 项目的 pom.xml 文件中添加 MyBatis 和数据库驱动的依赖:

<dependencies>
    <!-- Spring Boot Starter -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>
    
    <!-- MyBatis Starter -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-mybatis</artifactId>
    </dependency>
    
    <!-- 数据库驱动(例如 MySQL) -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
    </dependency>
</dependencies>
2.2 配置数据源

在 application.properties 或 application.yml 文件中配置数据源属性:

application.properties 示例

mybatis.type-aliases-super-type=com.bdqn.t369spingboot.entity.User
spring.application.name=T369-Spring-Boot
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/crm?useUnicode=true&characterEncoding=utf-8
spring.datasource.username=root
spring.datasource.password=123456

mybatis.config-location=classpath:mybatis/mybatis-config.xml
#mybatis.mapper-locations=classpath:mybatis/mapper/*.xml
mybatis.type-aliases-package=com.bdqn.t369spingboot.entity

logging.level.root=warn
logging.level.com.bdqn.t369spingboot.mapper=trace
logging.pattern.console=%p%m%n

#??JPA(Hibernate)????

#spring.jpa.properties.hibernate.hbm2ddl.auto=update
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQLDialect
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true
2.3 创建实体类

定义与数据库表对应的实体类:

public class User implements Serializable {
    private Long usrId;
    private String usrName;
    private String usrPassword;
    private Long usrRoleId;
    private Integer usrFlag;

 

2.4 创建 Mapper 接口

定义 Mapper 接口并标注 @Mapper 注解(如果使用 Spring Boot 2.0 或更高版本,可以省略 @Mapper 注解):

package com.bdqn.t369spingboot.mapper;

import com.bdqn.t369spingboot.entity.User;
import org.apache.ibatis.annotations.*;

import java.util.List;


public interface UserMapper {
    @Insert("INSERT INTO sys_user(usr_name, usr_password, usr_role_id, usr_flag) " +
            "VALUES(#{usrName}, #{usrPassword}, #{usrRoleId}, #{usrFlag})")
     void insert(User user);

    @Delete("DELETE FROM sys_user WHERE usr_id = #{id}")
     void delete(Long id);

    @Update("<script>" +
            "UPDATE sys_user SET " +
            "<if test=\"usrName != null\">usr_name = #{usrName}, </if>" +
            "<if test=\"usrPassword != null\">usr_password = #{usrPassword}, </if>" +
            "<if test=\"usrRoleId != null\">usr_role_id = #{usrRoleId}, </if>" +
            "<if test=\"usrFlag != null\">usr_flag = #{usrFlag}</if>" + // 移除最后一个逗号
            "WHERE usr_id = #{usrId}" +
            "</script>")
     void update(User user);

    @Select("SELECT usr_id, usr_name, usr_password, usr_role_id, usr_flag FROM sys_user WHERE usr_id = #{id}")
    @Results({
            @Result(property = "usrId", column = "usr_id"),
            @Result(property = "usrName", column = "usr_name"),
            @Result(property = "usrPassword", column = "usr_password"),
            @Result(property = "usrRoleId", column = "usr_role_id"),
            @Result(property = "usrFlag", column = "usr_flag")
    })
     User get(Long id);

    @Select("SELECT usr_id, usr_name, usr_password, usr_role_id, usr_flag FROM sys_user")
    @Results({
            @Result(property ="usrId", column = "usr_id"),
            @Result(property ="usrName", column = "usr_name"),
            @Result(property ="usrPassword", column = "usr_password"),
            @Result(property ="usrRoleId", column = "usr_role_id"),
            @Result(property ="usrFlag", column = "usr_flag")
    })
     List<User> findAll();
}

 2.5 编写测试类

@RunWith(SpringRunner.class)
@SpringBootTest(classes = T369SpingBootApplication.class)
public class UserMapperTester {
     @Autowired
    private UserMapper userMapper;

    @Test
    public void testInsert() throws Exception{
        userMapper.insert(new User("ktjiaoyu","123456",2L,1));
    }

    @Test
    public void testGet(){
        User user = userMapper.get(2L);
        System.out.println("usrName:"+user.getUsrName());
    }

 

总的来说,JPA 关联提供了强大的实体关系管理和自动处理关联数据的能力,适合于以对象为中心的开发模式。而 MyBatis 则更加灵活,以 SQL 为中心,适合于对 SQL 有较高要求和需要进行复杂数据库操作的场景。


http://www.kler.cn/a/291064.html

相关文章:

  • 【Mysql优化】SQL优化最佳实践分析与总结
  • (14)D-FINE网络,爆锤yolo系列
  • go-zero(十四)实践:缓存一致性保证、缓存击穿、缓存穿透与缓存雪崩解决方案
  • Hive解决数据倾斜
  • Elasticsearch-DSL高级查询操作
  • Docker 安装 禅道-21.2版本-外部数据库模式
  • GAMES104:10+11游戏引擎中物理系统的基础理论算法和高级应用-学习笔记
  • 流量密码算被你玩明白了!用AI做萌宠+萌娃短视频,百万播放量
  • union_collinear_contours_xld 算子介绍一下,条件关系
  • 【c++】平常自己练习写代码的两个大方向
  • Golang | Leetcode Golang题解之第387题字符串中的第一个唯一字符
  • 计算机毕业设计hadoop+spark+hive知识图谱股票推荐系统 股票数据分析可视化大屏 股票基金爬虫 股票基金大数据 机器学习 大数据毕业设计
  • 【大数据分析与挖掘算法】matlab实现——改进的Apriori关联规则算法
  • 基于单片机的浴室防雾镜系统设计
  • 使用python+opencv解析图像和文本数据
  • 前端常用的几种设计模式--观察者模式、单例模式等
  • 前端:HTML、CSS、JS、Vue
  • 怎样在公司将手机屏幕(远程)投屏到家里的大电视上?
  • Redis在Spring Boot中的应用详细讲解和案例示范
  • Verilog刷题笔记62
  • pyqt fromlayout 布局中间空隙问
  • mac 软连接需要绝对路径
  • HtmlSanitizer: 一个保护你的网站免受XSS攻击的.Net开源项目
  • 集成电路学习:什么是OLED有机发光二极管
  • 【为项目做准备】Linux操作系统day2
  • 不管夫妻还是情人,想要长相厮守、生活幸福美满,就这两个字!