我是网站编程的新手(等等程序和数据库之间的关系),我遇到了一个问题。
我创建了一个在线网上商店,可以在数据库中交互并保存每个信息。
问题出现在购物车上:我希望当用户在购物车中添加产品时,他可以退出,当他再次登录时,他应该发现购物车不变,所以我有一个产品作为对象{ {1}} Product
在数据库中是唯一的。
我有一个与数据库交互的包DAO,有这种方法:
int productID
班级/**
* Queries the database in search of the shopping cart of the indicated user
* @param userMail indicates the user from which take the shopping cart
* @return the Shopping Cart of the user
* @throws ClassNotFoundException if an error occurs with the connection to the database
*/
public static ShoppingCart getShoppingCartFromDatabase(String userMail) throws ClassNotFoundException {
ShoppingCart updatedCart = new ShoppingCart(userMail);
Class.forName("org.postgresql.Driver");
try (Connection con = DriverManager.getConnection(JDBC_URL, JDBC_USERNAME, JDBC_PASSWORD)){
try (PreparedStatement pst = con.prepareStatement(
"SELECT * FROM " + TABLE_NAME + " "
+ "WHERE user = ?")) {
pst.clearParameters();
pst.setString(1, userMail);
ResultSet rs = pst.executeQuery();
while (rs.next()) {
String userMail = rs.getString("user");
int IDProduct = rs.getInt("product");
int npieces = rs.getInt("npieces");
//HERE THE PROBLEM
updatedCart.addToCart(IDProduct, npieces);
}
} catch (SQLException e) {
System.out.println("Errorin query: " + e.getMessage());
}
} catch (SQLException e){
System.out.println("Error in connection: " + e.getMessage());
}
return updatedCart;
}
:
ShoppingCart
班级public class ShoppingCart {
private final String userMail;
private final List<ProductInCart> productsInCart;
/**
* Constructor of ShoppingCart.
* It creates a new ProductInCart item and assigns it to the list of ShoppingCart
* @param mail is the mail of the user, that is the owner of the shopping cart
*/
public ShoppingCart(String mail){
this.userMail = mail;
this.productsInCart = new ArrayList<ProductInCart>();
}
//other methods, such as get and set etc
}
:
ProductInCart
问题是方法public class ProductInCart{
private final Product product;
private int numberOfProducts;
/**
* Class constructor.
* @param product Product to be added
* @param num Number of that item in the cart
*/
public ProductInCart(Product product, int num){
this.product = product;
this.numberOfProducts = num;
}
//Other methods such as get and set, etc
}
添加了public void addToCart(Product product, int num)
类型的产品,我不知道如何从产品的ID到产品本身,除了再次创建使用Product
方法在本地创建产品。
如果存在解决方案,我希望当服务器关闭并重新启动时,应该可以查询数据库并恢复用户的购物车。
修改
getShoppingCartFromDatabase
方法
addToCart
方法/**
* Adds multiple items of a new product in the cart
* @param product added in cart
* @param num number of items of that product
* @throws ClassNotFoundException if an error occurs with the connection to the database
* @see ShoppingCartDAO#addOneItem(String, ProductInCart)
*/
public void addToCart(Product product, int num) throws ClassNotFoundException{
ProductInCart added = new ProductInCart(product, num);
this.productInCart.add(added);
ShoppingCartDAO.addOneItem(this.userMail, added);
}
在数据库ShoppingCartDAO.addOneItem(String, Product)
的表格中添加一行,cart(IDProduct, IDUser, nPieces)
。
根据用户的建议,我添加了我到达的解决方案,即使我认为它不是那么优化。
前提:存储的产品有三种类型,PK(IDProduct, IDUser)
,Product
和ProfessionalProduct
,均延伸ScholasticProduct
。
我的解决方案是在方法Product
中执行查询,使用getShoppingCartFromDatabase(String userMail, User user)
(即用户的ID)查询数据库(表cart
)并放入userMail
所有产品(或更确切地说是他们的ID)和商品数量。
当我扫描ResultSet
时,我首先清理用户的购物车,删除数据库中该用户的购物车(我在ResultSet
中有一个临时副本),然后我添加了新购物车和数据库中的产品:ResultSet
该方法现在有效,因为updatedCart.addToCart(ProductDAO.getFromDatabase(productID), nPieces);
会返回ProductDAO.getFromDatabase(productID)
。
方法Product
在数据库上执行查询,查找具有指定ID的产品,然后返回类型为ProductDAO.getFromDatabase(productID)
(或Product
或ProfessionalProduct
的新对象,具体取决于一个ScholasticProduct
区分类型,允许我调用正确的构造函数。)
我的问题是,是否有更好的解决方案,因为我看起来有点复杂,容易出错。
答案 0 :(得分:0)
虽然目前尚不清楚您是否缺少有关数据库关系的知识,或者您是否遗漏了数据模型中的某些内容,但我尝试展示我理解您的问题的解决方案。
如果您提供的代码显示您尝试解决问题,那将会很有帮助。这通常是一种更好,更快的方法。
据我了解您的datamodel,您有一个使用productId作为主键的Product表。然后有一个ShoppingCart表,它使用客户的电子邮件地址作为主键。
您的问题是,您不明白,如何将产品与购物车链接。虽然您已经了解到购物车需要参考其中的产品,但您没有意识到购物车实际上不是单行,甚至可能不是单个表。
我会像这样建模:
ShoppingCart
- ID ====> ShoppingCartItem
- owneremail - shoppingCartID (FK relation to cart)
- productID (FK relation to products)
- amount (... add other item properties)
FK
表示外键。
当您在购物车中存储商品时,您在ShoppingCartItem表中插入商品,在shoppingCartID上引用购物车,这是ShoppingCart表中ID列的值,其中电子邮件地址与客户电子邮件匹配。
因此,当您从数据库中读取购物车时,您可以:
SELECT ID
FROM ShoppingCart
WHERE email = <customer's email>
在您的模型中,这应始终只返回一条记录。 要检索项目,请致电
SELECT productID,
amount
FROM ShoppingCartItem
WHERE shoppingCartID = <ID from previous select>
要获取其他产品详细信息,您需要通过productID
加入产品表SELECT i.productID,
i.amount,
p.name,
p.price,
p.description
FROM ShoppingCartItem i join product p on p.ID = i.productID
WHERE shoppingCartID = <ID from previous select>
要在购买时添加商品,您需要手头的productID和购物车ID才能将商品添加到购物车。这似乎已经反映在您的代码中,但是由于您没有提供addToCart方法,我无法确定。
INSERT INTO ShoppingCartItem (shoppingCartID, productID, amount)
VALUES (<cart ID>, <productID>, <amount>)
这对您的问题有帮助吗?
更新:
你要求一种更优雅的方式来处理这一切。您当前的代码库肯定会有一些改进点。
ConnectionPool
:始终从DriverManager获取连接非常昂贵。 ConnectionPools保持连接打开并准备好获取。 这就是我现在可以添加的所有内容。你似乎走得很好: - )