网站制作视频教学wordpress cos
2026/3/27 5:59:39 网站建设 项目流程
网站制作视频教学,wordpress cos,新余做网站的,个人网站系统0、前言原项目框架 SpringBoot MybatisPlus Mysql1、切换流程1.1、项目引入postgresql驱动包由于我们要连接新的数据库#xff0c;理所当然的要引入该数据库的驱动包#xff0c;这与mysql驱动包类似dependencygroupIdorg.postgresql/groupIdar…0、前言原项目框架 SpringBoot MybatisPlus Mysql1、切换流程1.1、项目引入postgresql驱动包由于我们要连接新的数据库理所当然的要引入该数据库的驱动包这与mysql驱动包类似dependency groupIdorg.postgresql/groupId artifactIdpostgresql/artifactId /dependency1.2、修改jdbc连接信息之前用的是mysql协议现在改成postgresql连接协议spring: datasource: # 修改驱动类 driver-class-name: org.postgresql.Driver # 修改连接地址 url: jdbc:postgresql://数据库地址/数据库名?currentSchema模式名useUnicodetruecharacterEncodingutf8serverTimezoneGMT%2B8useSSLfalsepostgres相比mysql多了一层模式的概念 一个数据库下可以有多个模式。 这里的模型名等价于以前的mysql的数据库名。如果不指定默认是public。这时切换流程基本就改造完了无非就是代码修改下连接信息。但是你以为到这就结束了一堆坑还在后面呢毕竟是两个完全不同数据库在语法层面还有很多差别接下来就是修改代码里的sql语法踩坑2、踩坑记录2.1、TIMESTAMPTZ类型与LocalDateTime不匹配异常信息:PSQLException: Cannot convert the column of type TIMESTAMPTZ to requested type java.time.LocalDateTime.如果postgres表的字段类型是TIMESTAMPTZ但是java对象的字段类型是LocalDateTime 这时会无法转换映射上。postgres表字段类型应该用timestamp或者 java字段类型用Date2.2、参数值不能用双引号错误例子:WHERE name jay WHERE name jay这里参数值jay 应该改成单引号 jay2.3、字段不能用包起来错误例子WHERE name jay WHERE name jay这里的字段名name不能用选取2.4、json字段处理语法不同-- mysql语法: WHERE keywords_json-$.name LIKE CONCAT(%, ?, %) -- postgreSQL语法: WHERE keywords_json -name LIKE CONCAT(%, ?, %)获取json字段子属性的值mysql是用- $.xxx的语法去选取的 而 postgreSQL 得用-xx语法选择属性2.5、convert函数不存在postgreSQL没有convert函数用CAST函数替换-- mysql语法: select convert(name, DECIMAL(20, 2)) -- postgreSQL语法: select CAST(name as DECIMAL(20, 2))2.6、force index 语法不存在-- mysql语法 select xx FROM user force index(idx_audit_time)mysql可以使用force index强制走索引 postgres没有建议去掉2.7、ifnull 函数不存在postgreSQL没有ifnull函数用COALESCE函数替换异常信息cause: org.postgresql.util.PSQLException: ERROR: function ifnull(numeric, numeric) does not exist2.8、date_format 函数不存在异常信息Cause: org.postgresql.util.PSQLException: ERROR: function date_format(timestamp without time zone, unknown) does not existpostgreSQL没有date_format函数用to_char函数替换替换例子:// %Y YYYY // %m MM // %d DD // %H HH24 // %i MI // %s SS to_char(time,YYYY-MM-DD) DATE_FORMAT(time,%Y-%m-%d) to_char(time,YYYY-MM) DATE_FORMAT(time,%Y-%m) to_char(time,YYYYMMDDHH24MISS) DATE_FORMAT(time,%Y%m%d%H%i%s)2.9、group by语法问题异常信息Cause: org.postgresql.util.PSQLException: ERROR: column r.name must appear in the GROUP BY clause or be used in an aggregate functionpostgreSQL 的 selectd的字段必须是group by的字段里的 或者使用了聚合函数。mysql则没有这个要求非聚合列会随机取值错误例子select name, age, count(*) from user group by age, score这时select name是错误的 应为group by里没有这个字段要么加上要么变成select min(name)2.10、事务异常问题异常信息# Cause: org.postgresql.util.PSQLException: ERROR: current transaction is aborted, commands ignored until end of transaction block ; uncategorized SQLException; SQL state [25P02]; error code [0]; ERROR: current transaction is aborted, commands ignored until end of transaction block; nested exception is org.postgresql.util.PSQLException: ERROR: current transaction is aborted, commands ignored until end of transaction blockPostgres数据库中同一事务中如果某次数据库操作中出错的话那这个事务以后的数据库操作都会出错。正常来说不会有这种情况但是如果有人去捕获了事务异常后又去执行数据库操作就会导致这个问题。mysql貌似不会有这个问题下面就是错误的代码例子靠异常去走逻辑。解决办法就是不要靠数据库的异常去控制逻辑手动判断。2.11 类型转换异常 大头这个可以说是最坑的 因为mysql是支持自动类型转换的。在表字段类型和参数值之间如果类型不一样也会自动进行转换。而postgreSQL是强数据类型字段类型和参数值类型之间必须一样否则就会抛出异常。这时候解决办法一般有两种手动修改代码里的字段类型和传参类型保证 或者 postgreSQL表字段类型反正保证双方一一对应添加自动隐式转换函数达到类似mysql的效果布尔值和int类型类型转换错误1、select查询时的转换异常信息Cause: org.postgresql.util.PSQLException: ERROR: operator does not exist: smallint booleanSELECT xx fom xx WHERE enable ture错误原因enable字段是smallint类型查询却传了一个布尔值类型2、update更新时的转换异常信息Cause: org.postgresql.util.PSQLException: ERROR: column name is of type smallint but expression is of type booleanupdate from xx set name false where name true错误原因在update/insert赋值语句的时候字段类型是smallint但是传参却是布尔值类型解决办法postgres数据库添加boolean - smallint的自动转换逻辑-- 创建函数1 smallint到boolean到转换函数 CREATEORREPLACEFUNCTIONsmallint_to_boolean(i int2) RETURNSpg_catalog.boolAS $BODY$ BEGIN RETURN (i::int2)::integer::bool; END; $BODY$ LANGUAGE plpgsql VOLATILE -- 创建赋值转换1 createcast (SMALLINTasBOOLEAN) withfunction smallint_to_boolean as ASSIGNMENT; -- 创建函数2 boolean到smallint到转换函数 CREATEORREPLACEFUNCTIONboolean_to_smallint(bbool) RETURNSpg_catalog.int2AS $BODY$ BEGIN RETURN (b::boolean)::bool::int; END; $BODY$ LANGUAGE plpgsql VOLATILE -- 创建隐式转换2 createcast (BOOLEANasSMALLINT) withfunction boolean_to_smallint as implicit;如果想重来可以删除掉上面创建的函数和转换逻辑-- 删除函数 drop function smallint_to_boolean -- 删除转换 drop CAST (SMALLINT as BOOLEAN)主要不要乱添加隐式转换函数可能导致Could not choose a best candidate operator异常 和# operator is not unique异常 就是在操作符比较的时候有多个转换逻辑不知道用哪个了死循环了3、PostgreSQL辅助脚本3.1、批量修改timestamptz脚本批量修改表字段类型timestamptz为timestamp 因为我们说过前者无法与LocalDateTime对应上❝pstimestamp without time zone 就是 timestamptimestamp with time zone 就是 timestamptz❞DO $$ DECLARE rec RECORD; BEGIN FOR rec IN SELECT table_name, column_name,data_type FROM information_schema.columns where table_schema 要处理的模式名 AND data_type timestamp with time zone LOOP EXECUTE ALTER TABLE || rec.table_name || ALTER COLUMN || rec.column_name || TYPE timestamp; END LOOP; END $$;3.2、批量设置时间默认值脚本批量修改模式名下的所有字段类型为timestamp的并且字段名为create_time或者update_time的字段的默认值为CURRENT_TIMESTAMP-- 注意 || 号拼接的后面的字符串前面要有一个空格 DO $$ DECLARE rec RECORD; BEGIN FOR rec INSELECT table_name, column_name,data_type FROM information_schema.columns where table_schema 要处理的模式名 AND data_type timestamp without time zone -- 修改的字段名 and column_name in (create_time,update_time) LOOP EXECUTEALTER TABLE || rec.table_name || ALTER COLUMN || rec.column_name || SET DEFAULT CURRENT_TIMESTAMP;; ENDLOOP; END $$;4、注意事项1、将数据表从mysql迁移postgres 要注意字段类型要对应不要变更*2、原先是tinyint的就变samllint类型不要是bool类型有时代码字段类型可能对应不上3、如果java字段是LocalDateTime原先mysql时间类型到postgres后不要用TIMESTAMPTZ类型4、mysql一般用tinyint类型和java的Boolean字段对应并且在查询和更新时支持自动转换但是postgres是强类型不支持如果想无缝迁移postgres内部就新增自动转换的隐式函数但是缺点是每次部署postgres后都要去执行一次脚本。如果不想这样只能修改代码的所有表对象的字段类型和传参类型保证与postgres数据库的字段类型对应但是有些依赖的框架底层自己操作数据库可能就无法修改源码了只能修改数据库表字段类型了

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询