使用mybatis + postgreSql 中遇到的问题

CodeLumina
• 阅读 4620

问题一:字段名不存在

背景是:进行mapper的insert单元测试的时候出了问题
执行如下语句的时候出现了问题:

Test entity = new Test();
entity.setName(new RandomString().nextString());
entity.setFatherTestId(new RandomString().nextString());

Integer insNum = testMapper.insert(entity);

这里运用了mapper自带的insert方法向数据库中插入数据。

在用mapper进行插入的时候后,报了这样的错误: 字段名不存在。

使用mybatis + postgreSql 中遇到的问题

但是去数据表中查看,实际上是有fatherTestId这个字段的

就疑惑为什么后台会找不到这个字段


并仔细看红色的的报错,后台说fatherid这个字段找不到。
这里我发现了端倪,数据库中表定义的是fatherTestId, i和T字母是大写的。

猜测是由于数据库字段大小写的问题

之后去谷歌之后找到了答案:

原因:在于PostgreSQL对表名、字段名都是区分大小写的。在执行SQL时,那么不管你的SQL中字段是大写还是小写,最后都会默认转为小写去执行。

解决:

1. 数据库字段名改为小写。或者用下划线_分割。
后来改为下划线后运行正常

2. 写sql语句的时候,对表名或者字段名加上双引号

定义SQL的时候,对表名及字段名加上双引号,可以防止大写字段被转为小写去执行。

因为在PGSQL中,默认对SQL语句进行抹去双引号和大写转小写的其中一个且抹去双引号优先级比较高,因此当大写字段被加上双引号,只进行了抹去双引号的处理而不会再被转为小写了。

使用mybatis + postgreSql 中遇到的问题

例如这样, 加上双引号。


最后由于我这里使用的是mapper自带的insert函数来进行数据插入,并没有自己写sql语句。
所以最后采用了第一种方式解决。

问题二:char(32)类型字段,查询出来的数据带有空格

Integer insNum = testMapper.insert(entity);
Assert.isTrue(insNum.equals(1), "insert success");

String id = entity.getId();
Test getEntity = testMapper.selectById(id);;
Assert.isTrue(getEntity.getName().equals(entity.getName()), "name not equal");

在后台单元测试的时候,进行了断言:插入的数据和查询出来的数据相同。

也就是说,将一条数据插入到数据库中,再将其查询出来,判断这两个数据的属性都相同。

但是单元测试一直没通过

在代码中打断点测试中发现,发现从数据库中查询出来的数据都带有空格。如下图。

使用mybatis + postgreSql 中遇到的问题

猜测是因为postgresql在保存的时候会,自动将数据长度用空格补充至32位。

结果用testMapper自带的selectById方法查询出数据的时候,就会带有空格。

如果是这样的话,用mapper查询数据出来之后,还需要用trim()函数将空格逐个去除。

同时我找到了一篇使用了postgreSql的建议, 里面也提到了使用char(n)的一些弊端。
https://juejin.cn/post/684490...

使用mybatis + postgreSql 中遇到的问题

使用mybatis + postgreSql 中遇到的问题


同时也提到了不要使用大写字母作为表名
使用mybatis + postgreSql 中遇到的问题

mybatis + spring boot 的基本使用

以新建为例:

controller层:与以前使用差不多,都是直接调用serivice层

  @Autowired
  DictionaryService dictionaryService;

  @ApiOperation(value = "新建字典")
  @PostMapping("")
  public Dictionary addDictionary(@RequestBody Dictionary dictionary) {
   return dictionaryService.saveDictionary(dictionary);
  }

serivce层:

@Service
public class DictionaryServiceImpl extends ServiceImpl<DictionaryMapper, Dictionary> implements DictionaryService {

  @Autowired
  DictionaryMapper dictionaryMapper;

  @Override
  public Dictionary saveDictionary(Dictionary dictionary) {
    Integer insNum = dictionaryMapper.insert(dictionary);
    Assert.isTrue(insNum.equals(1), "insert success");

    String id = dictionary.getId();
    Dictionary getDictionary = dictionaryMapper.selectById(id);
    return  getDictionary;
  }

在使用Mapper内置的insert函数的时候,insert函数返回的是:插入该数据后受影响的数据条数。 而不是像jpa那样, 返回的是插入后的实体。

所以,如何使它返回插入后的实体呢?

在经过单元测试时,发现

在执行insert函数之前,实体的id为null。在执行完insert函数之后,实体的id有了值。

使用mybatis + postgreSql 中遇到的问题

使用mybatis + postgreSql 中遇到的问题

所以可以猜想到,在执行完insert函数之后,数据库的值会同步到实体中。 也就是说我们得到了id

使用mybatis + postgreSql 中遇到的问题

即便我们不放心,既然我们已经获取到了id的值。 我们还可以用selectById函数,再从数据库查询一遍,来确保它是数据库保存的值。

String id = dictionary.getId();
Dictionary getDictionary = dictionaryMapper.selectById(id);

整体的单元测试如下:

@Autowired
  DictionaryMapper dictionaryMapper;

  Dictionary getDictionary() {
    Dictionary dictionary = new Dictionary();
    dictionary.setKey(new RandomString().nextString());
    dictionary.setRemarks(new RandomString().nextString());
    dictionary.setValue(new RandomString().nextString());
    dictionary.setName(new RandomString().nextString());

    return dictionary;
  }

  @Test
  @DisplayName("插入一条记录并获取")
  void insertOne() {
    Dictionary dictionary = getDictionary();

    Integer insNum = dictionaryMapper.insert(dictionary);
    Assert.isTrue(insNum.equals(1), "insert success");

    String id = dictionary.getId();
    Dictionary getDictionary = dictionaryMapper.selectById(id);

    Assert.isTrue(getDictionary.getName().trim().equals(dictionary.getName()), "Name not equal");
    Assert.isTrue(getDictionary.getRemarks().trim().equals(dictionary.getRemarks()), "remarks not equal");
    Assert.isTrue(getDictionary.getValue().trim().equals(dictionary.getValue()), "value not equal");
    Assert.isTrue(getDictionary.getKey().trim().equals(dictionary.getKey()), "key not equal");

  }

自定义综合查询

Dao层: 定义根据name模糊查询,获取所有实体

public interface DictionaryMapper extends BaseMapper<Dictionary> {

  List<Dictionary> getByName(String name);

}

xml文件:
使用xml查询,与jpa的区别就是需要自己写sql语句。 虽然不方便,但是留给了我们很大的操作空间。

<?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="com.record.server.mapper.DictionaryMapper">

    <!-- 通用查询映射结果 -->
    <resultMap id="BaseResultMap" type="com.record.server.model.Dictionary">
        <id column="id" property="id" />
        <result column="key" property="key" />
        <result column="name" property="name" />
        <result column="remarks" property="remarks" />
        <result column="value" property="value" />
    </resultMap>

    <!-- 通用查询结果列 -->
    <sql id="Base_Column_List">
        id, key, name, remarks, value
    </sql>

    <select id="getByName" resultMap="BaseResultMap">
        select *
        from t_dictionary
        WHERE name LIKE '%${name}%'
    </select>


</mapper>
点赞
收藏
评论区
推荐文章
美凌格栋栋酱 美凌格栋栋酱
6个月前
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(
Stella981 Stella981
3年前
Git pull的时候遇到问题
转载:https://www.jianshu.com/p/7b1c58e0a9ef(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Fwww.jianshu.com%2Fp%2F7b1c58e0a9ef)使用git从远程pull代码时报错:error:Thefollowing
Stella981 Stella981
3年前
Spring boot jackson 时间格式问题
这个问题是具体表现是这样的:SpringbootApplication 直接使用IDEA运行没有任何问题,使用maven打包也不存在问题,但是在打包之后执行时一直提示出现错误。错误的信息大致如下:ErrorstartingApplicationContext.Todisplaytheautoconfiguration
Stella981 Stella981
3年前
SpringBoot整合Redis乱码原因及解决方案
问题描述:springboot使用springdataredis存储数据时乱码rediskey/value出现\\xAC\\xED\\x00\\x05t\\x00\\x05问题分析:查看RedisTemplate类!(https://oscimg.oschina.net/oscnet/0a85565fa
Easter79 Easter79
3年前
Springboot2 Jpa关于分页PageRequest
Ⅰ公司做项目,都是使用Mybatis,个人不太喜欢xml的方式,自然也尝试无xml的Mybatis,在之前写的一篇多数据源Mybatis无xml配置.不废话,本篇记录使用JPA遇到的问题笔记.Ⅱ写到Dao层,继承JpaRepository,实现分页时候的问题.publicinterfaceHelloRepository
Stella981 Stella981
3年前
OpenJDK11与Spring Cloud Finchley的不兼容问题与解决
本文的环境:OpenJDK11.0.4,SpringCloudfinchleySR4,SpringBoot2.0.3最近遇到了一个问题,在feign调用的时候,时常会出现这样一个奇怪的错误:2019100708:00:00.620ERRORxxx,e1ba4c7540954aa3,871b99c4576d42e3
Easter79 Easter79
3年前
SpringBoot整合Redis乱码原因及解决方案
问题描述:springboot使用springdataredis存储数据时乱码rediskey/value出现\\xAC\\xED\\x00\\x05t\\x00\\x05问题分析:查看RedisTemplate类!(https://oscimg.oschina.net/oscnet/0a85565fa
Stella981 Stella981
3年前
Faied to run MSBuild commond CmakeError
问题1:FaiedtorunMSBuildcommondCmakeError想要用cmake编译一个slam的工程,因为是新电脑,编译的时候遇到了这个问题首先工程的cmake文件是没有问题的,因为我在以前的电脑上可以正常的编译可使用,而在这里却出现了问题,查看了资料后解决方法如下:我的cmake版本是cmake3.13,据说很多
Stella981 Stella981
3年前
Hibernate纯sql查询结果和该sql在数据库直接查询结果不一致
问题:今天在做一个查询的时候发现一个问题,我先在数据库实现了我需要的sql,然后我在代码中代码:selectdistinctd.id,d.name,COALESCE(c.count_num,0),COALESCE(c.count_fix,0),COALESCE(c
Python进阶者 Python进阶者
2年前
os.listdir()读出来的文件顺序和本地的顺序不一致,应该怎么做呢?
大家好,我是皮皮。一、前言前几天在帮助粉丝解决问题的时候,遇到一个简单的小需求,这里拿出来跟大家一起分享,后面再次遇到的时候,可以从这里得到灵感。二、需求澄清问题如下所示:问题截图如下所示:三、实现过程这里【崔峰】给了一个思路,使用编码的方式进行解决:一开
Python进阶者 Python进阶者
1年前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这