我的代码是用java编写的,我对java很新,所以我希望我的解释是正确的: 我有一个java编写的Web服务,可以使用数据库。 数据库类型可以是PostgreSQL和mysql。 所以我的webservice使用两个数据库的JDBC连接。 我的一个数据库表是表网址, 对于postgressql,它是这样创建的:
CREATE TABLE urls (
id serial NOT NULL primary key,
url text not null,
type integer not null);
对于mysql,它是这样创建的:
CREATE TABLE IF NOT EXISTS URLS (
id INTEGER primary key NOT NULL AUTO_INCREMENT,
url varchar (1600) NOT NULL,
type INTEGER NOT NULL );
当我尝试向此表插入数据时,我使用了一个名为urls的实体: 这个实体有:
private BigDecimal id;
private String url;
private BigInteger type;
当我尝试将值插入urls表时,我将值分配给url实体,同时将id保留为NULL,因为它是mysql的AUTO_INCREMENT和postgres的serial。 该查询适用于我的sql,但是对于postgress失败了。 在postgres服务器日志中,我可以看到以下错误:
null value in column "id" violates not-null constraint
因为我发送NULL作为id值。 我发现为了使查询起作用,我应该使用这个查询:
INSERT INTO URLS(ID, TYPE, URL) VALUES(DEFAULT, 1, 'DED'); or this one:
INSERT INTO URLS(TYPE, URL) VALUES(1, 'DED'); or this one:
而不是这个,我使用:
INSERT INTO URLS(ID, TYPE, URL) VALUES(NULL, 1, 'DED');
所以我的问题是,
答案 0 :(得分:2)
如果在插入查询中指定列名,则postgres不会采用默认值。所以你应该使用你的第二个插入查询。
INSERT INTO URLS(TYPE, URL) VALUES(1, 'DED');
这种语法对于postgres和MySQL都是正确的。
这应解决您的问题(1)和(3)。对于(2)请勿删除实体中的id字段。此id将成为实体特定对象的数据库行的链接。
答案 1 :(得分:1)
1 - 我认为在id字段中使用Long或long类型而不是BigDecimal是合适的。
2 - 是的,它通常会有所帮助,但会降低可移植性。顺便说一句,使用像Hibernate这样的ORM框架可能是个不错的选择。
3 - 集成测试通常有帮助,您可能希望采用TDD风格开发。
答案 2 :(得分:1)
使用此声明时:
INSERT INTO URLS(ID, TYPE, URL) VALUES(NULL, 1, 'DED');
您告诉数据库您要在列ID中插入NULL值,而Postgres就是这样做的。与MySQL不同,PostgreSQL绝不会隐含地替换您提供的值与完全不同的值(实际上除MySQL以外的所有DBMS都是这样工作的 - 除非当然涉及某些触发器)。
所以唯一的解决方案是实际使用不为ID列提供值的INSERT。这应该适用于MySQL。