问题概况:Java中如何接收PG中Interval类型数据?
问题产生原因:
我负责的一个SpringBoot项目的数据源是PG数据库,然后我在配置Mybaits-plus的实体类时,其中一个数据字段的类型是Interval类型,然后我就思考Java中可以用什么类型接受?常用的数据类型里并没有能够替代PG中Interval类型的,直到我找到如下解决方案:
解决方案:
Java中没有可用的数据类型来进行接收,我们可以用String来接收,在需要用相关功能的地方使用工具类来实现功能
-
引入Maven依赖
<dependency> <groupId>org.postgresql</groupId> <artifactId>postgresql</artifactId> <version>9.4-1206-jdbc42</version> </dependency>
-
使用org.postgresql.util.PGInterval工具类实现Interval的取时分秒粒度的功能
我选取了部分工具类源码:
public class PGInterval extends PGobject implements Serializable, Cloneable { private static final int MICROS_IN_SECOND = 1000000; private int years; private int months; private int days; private int hours; private int minutes; private int wholeSeconds; private int microSeconds; public PGInterval() { this.setType("interval"); } public PGInterval(String value) throws SQLException { this(); this.setValue(value); } ....... public void setValue(String value) throws SQLException { boolean PostgresFormat = !value.startsWith("@"); if (value.startsWith("P")) { this.parseISO8601Format(value); } else if (!PostgresFormat && value.length() == 3 && value.charAt(2) == '0') { this.setValue(0, 0, 0, 0, 0, 0.0D); } else { int years = 0; int months = 0; int days = 0; int hours = 0; int minutes = 0; double seconds = 0.0D; try { String valueToken = null; value = value.replace('+', ' ').replace('@', ' '); StringTokenizer st = new StringTokenizer(value); for(int i = 1; st.hasMoreTokens(); ++i) { String token = st.nextToken(); if ((i & 1) == 1) { int endHours = token.indexOf(58); if (endHours == -1) { valueToken = token; } else { int offset = token.charAt(0) == '-' ? 1 : 0; hours = nullSafeIntGet(token.substring(offset + 0, endHours)); minutes = nullSafeIntGet(token.substring(endHours + 1, endHours + 3)); int endMinutes = token.indexOf(58, endHours + 1); if (endMinutes != -1) { seconds = nullSafeDoubleGet(token.substring(endMinutes + 1)); } if (offset == 1) { hours = -hours; minutes = -minutes; seconds = -seconds; } valueToken = null; } } else if (token.startsWith("year")) { years = nullSafeIntGet(valueToken); } else if (token.startsWith("mon")) { months = nullSafeIntGet(valueToken); } else if (token.startsWith("day")) { days = nullSafeIntGet(valueToken); } else if (token.startsWith("hour")) { hours = nullSafeIntGet(valueToken); } else if (token.startsWith("min")) { minutes = nullSafeIntGet(valueToken); } else if (token.startsWith("sec")) { seconds = nullSafeDoubleGet(valueToken); } } } catch (NumberFormatException var17) { throw new PSQLException(GT.tr("Conversion of interval failed", new Object[0]), PSQLState.NUMERIC_CONSTANT_OUT_OF_RANGE, var17); } if (!PostgresFormat && value.endsWith("ago")) { this.setValue(-years, -months, -days, -hours, -minutes, -seconds); } else { this.setValue(years, months, days, hours, minutes, seconds); } } } }
使用方法便是,先利用String将数据暂时接收下来,在需要取出时、分、秒等等粒度的场景时,使用PGInterval的setValue(接收下的String),然后取出对应粒度的属性便可,可以直接将String原字符串以PGInerval构造函数传入,可以看到源码里构造函数调用了setValue()。
譬如:
//AlertSetting是我的实体类,executionTime属性使用String类型 PGInterval execution = new PGInterval(alertSetting.getExecutionTime()); //如此便可取出PGInterval的粒度属性 System.out.println(execution.getSeconds());
如上所述,便可以解决Java中处理PG数据库中Interval类型数据的问题
ps:说实话,云同桌系列鸽了蛮久啦,哈哈~,没得办法,实习之后又得忙毕设,每次稿子都是用零散时间写得,一个月都没写出一篇完整的稿子,等我把毕设忙完毕业之后,一定更新后续SpringMVC的内容