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

标签:mybatis,映射,实际类型
0
投稿

猜你喜欢

  • Android应用内调用第三方应用的方法

    2023-02-03 11:11:32
  • java实现五子棋小游戏

    2021-12-25 06:58:56
  • C#获取存储过程返回值和输出参数值的方法

    2021-10-19 14:45:22
  • Android实现悬浮窗效果

    2022-08-17 05:59:40
  • Android自定义view仿淘宝快递物流信息时间轴

    2022-02-20 18:51:16
  • 详解如何在C#中接受或拒绝Excel中的修订

    2023-06-19 21:08:29
  • 简单谈谈java中匿名内部类构造函数

    2021-09-08 18:54:10
  • Spring中Bean的生命周期使用解析

    2021-09-06 23:06:54
  • Android DownloadProvider 源码详解

    2023-02-11 03:26:17
  • Spring Boot Thymeleaf实现国际化的方法详解

    2023-11-24 06:01:01
  • IDEA解决src和resource下创建多级目录的操作

    2023-03-24 07:05:37
  • C++11中std::packaged_task的使用详解

    2022-03-12 20:08:23
  • Java代理模式的深入了解

    2021-06-06 10:24:38
  • Java Map简介_动力节点Java学院整理

    2023-06-03 20:27:03
  • Java Swing JList列表框的实现

    2021-09-05 08:20:56
  • springcloud中RabbitMQ死信队列与延迟交换机实现方法

    2023-05-04 04:25:54
  • 使用maven开发springboot项目时pom.xml常用配置(推荐)

    2022-09-19 23:33:48
  • 一文带你了解Android中的网络请求

    2023-08-11 23:46:38
  • Java实现排队论的原理

    2023-11-23 02:19:24
  • Scala数据库连接池的简单实现

    2023-07-14 14:19:37
  • asp之家 软件编程 m.aspxhome.com