mybatis映射和实际类型不一致的问题

目录
  • mybatis映射和实际类型不一致
    • 原因分析
    • 小结一下
    • 解决方法
  • mybatis映射器Mapper(结果映射以及解决列名不一致)
    • 结果映射:(resultMap, resultType)
    • 1. resultType配置结果类型
    • 2. resultMap结果类型
    • 3. 小结一下

mybatis映射和实际类型不一致

项目今天出现个问题,在dao中定义了一个查询,方法的返回值是map并定义了泛型都是String类型,可是方法返回值中还是存在其他的类型。

//DAO接口查询 返回类型Map<String,String>
 Map<String,String> dealerInfo(String userId,String brandId);

实际返回类型还是存在不是String类型的数据

原因分析

1、泛型作用于编译阶段,仅为了防止类型混乱而出现,类型转换异常

2、mybatis结果集封装bean时采用反射,是在运行时进行的。

小结一下

泛型是在编译阶段将我们的返回值类型匹配到一具体类型,而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. 小结一下

都可以解决实体类属性 和 数据库表的列名 不匹配 情况

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

(0)

相关推荐

  • 深入浅出MyBatis中映射文件和实体类的关联性

    mybatis的映射文件写法多种多样,不同的写法和用法,在实际开发过程中所消耗的开发时间.维护时间有很大差别,今天我就把我认为比较简单的一种映射文件写法记录下来,供大家修改建议,争取找到一个最优写法~~: 以User对象和UserMap.xml为例讲解,代码如下: User为用户实体类(仅作为讲解,可以只关注引用类型变量,get/set方法省略): import com.google.common.collect.Lists; import com.gukeer.common.persisten

  • Mybatis实体类和表映射问题(推荐)

    本文是小编给大家带来的mybatis中实体类和表映射问题的知识,学习本教程能够快速帮助我们解决字段名与实体类属性名不相同的冲突问题,需要的朋友一起看看吧! 一.准备演示需要使用的表和数据 CREATE TABLE orders( order_id INT PRIMARY KEY AUTO_INCREMENT, order_no VARCHAR(20), order_price FLOAT ); INSERT INTO orders(order_no, order_price) VALUES('a

  • MyBatis查询时属性名和字段名不一致问题的解决方法

    问题 当我们数据库中的字段和实体类中的字段不一致的时候,查询会出问题 数据库字段是 pwd id name pwd 1 张三 123456 2 李四 123456 3 王五 123456 4 赵六 123456 实体类字段是 password public class User { private int id; private String name; private String password; } 查出来结果发现, password 是 null User{id=1, name='张三

  • Mybatis 自动映射(使用需谨慎)

    什么是自动映射? 介绍自动映射之前先看一下手动映射,如下: <resultMap id="orderModelMap1" type="com.javacode2018.chat05.demo7.model.OrderModel"> <id column="id" property="id"/> <result column="userId" property="use

  • mybatis映射和实际类型不一致的问题

    目录 mybatis映射和实际类型不一致 原因分析 小结一下 解决方法 mybatis映射器Mapper(结果映射以及解决列名不一致) 结果映射:(resultMap, resultType) 1. resultType配置结果类型 2. resultMap结果类型 3. 小结一下 mybatis映射和实际类型不一致 项目今天出现个问题,在dao中定义了一个查询,方法的返回值是map并定义了泛型都是String类型,可是方法返回值中还是存在其他的类型. //DAO接口查询 返回类型Map<Str

  • Mybatis映射文件实例详解

     一.输入映射 parameterType 指定输入参数的Java类型,可以使用别名或者类的全限定名.它可以接收简单类型.POJO.HashMap. 1.传递简单类型 根据用户ID查询用户信息: <select id="findUserById" parameterType="int" resultType="com.itheima.mybatis.po.User"> SELECT * FROM USER WHERE id =#{id

  • MyBatis映射文件resultMap元素中使用多个association的方法

    现在有一张订单表t_stockorder,其拥有id.code.client_id.merchandise_id.merchandise_number.order_date.operator_id这些字段,其中client_id关联t_client表中code字段,merchandise_id关联t_merchandise表的code字段,operator_id关联t_employee表的code字段. 现在要通过SQL语句将订单表中t_stockorder的数据全部查询出来,SQL语句如下所示

  • 解决Mybatis映射文件mapper.xml中的注释问题

    目录 Mybatis映射文件mapper.xml的注释问题 报错信息 解决办法 mapper.xml文件中的注释 注释方式 ‘无效的列索引’bug和解决 小结一下 Mybatis映射文件mapper.xml的注释问题 从昨天夜晚9点到今天中午,一直被项目bug所困惑,中间这段时间一直未解决这个问题,也咨询很多群里大佬,也未能解决 有的说是我代码写的有问题,如mapper文件中没有写入参数类型parameterType,也有说是我项目结构目录构建出错,按照他们的建议进行修正,也是未尽人意,启动项目

  • Mybatis映射文件规则实例详解

    目录 1.ORM概念 2.映射文件命名规则 3.Mybatis的两个一致 4.总结创建mybatis的步骤 补充:MyBatis_自定义结果映射规则 总结 在说明映射文件规则之前,先来回顾一下ORM相关概念. 1.ORM概念 ORM(Object Relationship Mapping)对象关系映射 对象:Java的实体类对象 关系:关系型数据库 映射:二者之间的对应关系 字段名和属性名要一一对应才可以,它们的名字要相同,底层调用的是反射机制 Java概念 数据库概念 属性 列,字段 类 表

  • MyBatis映射关系详解

    目录 数据库的配置 一.映射关系一对一 1.映射关系 1 对 1-基本介绍 2.映射关系 1 对 1-映射方式 3.应用实例 3.1方式一 方式二: 通过配置 XxxMapper.xml 的方式来实现下面的 1 对 1 的映射关系,实现级 联查询 , 通过 person 可以获取到对应的 identcard 信息 重点解析: 注解的方式实现 通过注解的方式来实现下面的 1 对 1 的映射关系,实现级联查询 , 通过 person 可以获取到 对应的 identcard 信息 在实际开发中还是 推

  • mybatis映射XML文件详解及实例

    mybatis映射XML文件 一个简单的映射文件: <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" > <mapper namespace="c

  • mybatis 映射文件中if标签判断字符串相等的两种方式

    mybatis 映射文件中,if标签判断字符串相等,两种方式: 因为mybatis映射文件,是使用的ognl表达式,所以在判断字符串sex变量是否是字符串Y的时候, <if test="sex=='Y'.toString()"> <if test = 'sex== "Y"'> 注意: 不能使用 <if test="sex=='Y'"> and 1=1 </if> 因为mybatis会把'Y'解析为字

  • 解决mybatis映射结果集失效的问题

    在开发中可能会遇到这样的问题,使用mybatis进行结果集与实体类之间的关系映射时,可能会出现某些属性映射不上去的情况. 为了方便排查问题我们需要查看mybatis访问数据库SQL信息. 可以在配置Log4J: log4j.logger.com.xxx.dao=TRACE log4j.logger.com.ibatis.common.jdbc.SimpleDataSource = DEBUG log4j.logger.com.ibatis.common.jdbc.ScriptRunner = D

  • 浅谈Mybatis+mysql 存储Date类型的坑

    场景: 把一个时间字符串转成Date,存进Mysql.时间天数会比实际时间少1天,也可能是小时少了13-14小时 Mysql的时区是CST(使用语句:show VARIABLES LIKE '%time_zone%'; 查) 先放总结: 修改方法: 1. 修改数据库时区 2. 在jdbc.url里加后缀 &serverTimezone=GMT%2B8 3. 代码里设置时区,给SimpleDateFormat.setTimeZone(...) 例外:new Date() 可以直接存为正确时间,其他

随机推荐