我想用JDBC将数据插入PostgreSQL,并且数据包含一个自定义类型的数组。当我尝试插入并出现错误时。
谁能指出我在哪里做错了?
String query = "INSERT INTO fitness_club (club_id, club_brand, club_name, latitude, longitude, club_status, club_home_url, address, open_hour) VALUES(?, ?::fitness_brand, ?, ?, ?, ?, ?, ?, ?)";
PreparedStatement pst = conn.prepareStatement(query);
pst.setInt(1, firstClub.getClubId());
pst.setString(2, firstClub.getBrand().toString());
pst.setString(3, firstClub.getDescription());
pst.setDouble(4, firstClub.getLatitude());
pst.setDouble(5, firstClub.getLongitude());
pst.setInt(6, firstClub.getClubStatus());
pst.setString(7, firstClub.getClubHomeUrl());
pst.setString(8, firstClub.getAddress());
Array arrayOpenHour = conn.createArrayOf("open_hour", firstClub.getOpenHours().toArray());
pst.setArray(9, arrayOpenHour);
ResultSet saveRS = pst.executeQuery();
这是错误消息
org.postgresql.util.PSQLException: ERROR: malformed record literal: "OpenHour@342c38f8"
Detail: Missing left parenthesis.
at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2510)
at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2245)
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:311)
自定义类型
public class OpenHour {
DayOfWeek day;
String time;
}
数据表
create table fitness_club
(
club_uid uuid not null
constraint fitness_club_pkey
primary key,
club_brand fitness_brand not null,
club_id integer not null,
club_name varchar(500) not null,
latitude double precision not null,
longitude double precision not null,
club_status integer,
club_home_url varchar(500),
zip_code varchar(500),
address varchar(500),
city varchar(500),
state us_state,
open_hour open_hour[],
constraint brand_id_constrain
unique (club_brand, club_id)
);
create type open_hour as
(
day week_day,
hours varchar(50)
);
其他类型使用的自定义类型
create type week_day as enum ('MONDAY', 'TUESDAY', 'WEDNESDAY', 'THURSDAY', 'FRIDAY', 'SATURDAY', 'SUNDAY');
我有相同的错误,似乎是createArrayOf中的序列化问题。我更改了解决方案,以JSON格式发送了文本。
我分享我的解决方案,希望它对您有用。
1.-模型
订购
@Getter
@Setter
@ToString
public class Order {
private String orderId;
private String customerId;
private Date createdAt;
private List<OrderProduct> orderProductList;
private Double amountOrder;
public Double getAmountOrder() {
return orderProductList.stream().mapToDouble(OrderProduct::getAmount).sum();
}
}
OrderProduct
@Getter
@Setter
@ToString
@AllArgsConstructor
public class OrderProduct implements Serializable {
private static final long serialVersionUID = 1L;
private int orderProductId;
private int quantity;
private String productId;
private Double productPrice;
Double getAmount() {
return productPrice.doubleValue() * this.getQuantity();
}
}
2.-连接并将数据发送到Postgresql,检查参数5
@Repository
public class OrderRepositoryAdapter implements CreateOrderPort
{
@Autowired
private JdbcTemplate jdbcTemplate;
@Override
public void createOrder(Order order) throws GlobalException {
final String procedureCall = "{ ? = call create_order(?, ?, ?, ?)}";
try (Connection connection = jdbcTemplate.getDataSource().getConnection();
CallableStatement callableStatement = connection.prepareCall(procedureCall)
) {
Gson gson = new Gson();
String json = gson.toJson(order.getOrderProductList());
callableStatement.registerOutParameter(1, Types.BIGINT);
callableStatement.setString(2, order.getCustomerId());
callableStatement.setTimestamp(3, new java.sql.Timestamp(order.getCreatedAt().getTime()));
callableStatement.setDouble(4, order.getAmountOrder());
callableStatement.setString(5, json);
callableStatement.execute();
order.setOrderId(Long.toString(callableStatement.getLong(1)));
} catch (Exception e) {
throw new GlobalException("Exception createOrder: " + e.getMessage());
}
}
}
3- Postgresql中的函数,检查参数“ p_order_product”
CREATE OR REPLACE FUNCTION public.create_order(
p_customer_id character varying,
p_created_at timestamp with time zone,
p_amount_order double precision,
p_order_product text)
RETURNS bigint
LANGUAGE 'plpgsql'
AS $BODY$
DECLARE
p_order_id bigint;
p_order_product_id bigint;
p_json json;
BEGIN
p_order_id := nextval('order_id_seq');
INSERT INTO public."ORDERS"(
order_id, customer_id, created_at, amount_order)
VALUES (p_order_id, p_customer_id, p_created_at, p_amount_order);
FOR p_json IN SELECT * FROM json_array_elements(p_order_product::json)
LOOP
p_order_product_id := nextval('order_product_id_seq');
INSERT INTO public."ORDERS_PRODUCTS"(
order_product_id, quantity, product_id, product_price, order_id)
VALUES (p_order_product_id, CAST (p_json->>'quantity' AS bigint) , p_json->>'productId', CAST(p_json->>'productPrice' AS double precision), p_order_id);
END LOOP;
RETURN p_order_id;
END;
$BODY$;
4.- API剩余
http://localhost:3002/v1/orders
{
"customerId":"5ed047dda2923f1ac2c64463",
"createdAt":"2020-06-06T00:10:12",
"orderProductList":
[{
"quantity":"2",
"productId":"5ed31ddb669529409edc2fd0",
"productPrice": 1099.51
},{
"quantity":"1",
"productId":"5ed31cb5669529409edc2fcf",
"productPrice": 2199.99
}]
}
5.- Postgresql中的表
6.-您可以在我的GitHub存储库中查看完整的示例
https://github.com/JonathanM2ndoza/Hexagonal-Architecture-DDD/tree/master/Order