在 java 中将数据库从 MySQL 更改为 PostgreSQL
Changing database from MySQL to PostgreSQL in java
我之前是运行我的java程序MySQL,一切正常。现在我将程序连接到 PostgreSQL,但它给了我一些错误,我不知道我应该在哪里找到问题以及如何解决它。如果有人能提供帮助,我将不胜感激。
我正在使用:
- Java 15
- Spring 开机
- Tomcat 9
- PostgreSQL 13
- PostgreSQL JDBC 42.2.23
对于 运行 SQL 查询和创建我的数据库表,我正在使用一个映射器存储库,它有一个带有接口的抽象 class 并且我为我的每个 classes.
这是我连接数据库的连接池:
import org.apache.commons.dbcp.BasicDataSource;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
public class ConnectionPool {
private static BasicDataSource ds = new BasicDataSource();
private final static String dbURL = "jdbc:postgresql://...:.../SomeThing?
characterEncoding=utf8";
private final static String dbUserName = "...";
private ConnectionPool() {
}
static {
ds.setDriverClassName("org.postgresql.Driver");
// remote db
ds.setUrl(dbURL);
ds.setUsername(dbUserName);
ds.setPassword(dbPassword);
ds.setMinIdle(1);
ds.setMaxIdle(2000);
ds.setMaxOpenPreparedStatements(2000);
setEncoding();
}
public static Connection getConnection() throws SQLException {
try {
return ds.getConnection();
}catch (Exception e){
ds.setPassword(dbPassword);
return ds.getConnection();
}
}
public static void setEncoding(){
try {
Connection connection = getConnection();
Statement statement = connection.createStatement();
statement.execute("ALTER DATABASE ... CHARACTER SET utf8mb4 COLLATE
utf8mb4_unicode_ci;");
connection.close();
statement.close();
}
catch (SQLException e)
{
System.out.println(e.getMessage());
}
}
}
这是我的课程映射器的示例 class:
public class CourseMapper extends Mapper<Offering, CustomPair> implements ICourseMapper {
private static final String COLUMNS = " code, classCode, name, units, type, instructor, capacity, signedUp, start, end, time ";
private static final String TABLE_NAME = "COURSES";
public CourseMapper(Boolean doManage) throws SQLException {
if (doManage) {
Connection con = ConnectionPool.getConnection();
Statement st = con.createStatement();
st.executeUpdate(String.format("DROP TABLE IF EXISTS %s", TABLE_NAME));
st.executeUpdate(String.format(
"create table %s (\n" +
" code varchar(255) not null,\n" +
" classCode varchar(255) not null,\n" +
" name tinytext not null,\n" +
" units int not null,\n" +
" type tinytext not null,\n" +
" instructor tinytext not null,\n" +
" capacity int not null,\n" +
" signedUp int not null default 0,\n" +
" start tinytext not null,\n" +
" end tinytext not null,\n" +
" time tinytext not null,\n" +
" primary key(code, classCode)\n" +
");",
TABLE_NAME));
st.close();
con.close();
}
}
public CourseMapper() throws SQLException {
}
@Override
protected String getFindStatement(CustomPair id) {
return String.format("select * from %s where %s.%s = %s and %s.%s = %s", TABLE_NAME, TABLE_NAME, "code",
StringUtils.quoteWrapper(id.getArgs().get(0)), TABLE_NAME, "classCode", StringUtils.quoteWrapper(id.getArgs().get(1)));
}
有了这个,我能够在 MySQL 数据库中创建表并执行查询(查找、插入、删除...)
但是,现在我想使用 PostgreSQL 数据库,运行 项目给了我这些错误:
org.postgresql.util.PSQLException: ERROR: syntax error at or near "end"
Position: 304
at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2552)
at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2284)
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:322)
at org.postgresql.jdbc.PgStatement.executeInternal(PgStatement.java:481)
at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:401)
at org.postgresql.jdbc.PgStatement.executeWithFlags(PgStatement.java:322)
at org.postgresql.jdbc.PgStatement.executeCachedSql(PgStatement.java:308)
at org.postgresql.jdbc.PgStatement.executeWithFlags(PgStatement.java:284)
at org.postgresql.jdbc.PgStatement.executeUpdate(PgStatement.java:258)
at org.apache.commons.dbcp.DelegatingStatement.executeUpdate(DelegatingStatement.java:228)
at org.apache.commons.dbcp.DelegatingStatement.executeUpdate(DelegatingStatement.java:228)
at com.internet.engineering.IECA5.repository.Course.CourseMapper.<init>(CourseMapper.java:24)
at com.internet.engineering.IECA5.repository.MzRepository.createAllTables(MzRepository.java:35)
at com.internet.engineering.IECA5.IeCa5Application.main(IeCa5Application.java:18)
org.postgresql.util.PSQLException: ERROR: type "tinytext" does not exist
Position: 67
at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2552)
at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2284)
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:322)
at org.postgresql.jdbc.PgStatement.executeInternal(PgStatement.java:481)
at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:401)
at org.postgresql.jdbc.PgStatement.executeWithFlags(PgStatement.java:322)
at org.postgresql.jdbc.PgStatement.executeCachedSql(PgStatement.java:308)
at org.postgresql.jdbc.PgStatement.executeWithFlags(PgStatement.java:284)
at org.postgresql.jdbc.PgStatement.executeUpdate(PgStatement.java:258)
at org.apache.commons.dbcp.DelegatingStatement.executeUpdate(DelegatingStatement.java:228)
at org.apache.commons.dbcp.DelegatingStatement.executeUpdate(DelegatingStatement.java:228)
at com.internet.engineering.IECA5.repository.Student.StudentMapper.<init>(StudentMapper.java:22)
尽管所有主流关系数据库系统都使用 SQL,但它们各有自己的方言和其他偏离 ISO-9075 SQL 标准的怪癖。您不能只是将项目从 MySQL 提升并转移到 PostgreSQL 并期望一切正常,尤其是数据类型。
堆栈跟踪显示两个不同的问题:
您有一个名为 end
的列,而 end
是一个 reserved word in PostgreSQL(并且在 SQL 标准中),因此它必须是引用可用作列名:"end"
,或在 Java 字符串 \"end\"
.
中
您使用了一种名为 tinytext
的数据类型,它是 MySQL 特有的,在 PostgreSQL 中不存在。根据 MySQL 文档判断,这最多允许 255 个字符,因此 VARCHAR(255)
可以用作替换(尽管给出了列的名称,但看起来其中一些是持续时间,时间或日期时间值,因此您可能要考虑使用更合适的数据类型)。
请记住,您可能 运行 在程序的其他地方遇到其他相关问题。 MySQL 因偏离 SQL 标准而臭名昭著(尽管近年来有所改进),有时 MySQL 允许标准和大多数 SQL 方言不允许的事情允许。
我之前是运行我的java程序MySQL,一切正常。现在我将程序连接到 PostgreSQL,但它给了我一些错误,我不知道我应该在哪里找到问题以及如何解决它。如果有人能提供帮助,我将不胜感激。
我正在使用:
- Java 15
- Spring 开机
- Tomcat 9
- PostgreSQL 13
- PostgreSQL JDBC 42.2.23
对于 运行 SQL 查询和创建我的数据库表,我正在使用一个映射器存储库,它有一个带有接口的抽象 class 并且我为我的每个 classes.
这是我连接数据库的连接池:
import org.apache.commons.dbcp.BasicDataSource;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
public class ConnectionPool {
private static BasicDataSource ds = new BasicDataSource();
private final static String dbURL = "jdbc:postgresql://...:.../SomeThing?
characterEncoding=utf8";
private final static String dbUserName = "...";
private ConnectionPool() {
}
static {
ds.setDriverClassName("org.postgresql.Driver");
// remote db
ds.setUrl(dbURL);
ds.setUsername(dbUserName);
ds.setPassword(dbPassword);
ds.setMinIdle(1);
ds.setMaxIdle(2000);
ds.setMaxOpenPreparedStatements(2000);
setEncoding();
}
public static Connection getConnection() throws SQLException {
try {
return ds.getConnection();
}catch (Exception e){
ds.setPassword(dbPassword);
return ds.getConnection();
}
}
public static void setEncoding(){
try {
Connection connection = getConnection();
Statement statement = connection.createStatement();
statement.execute("ALTER DATABASE ... CHARACTER SET utf8mb4 COLLATE
utf8mb4_unicode_ci;");
connection.close();
statement.close();
}
catch (SQLException e)
{
System.out.println(e.getMessage());
}
}
}
这是我的课程映射器的示例 class:
public class CourseMapper extends Mapper<Offering, CustomPair> implements ICourseMapper {
private static final String COLUMNS = " code, classCode, name, units, type, instructor, capacity, signedUp, start, end, time ";
private static final String TABLE_NAME = "COURSES";
public CourseMapper(Boolean doManage) throws SQLException {
if (doManage) {
Connection con = ConnectionPool.getConnection();
Statement st = con.createStatement();
st.executeUpdate(String.format("DROP TABLE IF EXISTS %s", TABLE_NAME));
st.executeUpdate(String.format(
"create table %s (\n" +
" code varchar(255) not null,\n" +
" classCode varchar(255) not null,\n" +
" name tinytext not null,\n" +
" units int not null,\n" +
" type tinytext not null,\n" +
" instructor tinytext not null,\n" +
" capacity int not null,\n" +
" signedUp int not null default 0,\n" +
" start tinytext not null,\n" +
" end tinytext not null,\n" +
" time tinytext not null,\n" +
" primary key(code, classCode)\n" +
");",
TABLE_NAME));
st.close();
con.close();
}
}
public CourseMapper() throws SQLException {
}
@Override
protected String getFindStatement(CustomPair id) {
return String.format("select * from %s where %s.%s = %s and %s.%s = %s", TABLE_NAME, TABLE_NAME, "code",
StringUtils.quoteWrapper(id.getArgs().get(0)), TABLE_NAME, "classCode", StringUtils.quoteWrapper(id.getArgs().get(1)));
}
有了这个,我能够在 MySQL 数据库中创建表并执行查询(查找、插入、删除...)
但是,现在我想使用 PostgreSQL 数据库,运行 项目给了我这些错误:
org.postgresql.util.PSQLException: ERROR: syntax error at or near "end"
Position: 304
at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2552)
at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2284)
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:322)
at org.postgresql.jdbc.PgStatement.executeInternal(PgStatement.java:481)
at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:401)
at org.postgresql.jdbc.PgStatement.executeWithFlags(PgStatement.java:322)
at org.postgresql.jdbc.PgStatement.executeCachedSql(PgStatement.java:308)
at org.postgresql.jdbc.PgStatement.executeWithFlags(PgStatement.java:284)
at org.postgresql.jdbc.PgStatement.executeUpdate(PgStatement.java:258)
at org.apache.commons.dbcp.DelegatingStatement.executeUpdate(DelegatingStatement.java:228)
at org.apache.commons.dbcp.DelegatingStatement.executeUpdate(DelegatingStatement.java:228)
at com.internet.engineering.IECA5.repository.Course.CourseMapper.<init>(CourseMapper.java:24)
at com.internet.engineering.IECA5.repository.MzRepository.createAllTables(MzRepository.java:35)
at com.internet.engineering.IECA5.IeCa5Application.main(IeCa5Application.java:18)
org.postgresql.util.PSQLException: ERROR: type "tinytext" does not exist
Position: 67
at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2552)
at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2284)
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:322)
at org.postgresql.jdbc.PgStatement.executeInternal(PgStatement.java:481)
at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:401)
at org.postgresql.jdbc.PgStatement.executeWithFlags(PgStatement.java:322)
at org.postgresql.jdbc.PgStatement.executeCachedSql(PgStatement.java:308)
at org.postgresql.jdbc.PgStatement.executeWithFlags(PgStatement.java:284)
at org.postgresql.jdbc.PgStatement.executeUpdate(PgStatement.java:258)
at org.apache.commons.dbcp.DelegatingStatement.executeUpdate(DelegatingStatement.java:228)
at org.apache.commons.dbcp.DelegatingStatement.executeUpdate(DelegatingStatement.java:228)
at com.internet.engineering.IECA5.repository.Student.StudentMapper.<init>(StudentMapper.java:22)
尽管所有主流关系数据库系统都使用 SQL,但它们各有自己的方言和其他偏离 ISO-9075 SQL 标准的怪癖。您不能只是将项目从 MySQL 提升并转移到 PostgreSQL 并期望一切正常,尤其是数据类型。
堆栈跟踪显示两个不同的问题:
您有一个名为
中end
的列,而end
是一个 reserved word in PostgreSQL(并且在 SQL 标准中),因此它必须是引用可用作列名:"end"
,或在 Java 字符串\"end\"
.您使用了一种名为
tinytext
的数据类型,它是 MySQL 特有的,在 PostgreSQL 中不存在。根据 MySQL 文档判断,这最多允许 255 个字符,因此VARCHAR(255)
可以用作替换(尽管给出了列的名称,但看起来其中一些是持续时间,时间或日期时间值,因此您可能要考虑使用更合适的数据类型)。
请记住,您可能 运行 在程序的其他地方遇到其他相关问题。 MySQL 因偏离 SQL 标准而臭名昭著(尽管近年来有所改进),有时 MySQL 允许标准和大多数 SQL 方言不允许的事情允许。