前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【JDBC实战】水果库存系统 [功能实现](接口实现类FruitDAOImpl的功能实现)万字长文

【JDBC实战】水果库存系统 [功能实现](接口实现类FruitDAOImpl的功能实现)万字长文

作者头像
.29.
发布2022-11-15 14:12:52
3200
发布2022-11-15 14:12:52
举报
文章被收录于专栏:个人技术博客

前言

上一篇文章中,我们对水果库存系统的需求进行了介绍,同时对系统需要的结构进行了设计,接下来,就到了实际上手,实现功能的阶段了。

在这篇文章中,我们将对实现类FruitDAOImpl中的单精度方法进行代码实现。

回顾一下实现类FruitDAOImpl中设计的单精度方法吧:

👇查询库存列表:

  • List< Fruit > getFruitList();

👇 新增库存:

  • boolean addFruit(Fruit fruit);

👇 修改库存:

  • boolean UpdateFruit(Fruit fruit);

👇删除库存:

  • boolean DelFruit(String fname);

👇查询指定库存:

  • Fruit getFruitByFname(String fname);

接口实现类FruitDAOImpl的功能实现

一、更新操作相关

1. boolean addFruit(Fruit fruit);

这是新增库存的方法,根据字面意思来简单理解一下,就是使用JDBC连接数据库,对数据库数据进行增添操作,增添的数据来自传入的Fruit对象。

依旧是常规的步骤:

加载驱动

代码语言:javascript
复制
//加载驱动
Class.forName("com.mysql.cj.jdbc.Driver");

使用数据库管理器,连接数据库

需要准备:

连接数据库的地址URL;

数据库账户USER;

账户密码PSW(password);

代码语言:javascript
复制
String URL = "jdbc:mysql://localhost:3306/fruitdb?useSSL=false&useUnicode=true&CharacterEncoding=utf-8";
String USER = "root" ;
String PSW = "" ;
 //数据库管理器,连接数据库
Connection  connection = DriverManager.getConnection(URL, USER, PSW);

编写SQL语句

因为第一个属性fid(水果编号)是自增列,所以填入0即可。

剩下的四个属性,使用占位符 ?代替,以便后续的填充。

代码语言:javascript
复制
String sql = "insert into t_fruit values(0,?,?,?,?)";

创建预处理对象

将编写的SQL语句传入;

代码语言:javascript
复制
 PreparedStatement pstm = connection.prepareStatement(sql);

填充占位符 ?参数

这里面的参数需要从传入的Fruit对象中获取,也就是:

  • fruit.getFname()
  • fruit.getPrice()
  • fruit.getFcount()
  • fruit.getRemark()
代码语言:javascript
复制
pstm.setString(1, fruit.getFname());
pstm.setInt(2,fruit.getPrice());
pstm.setInt(3,fruit.getFcount());
pstm.setString(4,fruit.getRemark());

执行更新,返回影响行数

代码语言:javascript
复制
int count = pstm.executeUpdate()

因为boolean addFruit(Fruit fruit);方法的返回值是布尔类型(boolean),所以当返回的影响行数大于零时,我们就返回true,否则返回false

代码语言:javascript
复制
return count > 0;

关闭资源

很重要的一步:

代码语言:javascript
复制
psmt.close();
connection.close();

完成这一系列的操作,我们得到了:

满屏的报错,对了,我们还需要异常处理try-catch-finally

代码语言:javascript
复制
    @Override
    public boolean addFruit(Fruit fruit){
        try {
            Class.forName("com.mysql.jdbc.Driver");
            Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/fruitdb?useSSL=false&useUnicode=true&characterEncoding=gbk",
                    "root", "");

            String sql = "insert into t_fruit values(8,?,?,?,?)";
            PreparedStatement psmt = connection.prepareStatement(sql);

            pstm.setString(1, fruit.getFname());
            pstm.setInt(2,fruit.getPrice());
            pstm.setInt(3,fruit.getFcount());
            pstm.setString(4,fruit.getRemark());

            int count = psmt.executeUpdate();
            
            return count > 0;
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        } finally{
            
            try {
                if(psmt != null)
                psmt.close();
                if(connection != null)
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        return false;
    }

但是,依旧爆红

这是因为我们经过异常处理之后,创建的对象,都被try{}代码块给囊括起来了,而出了代码块之后也就失去了效用,所以在finally{}中的对象会出问题…

为了解决这个问题,我们就需要将对象都设置成全局变量,这样的话,无论在那个代码块中,都能被识别出来。

同时,还可以将一些比较冗长,常常用到的属性也设置成全局变量,方便使用。

代码语言:javascript
复制
    final String DRIVER = "com.mysql.cj.jdbc.Driver";
    final String URL = "jdbc:mysql://localhost:3306/fruitdb?useSSL=false&useUnicode=true&CharacterEncoding=utf-8";
    final String USER = "root" ;
    final String PSW = "" ;
    Connection connection;
    PreparedStatement pstm;
    ResultSet rs;
    List<Fruit> list;

这样子,问题基本就解决啦:

代码语言:javascript
复制
    @Override
    public boolean addFruit(Fruit fruit){

        try {

            Class.forName(DRIVER);
            connection = DriverManager.getConnection(URL, USER, PSW);

            String sql = "insert into t_fruit values(0,?,?,?,?)";

            pstm = connection.prepareStatement(sql);
            pstm.setString(1, fruit.getFname());
            pstm.setInt(2,fruit.getPrice());
            pstm.setInt(3,fruit.getFcount());
            pstm.setString(4,fruit.getRemark());

            return pstm.executeUpdate() > 0;
        } catch (ClassNotFoundException | SQLException e) {
            e.printStackTrace();
        }finally{
            try {
                if(pstm != null)
                    pstm.close();
                if(connection != null)
                    connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        return false;
    }


上文介绍的功能实现,步骤已经十分齐全,而且在接下来的更新操作相关方法中,除了SQL语句,基本上都大同小异了。

2.boolean UpdateFruit(Fruit fruit);

在更新水果库存方法中,我们只需要更新指定水果的库存数量即可,所以需要填充的参数有两个,都是从传入的Fruit对象(已修改库存)中获取:

  • fruit.getFname() — 获取水果名称
  • fruit.getFcount() — 获取水果库存

功能实现代码:

代码语言:javascript
复制
 @Override
    public boolean UpdateFruit(Fruit fruit) {
        try {
        //加载驱动
        Class.forName(DRIVER);
        //数据库管理器,连接数据库
        connection = DriverManager.getConnection(URL, USER, PSW);
        //sql语句
        String sql = "update t_fruit set fcount = ? where fname like ?";
        //预处理对象
        pstm = connection.prepareStatement(sql);
        pstm.setInt(1,fruit.getFcount());
        pstm.setString(2, fruit.getFname());

        return pstm.executeUpdate() > 0;

    } catch (ClassNotFoundException | SQLException e) {
        e.printStackTrace();
    }finally{
        try {
            if(pstm != null)
                pstm.close();
            if(connection != null)
                connection.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
        return false;
    }


3.boolean DelFruit(String fname)

删除库存的方法里,只需要根据传入的水果名称,删除数据库中相应的数据即可:

功能实现的代码

代码语言:javascript
复制
 @Override
    public boolean DelFruit(String fname) {
        try {
            //加载驱动
            Class.forName(DRIVER);
            //数据库管理器,连接数据库
            connection = DriverManager.getConnection(URL, USER, PSW);
            //sql语句
            String sql = "delete from t_fruit where fname like ?";
            //预处理对象
            pstm = connection.prepareStatement(sql);
            pstm.setString(1,fname);

            return pstm.executeUpdate() > 0;

        } catch (ClassNotFoundException | SQLException e) {
            e.printStackTrace();
        }finally{
            try {
                if(pstm != null)
                    pstm.close();
                if(connection != null)
                    connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        return false;

    }



二、查询操作相关

1.List getFruitList()

执行查询操作与执行更新操作之间有一定的差异

查询操作通常调用的是预处理对象的executeQuery()方法

更新操作通常调用的是预处理对象的executeUpdate()方法

executeUpdate()方法返回的是更新操作后的影响行数;

executeQuery()方法返回的是一个 ResultSet对象,里面存储的是记录了数据库每行信息的数据。

我们需要使用循环来将数据库每行信息记录下来,存储进数组中返回。

集合在上文已经设置成了全局变量:

代码语言:javascript
复制
    ResultSet rs;     //rs对象
    List<Fruit> list; //集合

查询水果信息的实现代码

代码语言:javascript
复制
@Override
    public List<Fruit> getFruitList() {
        try {
            //加载驱动
            Class.forName(DRIVER);
            //数据库管理器,连接数据库
            connection = DriverManager.getConnection(URL, USER, PSW);
            //sql语句
            String sql = "select * from t_fruit";
            //预处理对象
            pstm = connection.prepareStatement(sql);
            //执行查询,返回结果集
            rs = pstm.executeQuery();
            list = new ArrayList<Fruit>();
            while(rs.next()){
                int Fid = rs.getInt("fid");
                String Fname = rs.getString("fname");
                int Price = rs.getInt("price");
                int Fcount = rs.getInt("fcount");
                String Remark = rs.getString("remark");
                Fruit fruitTable = new Fruit(Fid,Fname,Price,Fcount,Remark);
                list.add(fruitTable);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }finally{
            try {
                if(rs != null)
                    rs.close();
                if(pstm != null)
                    pstm.close();
                if(connection != null)
                    connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        return list;
    }


2.Fruit getFruitByFname(String fname)

查询指定水果的信息,在这个方法中,我们依靠传入的水果姓名-fname来确定需要查询信息的水果。

返回的是Fruit对象,此对象的属性便是指定水果的信息。

代码语言:javascript
复制
@Override
    public Fruit getFruitByFname(String fname) {
        try {
            //加载驱动
            Class.forName(DRIVER);
            //数据库管理器,连接数据库
            connection = DriverManager.getConnection(URL, USER, PSW);
            //sql语句
            String sql = "select * from t_fruit where fname = ? ";
            //预处理对象
            pstm = connection.prepareStatement(sql);
            pstm.setString(1,fname);
            //执行查询,返回结果集
            rs = pstm.executeQuery();
            while(rs.next()){
                int fid = rs.getInt("fid");
                int price = rs.getInt("price");
                int fcount = rs.getInt("fcount");
                String remark = rs.getString("remark");
                Fruit fruit = new Fruit(fid,fname,price,fcount,remark);
                return fruit;
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }finally{
            try {
                if(rs != null)
                    rs.close();
                if(pstm != null)
                    pstm.close();
                if(connection != null)
                    connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        return null;
    }


三、代码汇总

接口实现类FruitDAOImpl中出现的方法,全都是单精度方法,代表方法的颗粒密度已经不能再划分了。

简单点来说,方法的功能还过于单一,操作过于简易,而不足以满足水果库存系统的功能需求。

也正因如此,我们还需要菜单类Menu中的方法,里面的方法调用了接口实现类FruitDAOImpl这里的单精度方法,同时将拥有更加丰富的功能。

接口实现类FruitDAOImpl的功能实现:

代码语言:javascript
复制
import com.haojin.fruit.dao.FruitDAO;
import com.haojin.fruit.pojo.Fruit;

import java.sql.*;
import java.util.ArrayList;
import java.util.List;

/**
 * @author .29.
 * @create 2022-09-23 17:56
 */
public class FruitDAOImpl implements FruitDAO {
    final String DRIVER = "com.mysql.cj.jdbc.Driver";
    final String URL = "jdbc:mysql://localhost:3306/fruitdb?useSSL=false&useUnicode=true&CharacterEncoding=utf-8";
    final String USER = "root" ;
    final String PSW = "" ;
    Connection connection;
    PreparedStatement pstm;
    ResultSet rs;
    List<Fruit> list;

    @Override
    public List<Fruit> getFruitList() {
        try {
            //加载驱动
            Class.forName(DRIVER);
            //数据库管理器,连接数据库
            connection = DriverManager.getConnection(URL, USER, PSW);
            //sql语句
            String sql = "select * from t_fruit";
            //预处理对象
            pstm = connection.prepareStatement(sql);
            //执行查询,返回结果集
            rs = pstm.executeQuery();
            list = new ArrayList<Fruit>();
            while(rs.next()){
                int Fid = rs.getInt("fid");
                String Fname = rs.getString("fname");
                int Price = rs.getInt("price");
                int Fcount = rs.getInt("fcount");
                String Remark = rs.getString("remark");
                Fruit fruitTable = new Fruit(Fid,Fname,Price,Fcount,Remark);
                list.add(fruitTable);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }finally{
            try {
                if(rs != null)
                    rs.close();
                if(pstm != null)
                    pstm.close();
                if(connection != null)
                    connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        return list;
    }

    @Override
    public boolean addFruit(Fruit fruit){
        try {
            Class.forName(DRIVER);
            connection = DriverManager.getConnection(URL, USER, PSW);

            String sql = "insert into t_fruit values(0,?,?,?,?)";

            pstm = connection.prepareStatement(sql);
            pstm.setString(1, fruit.getFname());
            pstm.setInt(2,fruit.getPrice());
            pstm.setInt(3,fruit.getFcount());
            pstm.setString(4,fruit.getRemark());

            return pstm.executeUpdate() > 0;
        } catch (ClassNotFoundException | SQLException e) {
            e.printStackTrace();
        }finally{
            try {
                if(pstm != null)
                    pstm.close();
                if(connection != null)
                    connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        return false;
    }

    @Override
    public boolean UpdateFruit(Fruit fruit) {
        try {
        //加载驱动
        Class.forName(DRIVER);
        //数据库管理器,连接数据库
        connection = DriverManager.getConnection(URL, USER, PSW);
        //sql语句
        String sql = "update t_fruit set fcount = ? where fname like ?";
        //预处理对象
        pstm = connection.prepareStatement(sql);
        pstm.setInt(1,fruit.getFcount());
        pstm.setString(2, fruit.getFname());

        return pstm.executeUpdate() > 0;

    } catch (ClassNotFoundException | SQLException e) {
        e.printStackTrace();
    }finally{
        try {
            if(pstm != null)
                pstm.close();
            if(connection != null)
                connection.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
        return false;
    }

    @Override
    public boolean DelFruit(String fname) {
        try {
            //加载驱动
            Class.forName(DRIVER);
            //数据库管理器,连接数据库
            connection = DriverManager.getConnection(URL, USER, PSW);
            //sql语句
            String sql = "delete from t_fruit where fname like ?";
            //预处理对象
            pstm = connection.prepareStatement(sql);
            pstm.setString(1,fname);

            return pstm.executeUpdate() > 0;

        } catch (ClassNotFoundException | SQLException e) {
            e.printStackTrace();
        }finally{
            try {
                if(pstm != null)
                    pstm.close();
                if(connection != null)
                    connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        return false;

    }

    @Override
    public Fruit getFruitByFname(String fname) {
        try {
            //加载驱动
            Class.forName(DRIVER);
            //数据库管理器,连接数据库
            connection = DriverManager.getConnection(URL, USER, PSW);
            //sql语句
            String sql = "select * from t_fruit where fname = ? ";
            //预处理对象
            pstm = connection.prepareStatement(sql);
            pstm.setString(1,fname);
            //执行查询,返回结果集
            rs = pstm.executeQuery();
            while(rs.next()){
                int fid = rs.getInt("fid");
                int price = rs.getInt("price");
                int fcount = rs.getInt("fcount");
                String remark = rs.getString("remark");
                Fruit fruit = new Fruit(fid,fname,price,fcount,remark);
                return fruit;
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }finally{
            try {
                if(rs != null)
                    rs.close();
                if(pstm != null)
                    pstm.close();
                if(connection != null)
                    connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        return null;
    }
}

到这里,接口实现类FruitDAOImpl的功能实现就完成啦…

接下来就是对菜单类Menu的功能实现,再完成菜单类的功能代码,我们的水果库存系统功能就可以说是完成了。之后就可以进入代码优化阶段…

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-10-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • JDBC专栏
    • JDBC实战,实现水果库存系统
    • 前言
    • 接口实现类FruitDAOImpl的功能实现
      • 一、更新操作相关
        • 1. boolean addFruit(Fruit fruit);
        • 2.boolean UpdateFruit(Fruit fruit);
        • 3.boolean DelFruit(String fname)
      • 二、查询操作相关
        • 1.List getFruitList()
        • 2.Fruit getFruitByFname(String fname)
      • 三、代码汇总
      相关产品与服务
      数据库
      云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档