Mybatis-实体类属性名与数据库字段名不同的查询方法

查询语句是 MyBatis 中最常用的元素之一,本文涉及mybatis的单表查询操作,关联表有关的查询会后续补充。

  巧妇难为无米之炊,要想从数据库中表中取出数据并转化为javaBean,所以,我们要先准备javabean以及与其对应的数据表。

javaBean:

public class President {

	private int id;
	private String name;
	
	@Override
	public String toString() {
		return "President [id=" + id + ", name=" + name + "]";
	}
       //get set 方法.....
}
创建两个对应的数据库表,并插入两条数据:

create table president1(
    p_id int not null auto_increment primary key,
    p_name varchar(50) not null
);

insert into president1(p_name) values('lily'),('Tom');

create table president2(
    id int not null auto_increment primary key,
    name varchar(50) not null
);
insert into president2(name) values('lily'),('Tom');
创建两个数据库是为了测试两个不同的查询状况,

数据库字段名与实体类属性名相同

从sql表可以看出president2的字段名与javabean:President的属性名完全相同,这种情况下mybatis的select操作非常简单:
	<!-- 从表 president2中查询-->
	<select id="getPreByIdPresident2" parameterType="int" resultType="President">
		select * from president2 where id=#{id}
	</select>
此时mybatis运用反射机制会将查询返回的结果(id,name)封装成President对象。

如果从表president1中查询,同样采用上面的sql语句
	<!-- 从表 president1中查询-->
	<select id="getPreByIdPresident1" parameterType="int" resultType="President">
		<span style="white-space:pre">		</span>President p1 = session.selectOne(statement+"getPreByIdPresident1", 1);
<span style="white-space:pre">		</span>System.out.println("表president1中查询"+p1);
	</select>
此时如果用getPreByIdPresident1进行查询,返回的结果会是null,我们将上面的sql语句在mysql中执行下:

有结果返回,但是返回的字段名为(p_id,p_name)这种结果mybatis在解析时无法与President类对应。多数情况下实体类属性名与数据库表的字段名都会有差异,这种情况如果mybatis不能处理也就太low了。

数据库字段名与实体类属性名不相同

mybatis针对该种情况有两种解决方法,但是归根到底都是同一种实现。

Method1:定义一个ResultMap将数据库字段名与实体类属性名做个映射

我们欲从表president1中查询数据,此时的mapper配置如下:
	<resultMap type="President" id="getFromPresident2">
		<!-- 主键必须用id标签映射,其他的用非集合用result映射 集合类用collection映射 -->
		<!-- column为数据库字段名,property为实体类属性名 -->
		<id column="p_id" property="id" />
		<result column="p_name" property="name" />
	</resultMap>
	<select id="getPreByIdPresident1Method1" resultMap="getFromPresident2">
		select * from president1 where p_id=#{id}
	</select>
首先定义了一个resultMap,将数据库表的字段名与实体类属性名做了一一对应,其中type为实体类(此处运用的类别名),id为了在select标签中引用映射结果。
在select标签中并没有用resultType属性,而使用了resultMap,即为上面定义的resultMap,mybatis会根据resultMap中的映射关系去构造President

Method1:直接在sql语句中使用别名

	<!-- 从表 president1中查询 -->
	<select id="getPreByIdPresident1Method2" resultType="President">
		select p_id id,p_name name from president1 where p_id=#{id}
	</select>
这种方法会查到实际的数据,这种方法与字段名和属性名相同都是基于相同的原理: MyBatis 会在幕后自动创建一个 ResultMap,基于属性名来映射列到JavaBean 的属性上。即mybatis底层都是通过创建ResultMap来进行关系的映射,与method1原理相同。。

上面用到的测试用例的源码地址: 用例源码

<think>好的,我现在需要解决用户的问题:在MyBatis-Plus中,当实体类属性名数据库字段名不一致时,应该使用哪个注解来进行映射。根据用户提供的引用内容,我需要仔细分析这些引用,找出正确的答案。首先看引用[2],里面提到MyBatis-Plus默认使用字段名匹配的策略,即实体类字段名数据库列名一致时会自动映射。如果出现不一致的情况,这里没有直接提到解决方案,但可能涉及到其他注解。接着引用[1]和引用[3]都提到了@TableField注解。引用[1]中以数据库的name字段实体类的u_name为例,说明需要处理不一致的情况,但具体怎么用注解没有详细说明。而引用[3]中则明确提到使用@TableField(exist =false)来标记非数据库字段,不过这里的情况是字段多于数据库表的情况,但用户的问题是关于名称不一致,可能需要另一个参数。 在MyBatis-Plus的官方文档中,@TableField注解有一个value属性,用于指定对应的数据库字段名。例如,如果实体类属性是uName,数据库字段是name,可以写成@TableField(value= "name")。这样就能解决名称不一致的问题。用户提供的引用中虽然没有直接提到value属性,但引用[1]和[3]都涉及到了@TableField的使用,可能用户需要的就是这个注解的value参数。另外,用户可能还知道@TableName注解,但那是用于表名实体类名不一致的情况,不是字段映射的问题。所以正确的注解应该是@TableField,并设置其value属性为数据库字段名。 需要确认是否有其他注解,比如JPA的@Column,但在MyBatis-Plus中主要使用的是它自己的注解,而不是JPA的。因此,答案应该是@TableField(value ="数据库字段名")。总结一下,用户的问题可以通过使用@TableField注解,并指定value属性为数据库中的字段名来解决实体类属性名数据库字段不一致的问题。</think>在MyBatis-Plus中,当实体类属性名数据库字段名不一致时,应使用**@TableField**注解进行显式映射。通过设置`value`属性指定对应的数据库字段名即可解决映射问题[^2][^3]。 --- ### 具体实现步骤 1. **添加注解** 在实体类的属性上添加`@TableField`注解,并通过`value`属性指定数据库字段名: ```java public class User { @TableField(value = "name") // 数据库字段名为name,实体类属性为userName private String userName; // 其他字段... } ``` 2. **处理非映射字段** 如果实体类中存在数据库无关的额外属性(如关联对象),需添加`@TableField(exist = false)`标识其为非映射字段[^3]: ```java @TableField(exist = false) private List<Blog> blogs; ``` --- ### 注意事项 - **默认匹配规则**:若属性名字段名**完全一致**(不区分大小写),无需额外注解即可自动映射[^2]。 - **驼峰命名转换**:MyBatis-Plus默认开启驼峰命名转换(如`user_name` → `userName`),若数据库字段符合该规则则无需手动映射[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值