• 顾客点餐系统-----操作菜品JDBC代码的编写(1)


     2)针对菜品表来说,我们主要实现下面功能:

    1. 1)新增菜品
    2. 2)删除菜品(根据DishID来进行删除)
    3. 3)查询菜品
    4. 3.1查找所有菜品
    5. 3.2查找根据ID指定特定菜品
    6. 4)修改菜品----改价格
    1. public void AddDish(Dish dish) throws SQLException {
    2. //1.与数据库建立连接
    3. Connection connection= ConnectionMYSQL.GetConnection();
    4. //2.拼装SQL语句
    5. String SQL="insert into Dish values(null,?,?)";
    6. PreparedStatement statement=connection.prepareStatement(SQL);
    7. statement.setString(1,dish.getDishName());
    8. statement.setInt(2,dish.getDishMoney());
    9. //3.执行SQL语句
    10. int len= statement.executeUpdate();
    11. if(len==1){
    12. System.out.println("新增菜品成功");
    13. }else{
    14. System.out.println("新增菜品失败");
    15. }
    16. }
    17. public void deleteDishById(int DishID) throws SQLException {
    18. //1.与数据库建立连接
    19. Connection connection=ConnectionMYSQL.GetConnection();
    20. //2.拼装SQL语句
    21. String SQL="delete from Dish where DishID=?";
    22. PreparedStatement statement= connection.prepareStatement(SQL);
    23. statement.setInt(1,DishID);
    24. //3.执行SQL语句
    25. int len=statement.executeUpdate();
    26. if(len==1){
    27. System.out.println("删除成功");
    28. }else{
    29. System.out.println("删除失败");
    30. }
    31. }
    32. public List GetAll() throws SQLException {
    33. //1.与数据库建立连接
    34. Connection connection=ConnectionMYSQL.GetConnection();
    35. //2.拼装SQL语句
    36. String SQL="select * from Dish";
    37. PreparedStatement statement= connection.prepareStatement(SQL);
    38. //3.执行SQL语句
    39. ResultSet resultSet=statement.executeQuery();
    40. //4.返回结果
    41. List list=new ArrayList<>();
    42. while(resultSet.next()){
    43. Dish dish=new Dish();
    44. dish.setDishID(resultSet.getInt("DishID"));
    45. dish.setDishName(resultSet.getString("DishName"));
    46. dish.setDishMoney(resultSet.getInt("DishMoney"));
    47. list.add(dish);
    48. }
    49. return list;
    50. }
    51. public Dish GetOneByID(int dishID) throws SQLException {
    52. //1.与数据库建立连接
    53. Connection connection=ConnectionMYSQL.GetConnection();
    54. //2.拼装SQL语句
    55. String SQL="select * from Dish where DishID=?";
    56. //3执行SQL语句
    57. PreparedStatement statement= connection.prepareStatement(SQL);
    58. statement.setInt(1,dishID);
    59. ResultSet resultSet= statement.executeQuery();
    60. //4.遍历循环结果
    61. while(resultSet.next()){
    62. Dish dish=new Dish();
    63. dish.setDishID(resultSet.getInt("DishID"));
    64. dish.setDishName(resultSet.getString("DishName"));
    65. dish.setDishMoney(resultSet.getInt("DishMoney"));
    66. return dish;
    67. }
    68. return null;
    69. }
    70. public void UpdateDishMoney(int DishID,int money) throws SQLException {
    71. //1.与数据库建立连接
    72. Connection connection=ConnectionMYSQL.GetConnection();
    73. //2.拼装SQL语句
    74. String Sql="update Dish set DishMoney =? where DishID=?";
    75. //3.执行SQL语句
    76. PreparedStatement statement=connection.prepareStatement(Sql);
    77. statement.setInt(1,money);
    78. statement.setInt(2,DishID);
    79. int len= statement.executeUpdate();
    80. if(len==1){
    81. System.out.println("更新钱的信息成功");
    82. }else{
    83. System.out.println("更新失败");
    84. }
    85. }

    3)针对订单来说,我们主要是进行下面的操作:

    1. 1)新增订单
    2. 2)查看所有订单(管理员,商家)
    3. 3)查看指定订单的详细信息(普通用户,顾客)
    4. 4)查看订单的状态
    5. 5)修改订单状态(订单是否已经完成)

    1)新增订单:

    1.1我们的订单是和两张表关联的,一张表是order_user,一张表是order_dish,这就意味着我们新增订单的时候要插入两张表,尤其还要注意,我们在插入第二张表的时候,一个订单中可能会涉及到多个菜品,我们就需要给这张表一次性插入多条记录(因为第二张表第一个属性是OrderID,第二个属性是一个OrderID对应的菜品(DishID)

    1.2我们进行插入第一张表

    1. package MYSQL;
    2. import java.sql.Connection;
    3. import java.sql.PreparedStatement;
    4. import java.sql.SQLException;
    5. public class OperateOrder {
    6. public void AddOrder(Order order) throws SQLException {
    7. //1先进行操作order_user表
    8. addOrderUser(order);
    9. addOrderDish(order);
    10. }
    11. private void addOrderUser(Order order) throws SQLException {
    12. //1与数据库建立连接
    13. Connection connection=ConnectionMYSQL.getConnection();
    14. //2拼装SQL语句
    15. String SQL="insert into order_user values(null,?,now(),0)";
    16. PreparedStatement statement= connection.prepareStatement(SQL);
    17. statement.setInt(1,order.getUserID());
    18. int len= statement.executeUpdate();
    19. if(len==1)
    20. {
    21. System.out.println("新增菜品成功");
    22. }else{
    23. System.out.println("新增菜品失败");
    24. }
    25. ConnectionMYSQL.close(statement,null,connection);
    26. }
    1. //新增订单
    2. public void addOrderUser(Order order) throws SQLException {
    3. //1.与数据库建立连接
    4. Connection connection= ConnectionMYSQL.GetConnection();
    5. //2.拼装SQL语句
    6. String SQL="insert into order_user values(bull,?,?,?)";
    7. //3.执行SQL语句
    8. PreparedStatement statement= connection.prepareStatement(SQL);
    9. statement.setInt(1,order.getUserID());
    10. statement.setInt(2,order.getIsDone());
    11. statement.setTimestamp(3,order.getOrderTime());
    12. //4.执行SQL语句
    13. int len= statement.executeUpdate();
    14. if(len==1){
    15. System.out.println("新增order_user表成功");
    16. }else{
    17. System.out.println("新增order_user表失败");
    18. }
    19. }

    我们在进行插入OrderUser表的时候,因为是刚刚插入的时候,你的订单还没有完成,所以IsDone自动设置成0,还有你插入时间的时候,直接进行调用Now()函数就可以了,时间插入就更准确

    1.2)我们进行插入第二张表:我们在进行插入的时候,必须同时知道OrderID和DishID

    1)我们的第二张表是order_dish表,里面有两个字段,一个是orderID,一个是DishID,DishID是很好进行插入的,因为在Order表中,有一个属性表示List属性,可以获取到所有的Dishs,进而获取到DishsID进行插入;

    2)当我们在执行addOrderUser的时候,我们在执行SQL语句的时候,我们看到SQL里面确实是没有进行指定OrderID的,是需要数据库进行生成的,数据库是知道了最终知道了OrderID的值

     String SQL="insert into order_user values(null,?,now(),0)";

    3)在AddOrderUser,虽然在这个SQL语句执行完成之后,在数据库里面已经把OrderID生成了,但是在我们的Java代码里面Order对象还是不知道这个OrderID是多少,此时order对象中的OrderID还是空的,后续再进行OrderDish(Order order)方法的时候,order中的OrderID是空

    4)我们要想解决这个问题,我们就需要再进行AddOrderUser插入操作的时候,进行获取到自增主键的值,再把它添加到Order对象里面,才可以进行后续的订单---菜品插入操作(AddOrderDish)

    1. 执行SQL语句,插入的同时数据库会自动把自增主键的值进行返回,表示能获取,我们就可以进行读取了
    2. PreparedStatement statement= connection.prepareStatement(SQL,PreparedStatement.RETURN_GENERATED_KEYS);
    3. statement.setInt(1,order.getUserID());
    4. //把自增主键的值获取到,这是获取的方法,获取之后设置到Order对象里面
    5. ResultSet resultSet=statement.getGeneratedKeys();
    6. if(resultSet.next()){
    7. order.setOrderID(resultSet.getInt(1));
    8. }

    6)我们这个代码一加,插入Order_User表的同时就会把数据库自动生成的自增主键的值获取到(表示现在有权力进行获取自增主键的值)(数据库会自动返回自增主键的值)

    1. private void addOrderUser(Order order) throws SQLException {
    2. //1与数据库建立连接
    3. Connection connection=ConnectionMYSQL.getConnection();
    4. //2拼装SQL语句
    5. String SQL="insert into order_user values(null,?,now(),0)";
    6. PreparedStatement statement= connection.prepareStatement
    7. (SQL,PreparedStatement.RETURN_GENERATED_KEYS);
    8. statement.setInt(1,order.getUserID());
    9. int len= statement.executeUpdate();
    10. if(len==1)
    11. {
    12. System.out.println("新增菜品1成功");
    13. }else{
    14. System.out.println("新增菜品1失败");
    15. }
    16. //把自增主键的值进行获取到
    17. ResultSet resultSet= statement.getGeneratedKeys();
    18. if(resultSet.next())
    19. {
    20. order.setOrderID(resultSet.getInt(1));
    21. }
    22. ConnectionMYSQL.close(statement,null,connection);
    23. }

    1)这里面的getInt(1)表示什么含义呢?

    2)理解参数:当我们进行读取ResultSet的结果的时候,我们可以使用列名,还可以使用下标,由于一张表中的自增列可以有多个,返回的时候都返回回来了,下标填成1,就表示想要获取到第一个自增列生成的值;

    1.3)当我们进行新增order_dishs表的数据的时候,由于一个订单中包含着多个菜品,我们就需要向表中插入多条记录;

    这里面想到了两种方法:

    1)循环式的构建N条SQL语句,我们依次执行每一条SQL语句

    1. insert into order_dish values(1,1);
    2. insert into order_dish values(1,2);

    2)构建1条SQL语句,把多条记录以values的形式构造进去

    insert into order_values(1,1),(1,2)......

    我们建议使用第二种,因为执行一个SQL的效率要比执行多个SQL的效率更高

    1. private void addOrderDish(Order order) throws SQLException {
    2. //把菜品信息插入到表中
    3. //1.与数据库建立连接
    4. Connection connection=ConnectionMYSQL.getConnection();
    5. //关闭自动提交
    6. connection.setAutoCommit(false);
    7. //2.拼装SQL语句
    8. String SQL="insert into order_dish values(?,?)";
    9. //3执行SQL语句
    10. PreparedStatement statement= connection.prepareStatement(SQL);
    11. //由于一个订单对应到多个菜品,所以我们需要遍历Order中所包含的菜品数组
    12. 把每一条记录都取出来
    13. List list= order.getList();
    14. for(Dishes dish:list)//遍历Dishes给每一个字段添加values的值
    15. {//这里面的OrderID是在进行刚刚的插入order_user表之后,获取到的自增主键
    16. statement.setInt(1,order.getOrderID());
    17. statement.setInt(2,dish.getDishID());
    18. //这句代码表示给我们的SQL增加一些片段,每循环一次就要多加一个片段
    19. statement.addBatch();
    20. }
    21. statement.executeBatch();//既不是executeUpdate也不是ExecuteQuery();
    22. //发送给服务器
    23. connection.commit();
    24. //关闭操作
    25. ConnectionMYSQL.close(statement,null,connection);
    26. }

    下面有几个注意事项:

    1)connection.setAutoCommit(false);这句代码表示关闭自动提交

    我们在正常情况下是自动提交的,我们再调用executeXXX就可以自动地把请求的SQL发送给服务器了;

    但是在这个场景下,需要先进行关闭,然后再手动提交;

    2)statement.addBatch()这个方法是为了给SQL新增一组values,加了这个代码之后,循环几次,就加上一组数据,我们就可以把多组数据合并成一个SQL语句了

    3)statement.executeBatch()(检查SQL基本的语法有没有问题,如果没有问题,才发送给服务器;

    4)connection.commit()方法是执行SQL并发送给服务器,commit可以一次执行多个SQL,依次调用commit可以全部发送给服务器

    1.4)虽然我们执行了上面的代码操作,但是这段代码还是有一个致命的问题,整个插入操作不是原子的,假设如果说出现了这种极端情况,第一个方法执行成功了,第二个方法执行失败了,那么这个时候数据库中的数据就出现问题了,因为我们这一次新增菜单是根据两张表来进行操作的,一个是order_user表执行成功了,另一个是order_dish表执行失败了,此时我们认为这里面的插入操作还是失败的,因为这里面就出现了一个中间状态,数据库中记录了订单是谁提交的,但是没有记录这个顾客再订单里面的菜都有啥

    我们在这里面的解决方案有两种:

    1)使用事务,但是在这里面写代码是很麻烦的

    2)在第二个方法失败的时候,我们直接进行回滚,把第一次插入的order_user表给进行删除了就可以了

    1. public void AddOrder(Order order) throws SQLException {
    2. //1先进行操作order_user表,在Order_User表中进行插入,并设置自增主键在order对象里面
    3. addOrderUser(order);
    4. //2.在Order_Dish表中进行操作,此时在order表中就有自增主键了
    5. addOrderDish(order);
    6. }
    7. private void addOrderUser(Order order) throws SQLException {
    8. //1与数据库建立连接
    9. Connection connection=ConnectionMYSQL.getConnection();
    10. //2拼装SQL语句
    11. String SQL="insert into order_user values(null,?,now(),0)";
    12. PreparedStatement statement= connection.prepareStatement(SQL,PreparedStatement.RETURN_GENERATED_KEYS);
    13. statement.setInt(1,order.getUserID());
    14. int len= statement.executeUpdate();
    15. if(len==1)
    16. {
    17. System.out.println("新增菜品1成功");
    18. }else{
    19. System.out.println("新增菜品1失败");
    20. }
    21. //把自增主键的值进行获取到
    22. ResultSet resultSet= statement.getGeneratedKeys();
    23. if(resultSet.next())
    24. {
    25. order.setOrderID(resultSet.getInt(1));
    26. }
    27. ConnectionMYSQL.close(statement,null,connection);
    28. }
    29. private void addOrderDish(Order order) throws SQLException {
    30. //把菜品信息插入到表中
    31. //1.与数据库建立连接
    32. Connection connection=ConnectionMYSQL.getConnection();
    33. connection.setAutoCommit(false);
    34. //2.拼装SQL语句
    35. String SQL="insert into order_dish values(null,null)";
    36. //3执行SQL语句
    37. PreparedStatement statement= null;
    38. try {
    39. statement = connection.prepareStatement(SQL);
    40. //由于一个订单对应到多个菜品,所以我们需要遍历Order中所包含的菜品数组,把每一条记录都取出来
    41. List list= order.getList();
    42. for(Dishes dish:list)
    43. {//这里面的OrderID是在进行刚刚的插入order_user表之后,获取到的自增主键
    44. statement.setInt(1,order.getOrderID());
    45. statement.setInt(2,dish.getDishID());
    46. //这句代码表示给我们的SQL增加一些片段
    47. statement.addBatch();
    48. }
    49. statement.executeBatch();
    50. connection.commit();
    51. } catch (SQLException throwables) {
    52. throwables.printStackTrace();
    53. //这个方法主要是为了说如果上面的操作失败了,那么我们就认为整体的新增订单失败,回滚之前的order_user表里面的内容
    54. deleteOrderUser(order.getOrderID());
    55. }finally{
    56. ConnectionMYSQL.close(statement,null,connection);
    57. }
    58. }
    59. //这个方法用于删除order_user表中的记录
    60. private void deleteOrderUser(int OrderID)
    61. { Connection connection=null;
    62. PreparedStatement statement=null;
    63. //1与数据库建立连接
    64. try {
    65. connection=ConnectionMYSQL.getConnection();
    66. //2拼装SQL语句
    67. String SQL="delete from order_user where OrderID=?";
    68. statement= connection.prepareStatement(SQL);
    69. statement.setInt(1,OrderID);
    70. int len= statement.executeUpdate();
    71. if(len==1)
    72. {
    73. System.out.println("回滚成功");
    74. }else{
    75. System.out.println("回滚失败");
    76. }
    77. } catch (SQLException throwables) {
    78. throwables.printStackTrace();
    79. }
    80. }

    测试代码如下:

    1. OrderDAO orderDAO=new OrderDAO();
    2. Order order=new Order();
    3. order.setUserID(1);
    4. List list=new ArrayList<>();
    5. Dish dish1=new Dish();
    6. dish1.setDishID(1);
    7. Dish dish2=new Dish();
    8. dish2.setDishID(2);
    9. list.add(dish1);
    10. list.add(dish2);
    11. order.setList(list);
    12. orderDAO.addOrder(order);

  • 相关阅读:
    office办公软件太贵了 Microsoft的Word为什么要买 Microsoft365家庭版多少钱 Microsoft365密钥
    ubuntu20.04开机运行java的sh脚本
    VS101型单通道振弦传感器采集仪工程安全监测应用及常见问题
    Vue3入门
    【14】c++设计模式——>工厂模式
    创建一个前后端分离项目:Vue+SpringBoot
    【信管2.2】项目管理知识体系与组织结构
    flutter出现entrypoint isn‘t within the current project
    如何通过ip查询用户的归属地
    电脑版微信图片保存在哪个文件夹,如何一次性全选保存
  • 原文地址:https://blog.csdn.net/weixin_61518137/article/details/127462572