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);