mybatis映射和实际类型不一致的问题
作者:北城深海未眠 发布时间:2023-08-13 18:09:06
mybatis映射和实际类型不一致
项目今天出现个问题,在dao中定义了一个查询,方法的返回值是map并定义了泛型都是String类型,可是方法返回值中还是存在其他的类型。
//DAO接口查询 返回类型Map<String,String>
Map<String,String> dealerInfo(String userId,String brandId);
实际返回类型还是存在不是String类型的数据
原因分析
1、泛型作用于编译阶段,仅为了防止类型混乱而出现,类型转换异常
2、mybatis结果集封 * ean时采用反射,是在运行时进行的。
小结一下
泛型是在编译阶段将我们的返回值类型匹配到一具体类型,而DAO层的接口却没有具体的返回值信息,所以在编译阶段它是可以通过的,这也就是说我们在DAO层定义的接口返回值泛型是不起作用的,具体的类型还是得依靠mapper.xml文件中定义的返回值类型为准。
解决方法
在查询sql中就将数据转换成对应类型即可
SELECT CONVERT(23,CHAR); 会将23转成字符串
mybatis映射器Mapper(结果映射以及解决列名不一致)
结果映射:(resultMap, resultType)
resultMap 元素是 MyBatis 中最重要最强大的元素。它可以让你从 90% 的 JDBC ResultSets 数据提取代码中解放出来,并在一些情形下允许你进行一些 JDBC 不支持的操作。实际上,在为一些比如连接的复杂语句编写映射代码的时候,一份 resultMap 能够代替实现同等功能的长达数千行的代码。ResultMap 的设计思想是,对于简单的语句根本不需要配置显式的结果映射,而对于复杂一点的语句只需要描述它们的关系就行了。
resultType属性可以指定结果集的类型,它?持 基本类型和 实体类类型(JavaBean 或 POJO(Plain Old Java Objects,普通老式 Java 对象))
需要注意的是,它和parameterType?样,如果注册过类型别名的,可以直接使?别名。没有注册过的必须使?全限定类名。例如:我们的实体类此时必须是全限定类名
同时,当是实体类名称是,还有?个要求,实体类中的属性名称必须和查询语句中的列名 保持? 致,否则?法实现封装。
1. resultType配置结果类型
这?考虑实体类属性和数据库表的列名已经不?致的情况
JavaBean:
public class User {
private int id;
private String username;
private String hashedPassword;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getHashedPassword() {
return hashedPassword;
}
public void setHashedPassword(String hashedPassword) {
this.hashedPassword = hashedPassword;
}
}
基于JavaBean的规范,上面这个类有 3 个属性:id,username 和 hashedPassword。这些属性会对应到 select 语句中的列名。
xml映射
类型别名是你的好帮手。使用它们,你就可以不用输入类的完全限定名称了。比如:
<!-- mybatis-config.xml 中 -->
<typeAlias type="com.someapp.model.User" alias="User"/>
<!-- SQL 映射 XML 中 -->
<select id="selectUsers" resultType="User">
select id, username, hashedPassword
from some_table
where id = #{id}
</select>
这些情况下,MyBatis 会在幕后自动创建一个 ResultMap,再基于属性名来映射列到 JavaBean 的属性上。
如果列名和属性名没有精确匹配,可以在 SELECT 语句中对列使用别名(这是一个基本的 SQL 特性)来匹配标签。比如:
<select id="selectUsers" resultType="User">
select
user_id as "id",
user_name as "userName",
hashed_password as "hashedPassword"
from some_table
where id = #{id}
</select>
这样,可以解决 实体类属性和数据库表的列名已经不?致的情况
思考:如果我们的查询很多,都使?别名的话写起来岂不是很麻烦,有没有别的解决办法呢?
2. resultMap结果类型
resultMap标签可以建?查询的列名和实体类的属性名称不?致时建?对应关系。从?实现封装。 在select标签中使?resultMap属性指定引?即可。同时resultMap可以实现将查询结果映射为复 杂类型的pojo,?如在查询结果映射对象中包括pojo和list实现?对?查询和?对多查询。
<!--
建?User实体和数据库表的对应关系
type属性:指定实体类的全限定类名
id属性:给定?个唯?标识,是给查询select标签引??的。
-->
<resultMap id="userResultMap" type="User">
<!-- id标签:?于指定主键字段
result标签:?于指定?主键字段
column属性:?于指定数据库列名
property属性:?于指定实体类属性名称
-->
<!--主键映射-->
<id property="id" column="user_id" />
<!--普通属性映射-->
<result property="username" column="user_name"/>
<result property="password" column="hashed_password"/>
</resultMap>
type属性
:指定实体类的全限定类名id="userResultMap"
:给定?个唯?标识,是给查询select标签引??的。<id>标签
:?于指定主键字段<result>标签
:?于指定?主键字段column属性
:?于指定数据库列名property属性
:?于指定实体类属性名称
而在引用它的语句中使用 resultMap 属性就行了(注意我们去掉了 resultType 属性)。比如:
<select id="selectUsers" resultMap="userResultMap">
select user_id, user_name, hashed_password
from some_table
where id = #{id}
</select>
使用外部的 resultMap ,这也是解决 实体类属性 和 数据库表的列名 不匹配的另外一种方式。
3. 小结一下
都可以解决实体类属性 和 数据库表的列名 不匹配 情况
来源:https://blog.csdn.net/weixin_43209060/article/details/103763696
猜你喜欢
- springboottest测试依赖和使用<dependency> <groupId>or
- 问题描述在使用 Matisse 与 glide 4.0.0 以及 4.0.0 之后的版本过程中,发现通过Matisse 的 wiki 代码调
- Android webview旋转屏幕导致页面重新加载问题解决办法1. 在create时候加个状态判断protected void onCr
- MyBatis多数据源配置(读写分离)首先说明,本文的配置使用的最直接的方式,实际用起来可能会很麻烦。实际应用中可能存在多种结合的情况,你可
- 本文实例为大家分享了Unity实现切割图集工具的具体代码,供大家参考,具体内容如下操作步骤先将脚本拖入Editor1.选中要切割的图片,te
- 本文实例为大家分享了Java实现UDP多线程在线咨询,供大家参考,具体内容如下1.发送的线程import java.io.BufferedR
- 一、前言程序中经常会用到TabControl控件,默认的控件样式很普通。而且样式或功能不一定符合我们的要求。比如:我们需要TabContro
- 本文实例讲述了C#远程获取图片文件流的方法。分享给大家供大家参考,具体如下:protected void Page_Load(object
- 前言Set 表示由无重复对象组成的集合,也是集合框架中重要的一种集合类型,直接扩展自 Collection 接口。在一个 Set 中,不能有
- 这个问题困扰了很久,有些类不是controller在使用autowired注入的类显示为空,找到网上的方法是在类初始化时主动注入被Autow
- 前言早就听说Go语言开发的服务不用任何架构优化,就可以轻松实现百万级别的qps。这得益于Go语言级别的协程的处理效率。协程不同于线程,线程是
- 在C#中,数组由于是固定长度的,所以常常不能满足我们开发的需求。由于这种限制不方便,所以出现了ArrayList。ArrayList、Lis
- 为了创建比例大小的子View,可以将LinearLayout的宽度和高度设为fill_parent, 而将子View的宽度或是高度设为0,然
- 前言easyui是一种基于jQuery的用户界面插件集合。easyui为创建现代化,互动,JavaScript应用程序,提供必要的功能。使用
- 一、下载Xxl-Job源代码并导入本地并运行Github地址:https://github.com/xuxueli/xxl-job中文文档地
- 一、遇到一个问题1、读取CSV文件package com.guor.demo.charset;import java.io.Buffered
- 还记得我们之前说的ListView吗,(这个难用的控件-。+)我们在用他的同时也用到了一个叫做适配器Adapter的东西。一般我们用一个类继
- 最近项目需要微信支付,然后看了下微信公众号支付,,虽然不难,但是细节还是需要注意的,用了大半天时间写了个demo,并且完整的测试了一下支付流
- 微信聊天现在非常火,是因其界面漂亮吗,哈哈,也许吧。微信每条消息都带有一个气泡,非常迷人,看起来感觉实现起来非常难,其实并不难。下面小编给大
- 1、返回字符串,Model传输数据/** * 返回String * @param m