当前位置: 代码网 > it编程>编程语言>Java > MyBatis-Plus ORM数据库和实体类映射方式

MyBatis-Plus ORM数据库和实体类映射方式

2025年01月21日 Java 我要评论
在开发中,数据库和 java 对象的映射(orm)是一个绕不开的话题,而 mybatis-plus(mp)作为一款优秀的 orm 工具,帮我们简化了繁琐的数据库操作。本文将从数据库基础、表与实体映射、

在开发中,数据库和 java 对象的映射(orm)是一个绕不开的话题,而 mybatis-plus(mp)作为一款优秀的 orm 工具,帮我们简化了繁琐的数据库操作。本文将从数据库基础、表与实体映射、复杂对象映射、自定义 sql 等角度,深入探讨 mp 的数据库映射功能。

一、数据库设计基本知识

在开始 orm 映射之前,理解数据库设计的基本原则至关重要:

1. 索引

索引可以提高查询效率,例如主键索引、唯一索引、复合索引等。

在创建实体时,可以用注解标注需要索引的字段:

@tablefield("username")
@tableindex(type = indextype.unique)
private string username;

2. 主键与外键

  • 主键:标识表中每一行记录的唯一性。
  • 外键:用来建立表与表之间的关系。

3. 范式

数据库范式(如第一范式、第三范式)是设计良好表结构的重要参考。

tip: 保持表结构简单,但不妨碍业务扩展。

二、表与实体的映射关系

mp 提供了丰富的注解,帮助开发者高效完成数据库表与 java 对象的映射。

1. 基本映射

mp 默认将表名与实体名直接映射,但我们可以通过注解自定义:

表名映射:使用 @tablename 注解将实体类与数据库表关联:

@tablename("user")
public class user {
    @tableid(value = "id", type = idtype.auto)
    private long id;

    @tablefield("username")
    private string name;
}

字段名映射:数据库字段名通常为下划线风格,java 属性名为驼峰风格。当字段名与属性名不一致时,mp 默认自动处理这种映射,也可以通过 @tablefield 自定义:

@tablefield("email_address")
private string emailaddress;

2. 自定义主键生成策略

主键生成是 orm 映射中重要的一环,当往数据库添加字段的时候,此id会根据指定的主键生成策略来进行生成对应的值。mp 支持多种主键生成策略:

idtype.auto

  • 适用于主键为自增类型(如 mysql 的 auto_increment
  • 在插入数据时,不需要为主键赋值,由数据库根据自增策略生成。
  • 此策略仅在数据库支持自增主键的情况下有效,需要在数据库中保证主键是自增的。

idtype.assign_id

  • mybatis-plus 默认的主键生成策略,使用 雪花算法 生成全局唯一 id。
  • 在插入数据时,mp 自动生成主键值,并在 sql 中直接插入该值。
  • 数据库表的主键类型为 bigint,需要全局唯一标识符。

idtype.input

  • 手动输入主键值
  • 需要在插入数据前手动设置主键值,否则插入操作将失败。
  • 适用于特定业务场景(如主键由外部系统生成)。

示例:

在实体类中通过注解设置:

@tableid(value = "id", type = idtype.auto)
private long id;

全局设置主键策略(application.yaml 配置文件中)

mybatis-plus:
  global-config:
    db-config:
      id-type: assign_id  # 全局默认使用雪花算法
      # 可选值:
      # auto: 数据库自增
      # none: 无状态
      # input: 手动输入
      # assign_id: 雪花算法
      # assign_uuid: uuid

三、xml 中配置复杂映射

1. 基本数据类型映射

对于普通表字段到实体属性的映射,mp 提供了简单直观的方式。

通过 resultmap 解决复杂结果集的映射问题。

指定了id之后,如果查询数据中包含了多个id的值,会自动合并,映射为一个对象集合

a. 基本映射规则

mp 默认遵循数据库字段名和实体类属性名之间的映射规则

  • 数据库字段名:下划线命名。
  • java 属性名:驼峰命名。

示例表结构(user 表):

create table user (
    id bigint primary key,
    username varchar(50),
    age int
);

实体类定义:

@data
public class user {
    private long id;          // 对应数据库字段 id
    private string username;  // 对应数据库字段 username
    private integer age;      // 对应数据库字段 age
}

b. 自定义字段映射

通过 column 属性来指定表字段

<resultmap id="usermap" type="user">
    <id property="id" column="id"/>
    <result property="username" column="user_name"/>
    <result property="age" column="age"/>
</resultmap>

2. 嵌套对象映射

嵌套对象映射用于处理对象属性本身是另一个复杂对象的场景,例如主表与子表关联。

a. 表和实体类

假设有以下表结构

user表:

create table user (
     id bigint primary key,
     name varchar(50)
 ); 

address表:

    create table address (
      id bigint primary key,
      user_id bigint,
      city varchar(50),
      foreign key (user_id) references user(id)
    );

实体类定义:

@data
public class user {
    private long id;
    private string name;
    private address address; // 嵌套对象
}

@data
public class address {
    private long id;
    private long userid;
    private string city;
}

b. xml 映射

在 xml 文件中通过 <association> 定义嵌套对象映射:

<resultmap id="userwithaddressmap" type="user">
    <id property="id" column="id"/>
    <result property="name" column="name"/>
    <association property="address" javatype="address">
        <id property="id" column="address_id"/>
        <result property="city" column="city"/>
    </association>
</resultmap>

<select id="selectuserwithaddress" resultmap="userwithaddressmap">
    select u.id, u.name, a.id as address_id, a.city
    from user u
    left join address a on u.id = a.user_id
</select>

3. 集合类型映射

当查询结果中存在一个字段包含 多个值(例如多个标签 tag),并且在实体类中将该字段指定为 集合类型(如 list<string>),mybatis-plus 会根据配置自动将这些值合并并映射为集合。

这种场景常见于 一对多多对多 的查询中,主要通过 <collection> 元素 实现。

a. 基本示例

① 假设有以下数据:

article_tag

article_idtag
1spring
1mybatis
2java

② 实体类定义

public class article {
    private long id;               // 文章 id
    private string title;          // 文章标题
    private list<string> tags;     // 标签集合
}

③ mapper 配置(xml 映射文件)

使用 <collection> 将多行数据的 tag 字段自动映射为一个集合:

<resultmap id="articleresultmap" type="com.example.article">
    <id property="id" column="article_id" />
    <result property="title" column="title" />
    <collection property="tags" oftype="java.lang.string">
        <result column="tag" />
    </collection>
</resultmap>

<select id="selectarticleswithtags" resultmap="articleresultmap">
    select 
        a.id as article_id, 
        a.title, 
        t.tag 
    from 
        article a
    left join 
        article_tag t 
    on 
        a.id = t.article_id
</select>

④ 查询结果

list<article> articles = articlemapper.selectarticleswithtags();

假设查询结果为:

[
  {
    "id": 1,
    "title": "学习 mybatis",
    "tags": ["spring", "mybatis"]
  },
  {
    "id": 2,
    "title": "java 基础",
    "tags": ["java"]
  }
]

b. 对象类型集合

以用户为例和订单表为例:

① 表和实体类

假设有以下表结构

user表:

create table user (
    id bigint primary key,
    name varchar(50)
);

order表:

create table order (
    id bigint primary key,
    user_id bigint,
    order_number varchar(50),
    foreign key (user_id) references user(id)
);

实体类定义:

@data
public class user {
    private long id;
    private string name;
    private list<order> orders; // 集合类型
}

@data
public class order {
    private long id;
    private long userid;
    private string ordernumber;
}

xml 映射

在 xml 文件中通过 <collection> 定义集合映射:

<resultmap id="userwithordersmap" type="user">
    <id property="id" column="id"/>
    <result property="name" column="name"/>
    <collection property="orders" oftype="order">
        <id property="id" column="order_id"/>
        <result property="ordernumber" column="order_number"/>
    </collection>
</resultmap>

<select id="selectuserwithorders" resultmap="userwithordersmap">
    select u.id, u.name, o.id as order_id, o.order_number
    from user u
    left join order o on u.id = o.user_id
</select>

【注意事项】

  • <collection> 的 oftype 属性指定集合中元素的类型。
  • 确保 sql 查询中包含子表数据,否则集合为空。

四、自定义 sql

mp 提供了两种自定义 sql 的方式:xml 文件注解方式

1. 使用注解自定义 sql

mapper 接口中直接使用注解书写简单 sql:

@mapper
public interface usermapper extends basemapper<user> {
    @select("select * from user where name = #{name}")
    user findbyname(@param("name") string name);
}
  • 优点:简洁、轻量化。
  • 缺点:不适合复杂查询。

2. 使用 xml 文件自定义 sql

对于复杂 sql,建议使用 xml 文件。mp 通过 mapper 文件与 xml 配置绑定:

usermapper.java

@mapper
public interface usermapper extends basemapper<user> {
    user selectuserwithorders(long userid);
}

usermapper.xml

<resultmap id="userresultmap" type="user">
    <id property="id" column="id"/>
    <result property="name" column="name"/>
    <collection property="orders" oftype="order">
        <id property="id" column="order_id"/>
        <result property="ordernumber" column="order_number"/>
    </collection>
</resultmap>

<mapper namespace="com.example.mapper.usermapper">
    <select id="selectuserwithorders" resulttype="user">
        select u.*, o.*
        from user u
        left join order o on u.id = o.user_id
        where u.id = #{userid}
    </select>
</mapper>

五、写在最后

总结:

  • mp 将实体类与数据库表映射打通,使得开发效率提升。
  • 对于复杂场景,xml 自定义 sql 是不可或缺的利器。
  • 主键生成字段映射等基础功能覆盖面广,足够应对大多数项目需求。

建议:

  • 优先使用 mp 提供的内置方法,减少代码冗余。
  • 复杂业务逻辑时,灵活使用自定义 sql(尤其是 xml 文件)。
  • 对于关联查询,合理使用 resultmap嵌套映射

以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com