在线网上商店,实例化所有产品

时间:2017-08-05 18:17:18

标签: java jdbc

我是网站编程的新手(等等程序和数据库之间的关系),我遇到了一个问题。

我创建了一个在线网上商店,可以在数据库中交互并保存每个信息。

问题出现在购物车上:我希望当用户在购物车中添加产品时,他可以退出,当他再次登录时,他应该发现购物车不变,所以我有一个产品作为对象{ {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)ProductProfessionalProduct,均延伸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)(或ProductProfessionalProduct的新对象,具体取决于一个ScholasticProduct区分类型,允许我调用正确的构造函数。)

我的问题是,是否有更好的解决方案,因为我看起来有点复杂,容易出错。

1 个答案:

答案 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保持连接打开并准备好获取。
  • 具体说明您的语句:在代码中对SQL查询执行“select *”被认为是不好的做法。始终是特定的,甚至更好地在列上放置别名,并在resultset.getXXX()方法中使用它们。
  • 不要修改数据库并期望结果集成为您的缓冲区。从数据库创建购物车对象,然后将其作为一个整体保留。持久性可以是事务性的,因此您可以在创建的同一事务中删除。这将使操作免受中断。如果不这样做,则在删除购物车时,代码中会有间隙,但新购物车尚未保存。如果你在NPE或OOM或其他什么时候堵嘴,你的购物车就不见了。
  • 尝试在DAO层中处理您的对象,不要将数据库结构过多地移动到您的代码中。最好有一个ShoppingCartDAO.saveCart(ShoppingCart),然后将items.add()与ShoppingCartDAO.addItemToCart()方法配对。
  • 一般情况下:对对象执行数据库操作,并且批量执行这些操作。这会降低数据库端的性能,并阻碍您在不更改数据库的情况下重构对象模型。对象模型只是数据库模型的一种可能投影。

这就是我现在可以添加的所有内容。你似乎走得很好: - )