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

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

1)新增菜品
2)删除菜品(根据DishID来进行删除)
3)查询菜品
3.1查找所有菜品
3.2查找根据ID指定特定菜品
4)修改菜品----改价格
   public void AddDish(Dish dish) throws SQLException {
        //1.与数据库建立连接
        Connection connection= ConnectionMYSQL.GetConnection();
        //2.拼装SQL语句
        String SQL="insert into Dish values(null,?,?)";
        PreparedStatement statement=connection.prepareStatement(SQL);
        statement.setString(1,dish.getDishName());
        statement.setInt(2,dish.getDishMoney());
        //3.执行SQL语句
        int len= statement.executeUpdate();
        if(len==1){
          System.out.println("新增菜品成功");
        }else{
            System.out.println("新增菜品失败");
        }
    }
   public void deleteDishById(int DishID) throws SQLException {
        //1.与数据库建立连接
       Connection connection=ConnectionMYSQL.GetConnection();
       //2.拼装SQL语句
       String SQL="delete from Dish where DishID=?";
       PreparedStatement statement= connection.prepareStatement(SQL);
       statement.setInt(1,DishID);
       //3.执行SQL语句
       int len=statement.executeUpdate();
       if(len==1){
           System.out.println("删除成功");
       }else{
           System.out.println("删除失败");
       }
   }
   public List<Dish> GetAll() throws SQLException {
        //1.与数据库建立连接
       Connection connection=ConnectionMYSQL.GetConnection();
       //2.拼装SQL语句
       String SQL="select * from Dish";
       PreparedStatement statement= connection.prepareStatement(SQL);
       //3.执行SQL语句
       ResultSet resultSet=statement.executeQuery();
       //4.返回结果
       List<Dish> list=new ArrayList<>();
       while(resultSet.next()){
           Dish dish=new Dish();
           dish.setDishID(resultSet.getInt("DishID"));
           dish.setDishName(resultSet.getString("DishName"));
           dish.setDishMoney(resultSet.getInt("DishMoney"));
           list.add(dish);
       }
       return list;
   }
   public Dish GetOneByID(int dishID) throws SQLException {
        //1.与数据库建立连接
       Connection connection=ConnectionMYSQL.GetConnection();
       //2.拼装SQL语句
       String SQL="select * from Dish where DishID=?";
       //3执行SQL语句
       PreparedStatement statement= connection.prepareStatement(SQL);
       statement.setInt(1,dishID);
       ResultSet resultSet= statement.executeQuery();
       //4.遍历循环结果
       while(resultSet.next()){
           Dish dish=new Dish();
           dish.setDishID(resultSet.getInt("DishID"));
           dish.setDishName(resultSet.getString("DishName"));
           dish.setDishMoney(resultSet.getInt("DishMoney"));
           return dish;
       }
     return null;
   }
   public void UpdateDishMoney(int DishID,int money) throws SQLException {
        //1.与数据库建立连接
       Connection connection=ConnectionMYSQL.GetConnection();
       //2.拼装SQL语句
       String Sql="update Dish set DishMoney =? where DishID=?";
       //3.执行SQL语句
       PreparedStatement statement=connection.prepareStatement(Sql);
       statement.setInt(1,money);
       statement.setInt(2,DishID);
       int len= statement.executeUpdate();
       if(len==1){
           System.out.println("更新钱的信息成功");
       }else{
           System.out.println("更新失败");
       }
   }

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

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

1)新增订单:

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

1.2我们进行插入第一张表

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

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

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

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

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

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

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

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

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

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

这里面想到了两种方法:

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

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

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

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

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

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

    }

下面有几个注意事项:

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表给进行删除了就可以了

 public void AddOrder(Order order) throws SQLException {
//1先进行操作order_user表,在Order_User表中进行插入,并设置自增主键在order对象里面
        addOrderUser(order);
//2.在Order_Dish表中进行操作,此时在order表中就有自增主键了
        addOrderDish(order);
    }

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

    private void addOrderDish(Order order) throws SQLException {
       //把菜品信息插入到表中
        //1.与数据库建立连接
        Connection connection=ConnectionMYSQL.getConnection();
        connection.setAutoCommit(false);
        //2.拼装SQL语句
        String SQL="insert into order_dish values(null,null)";
        //3执行SQL语句
        PreparedStatement statement= null;
        try {
            statement = connection.prepareStatement(SQL);
            //由于一个订单对应到多个菜品,所以我们需要遍历Order中所包含的菜品数组,把每一条记录都取出来
            List<Dishes> list= order.getList();
            for(Dishes dish:list)
            {//这里面的OrderID是在进行刚刚的插入order_user表之后,获取到的自增主键
                statement.setInt(1,order.getOrderID());
                statement.setInt(2,dish.getDishID());
                //这句代码表示给我们的SQL增加一些片段
                statement.addBatch();
            }
            statement.executeBatch();
            connection.commit();
        } catch (SQLException throwables) {
            throwables.printStackTrace();
//这个方法主要是为了说如果上面的操作失败了,那么我们就认为整体的新增订单失败,回滚之前的order_user表里面的内容
            deleteOrderUser(order.getOrderID());
        }finally{
            ConnectionMYSQL.close(statement,null,connection);
        }

    }
//这个方法用于删除order_user表中的记录
    private void deleteOrderUser(int OrderID)
    {  Connection connection=null;
        PreparedStatement statement=null;
        //1与数据库建立连接
        try {
             connection=ConnectionMYSQL.getConnection();
         //2拼装SQL语句
         String SQL="delete from order_user where OrderID=?";
         statement= connection.prepareStatement(SQL);
         statement.setInt(1,OrderID);
         int len= statement.executeUpdate();
         if(len==1)
         {
             System.out.println("回滚成功");
         }else{
             System.out.println("回滚失败");
         }
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
    }

测试代码如下:

  OrderDAO orderDAO=new OrderDAO();
        Order order=new Order();
        order.setUserID(1);
        List<Dish> list=new ArrayList<>();
        Dish dish1=new Dish();
        dish1.setDishID(1);
        Dish dish2=new Dish();
        dish2.setDishID(2);
        list.add(dish1);
        list.add(dish2);
        order.setList(list);
        orderDAO.addOrder(order);

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值