水果库存系统(进阶版)

不为失败找理由,只为成功找方法。所有的不甘,因为还心存梦想,所以在你放弃之前,好好拼一把,只怕心老,不怕路长。


前言

    本系统是基于之前写的水果库存基础版的基础上进行技术迭代,如果想了解基础版小伙伴可点击此:水果库存系统(基础版)。本次为水果库存系统的进阶版,那么和基础版有何不同呢?接下来介绍一下:

1. 使用Spring中IOC思想,把创建对象交给Spring(框架)管理。
2. 使用Spring里的模板JdbcTemplate实现与持久化技术的交接。
3. 使用MySQL来存储数据,真正关闭系统数据依旧存在的持久化效果。

以上就是本次升级后的系统与基础版的最大区别,那么废话不多说,先演示,后分析。


一、项目演示

查询操作 》》》

在这里插入图片描述

修改操作 》》》

在这里插入图片描述

新增操作 》》》

在这里插入图片描述

删除与退出操作 》》》

在这里插入图片描述

以上就是本系统的全部功能,看效果的话和基础版的差别不是很大,如果真看表面效果的话,那么就是退出系统,再开启系统,里面保存的数据会一直存在,除非手动删除。那么接下来我们的来看看这个系统的内部结构。

二、项目分析

    首先先聊聊本次系统使用到了什么技术。先说说项目管理功能maven,因为要使用第三方的库,比如Spring、MySQL、JDBC驱动,为了版本一致性和管理的灵活性,本次使用maven管理第三方工具包;然后就是编译器使用eclipse(也可以切换为iade);然后技术就是Spring使用的版本是5.x,MySQL使用的是8.x的。最后就是项目结构如下:
在这里插入图片描述

这里按照三层架构的模式来编写该系统。三层架构即数据访问层(持久层)、业务逻辑层(业务层)、视图控制层(控制层)。然后其他的就是实体类,工具类(上图也有标注)。那么在上代码之前,我们先做一点准备工具,得把maven环境搭建好。

在这里插入图片描述

在这里插入图片描述

搜索找到maven 》》》

在这里插入图片描述

在这里插入图片描述
以上就是使用eclipse创建maven的全部过程,然后在生成的maven项目中找到pom.xml文件,把下面的代码复制上去就完成了:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.nan</groupId>
  <artifactId>fruitSys</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  
  <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.3.20</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>5.3.20</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>5.3.20</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.29</version>
        </dependency>
    </dependencies>
</project>

环境准备完毕,但是还有一个重要的点,就是数据库还没准备,接下来就是准备数据库了,数据库的设计如下所示:

在这里插入图片描述
准备工作到这里就基本完成了,接下来就是上代码。

三、上代码

    我们按照数据库到视图层的顺序一一填充代码。
我们先创建Java映射类,作用是对应数据库中的数据。

package com.pojo;

/**
 * @author Ban 水果实体类
 */
public class Fruit {
	private Integer id; // 水果编号
	private String name; // 水果名称
	private double price; // 水果价格
	private String described; // 描述

	/* 构造方法 */
	public Fruit(String name, double price, String described) {
		this.name = name;
		this.price = price;
		this.described = described;
	}

	public Fruit(Integer id, String name, double price, String described) {
		this.id = id;
		this.name = name;
		this.price = price;
		this.described = described;
	}

	public Fruit() {
	}

	/* get、set方法 */
	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public double getPrice() {
		return price;
	}

	public void setPrice(double price) {
		this.price = price;
	}

	public String getDescribed() {
		return described;
	}

	public void setDescribed(String described) {
		this.described = described;
	}

	/* toString方法 方便打印数据 */
	@Override
	public String toString() {
		return "编号=" + id + ", 名称=" + name + ", 价格=" + price + ", 描述=" + described;
	}

}

这里需要注意的是Java属性名要和数据库里的字段名保持一致,不然会导致找不到而程序执行失败。接下来就是Dao层,持久层的代码。

package com.dao;

import com.pojo.Fruit;

import java.util.List;

/**
 * 持久层接口
 */
public interface FruitDao {
    /*新增库存*/
    int addFruit(Fruit fruit);

    /*查询库存*/
    List<Fruit> selectFruit();

    /*根据水果编号查询库存*/
    Fruit fruitById(Integer id);

    /*修改库存*/
    int updateFruit(Fruit newFruit);

    /*删除库存*/
    int deleteFruit(Integer id);

}

dao实现类

package com.dao;

import com.pojo.Fruit;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;

import java.util.List;

public class FruitDaoImpl implements FruitDao {
    //定义jdbcTemplate模板
    private JdbcTemplate jdbcTemplate;

    //在spring容器里获取jdbcTemplate
    public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

    /*新增水果*/
    @Override
    public int addFruit(Fruit fruit) {
        //准备SQL
        String sql = "insert into fruit(name,price,described) values (?,?,?)";
        //获取sql参数
        Object[] params = new Object[]{fruit.getName(),fruit.getPrice(),fruit.getDescribed()};
        //执行jdbcTemplate 进行新增操作
        int num = jdbcTemplate.update(sql, params);
        return num;
    }

    /*查询水果*/
    @Override
    public List<Fruit> selectFruit() {
        //准备SQL
        String sql = "select * from fruit";
        //映射转换器
        RowMapper rowMapper = new BeanPropertyRowMapper<Fruit>(Fruit.class);
        //执行查询操作
        return jdbcTemplate.query(sql,rowMapper);
    }

    /*根据编号id查询水果*/
    @Override
    public Fruit fruitById(Integer id) {
        //默认没有查询到
        Fruit fruit = null;
        try {
            String sql = "select * from fruit where id =?";
            RowMapper<Fruit> rowMapper = new BeanPropertyRowMapper<Fruit>(Fruit.class);
            fruit = jdbcTemplate.queryForObject(sql, rowMapper, id);
        }catch (EmptyResultDataAccessException e){
            //没有查询到对应的水果
        }

        return fruit;
    }

    /*更新水果*/
    @Override
    public int updateFruit(Fruit newFruit) {
        String sql = "update fruit set name=?,price=?, described=? where id =?";
        //参数
        Object[] params = new Object[]{newFruit.getName(),newFruit.getPrice(),newFruit.getDescribed(),newFruit.getId()};
        int num = this.jdbcTemplate.update(sql,params);
        return num;
    }

    /*根据id删除水果*/
    @Override
    public int deleteFruit(Integer id) {
        String sql ="delete from fruit where id =?";
        int num = jdbcTemplate.update(sql,id);
        return num;
    }
}

这里使用了面向接口编程,这样写的好处是维护性得到了统一。而这一层就是操作数据库的,使用了Spring框架里面的JdbcTemplate模板,代码里都有注释,这里就不啰嗦了。那么接下来就是业务层了:

package com.service;

import com.pojo.Fruit;

/**
 *
 * @author Ban
 * 水果库存业务层接口
 *
 */
public interface FruitService {
	/*新增库存*/
	int addFruit(Fruit fruit);

	/*查询库存*/
	void selectFruit();

	/*根据水果编号查询库存*/
	String selectById(Integer id);

	/*修改库存*/
	void updateFruit(Fruit newFruit);

	/*删除库存*/
	void deleteFruit(Integer id);
}

业务层实现类

package com.service;

import com.dao.FruitDaoImpl;
import com.pojo.Fruit;
import com.util.SpringBean;

import java.util.List;

/**
 * @author Ban
 * 水果库存逻辑类
 */

public class FruitServiceImpl implements FruitService {
    //获取持久层
    private FruitDaoImpl fruitDao;
    //水果实体类
    private Fruit fruit;

	//使用setter方法注入
    public void setFruitDaoImpl(FruitDaoImpl fruitDaoImpl) {
        this.fruitDao = fruitDaoImpl;
    }

    /**
     * 新增库存
     */
    public int addFruit(Fruit fruit) {
    	//在spring容器中获取对象fruitDaoImpl
        fruitDao = (FruitDaoImpl)SpringBean.getSpringBean("fruitDaoImpl");
        //获取水果信息
        Integer id = fruit.getId();
        String name = fruit.getName();
        double price = fruit.getPrice();
        String described = fruit.getDescribed();
        //创建一个水果类并生产水果信息
        Fruit fruit1 = new Fruit(name, price, described);
        //把水果放入仓库 并返回受影响的行数
        return fruitDao.addFruit(fruit1);
    }

    /**
     * 查询库存
     */
    public void selectFruit() {
        FruitDaoImpl fruitDao = (FruitDaoImpl)SpringBean.getSpringBean("fruitDaoImpl");
        List<Fruit> fruits = fruitDao.selectFruit();
        if (fruits.size() == 0 || fruits == null) {
            System.out.println("库存空空如也~~~");
            return;
        }
        //遍历查询
        for (Fruit fruit : fruits) {
            //直接打印
            System.out.println(fruit.toString());
        }
    }

    /**
     * 根据水果编号查询对应的水果库存
     */
    public String selectById(Integer id) {
        Fruit fruit1 = fruitDao.fruitById(id);
        //判断
        if (null != fruit1) {
            return "200";
        }
        return "-1";
    }

    /**
     * 根据水果编号修改对应库存信息
     */
    public void updateFruit(Fruit newFruit) {
        int i = fruitDao.updateFruit(newFruit);
        if (i > 0) {
            System.out.println("修改成功");
        }
        return;
    }

    /**
     * 根据水果编号删除对应的库存
     */
    public void deleteFruit(Integer id) {
        //删除水果库存
        int i = fruitDao.deleteFruit(id);
        if (i > 0) {
            System.out.println("操作成功");
        }else {
            System.out.println("该编号对应的水果不存在!");
        }
        return;
    }
}

关于依赖注入的是需要一个配置文件的,咱们放到后面再说,我们先把整体业务流程捋下来。接下来就是视图层了,也就是controller:

package com.controller;

import com.pojo.Fruit;
import com.service.FruitServiceImpl;
import com.util.SpringBean;
import java.util.Scanner;

/**
 * 水果库存系统的视图层
 */
public class View {
    //创建水果库存逻辑类
    private FruitServiceImpl fruitService;

    public void setFruitService(FruitServiceImpl fruitService) {
        this.fruitService = fruitService;
    }

    //水果库存系统视图设置
    public void getView(Scanner sc, String inputUser) {
    	//从Spring容器中获取fruitServiceImpl对象
        fruitService = (FruitServiceImpl)SpringBean.getSpringBean("fruitServiceImpl");
        //判断用户输入的信息进行不同场景的设计
        switch (inputUser) {
            case "1": //新增库存
                System.out.println("请您根据下面的指示进行操作:");

                System.out.print("请输入水果名称:");
                String name = sc.next();

                System.out.print("请输入水果价格:");
                double price = sc.nextDouble();

                System.out.print("请输入水果描述:");
                String desbriced = sc.next();

                //存储水果的对象并把水果信息存入其中
                Fruit fruit = new Fruit(name, price, desbriced);
                //调用逻辑类添加库存
                int count = fruitService.addFruit(fruit);
                //判断是否新增成功
                if(count <1) {
                	System.out.println("新增失败!");
                }else {
                	System.out.println("新增成功!");
                }
                break;
            case "2": //查询库存
                System.out.println("正在查询...");
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("<===============水果库存列表===============>");
                fruitService.selectFruit();
                System.out.println("<================库存列表=================>");
                System.out.println(""); //换行
                break;
            case "3": //修改库存
                System.out.println("请输入您要修改的水果编号:");
                Integer uId = sc.nextInt();
                //在仓库里查询一边是否存在
                String msg = fruitService.selectById(uId);
                if ("200".equals(msg)) {
                    //存在,可以修改
                    System.out.println("请您根据下面的指示进行操作:");

                    System.out.print("请输入水果名称:");
                    String uname = sc.next();

                    System.out.print("请输入水果价格:");
                    double uprice = sc.nextDouble();

                    System.out.print("请输入水果描述:");
                    String udesbriced = sc.next();
                    //存储水果的对象并把水果信息存入其中
                    Fruit uFruit = new Fruit(uId,uname, uprice, udesbriced);
                    //调用逻辑类添加库存
                    fruitService.updateFruit(uFruit);
                } else {
                    System.out.println("您输入的水果编号不存在");
                }
                break;
            case "4": //删除库存
                System.out.println("请输入您要删除的水果编号:");
                Integer fid = sc.nextInt();
                //调用逻辑类
                fruitService.deleteFruit(fid);
                break;
            case "5": //退出系统
                System.out.println("系统已退出");
                System.exit(0);
            default: //其他不存在操作
                System.out.println("您输入的操作不存在!");
                break;
        }
    }
}

本类是编写视图控制的,是与用户操作交互的逻辑,接下来就是程序入口了:

package com.controller;

import java.util.Scanner;

/**
 * 水果库存的主菜单
 *
 * @author Ban
 */
public class Main {

    public static void main(String[] args) {
        while (true) {
            // 设置菜单项
            System.out.println("<=====欢迎使用水果库存系统======>");
            System.out.println("本系统菜单功能如下:");
            System.out.println("【1】新增库存");
            System.out.println("【2】查询库存");
            System.out.println("【3】修改库存");
            System.out.println("【4】删除库存");
            System.out.println("【5】退出系统");
            //使用扫描器 获取用户输入的信息
            Scanner sc = new Scanner(System.in);
            System.out.println("请输入您要选择的操作:");
            String inputUser = sc.next();

            //调用视图
            new View().getView(sc, inputUser);
        }
    }
}

    单独写一个程序入口,然后调用视图业务,这样实现了解耦,也使代码看起来更精简了。那么接下来就是重点了,在本系统中,我们可以看到,对象基本不是我们使用new关键字创建出来的,而是让框架Spring里获取的,那么Spring如何存储呢。在基础版的时候,我们需要自己创建对象,然后放进一个集合容器里面,而且现在我们来看看如何把对象交给Spring来管理。
    我们来观察maven项目的结构,我们要在src/main/resources中创建一个xml文件,文件名可以自定义,我这里的为:applicationContext,编写的内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 
       http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd 
       http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">

    <!--1.配置数据源-->
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <!--数据库驱动-->
        <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
        <!--连接的数据库url-->
        <property name="url" value="jdbc:mysql:///mydb?useUnicode=true&amp;useSSL=false&amp;serverTimezone=UTC&amp;characterEncoding=utf-8"/>
        <!--连接的数据库用户-->
        <property name="username" value="root"/>
        <!--连接的数据库密码-->
        <property name="password" value=""/>
    </bean>

    <!--2.配置JDBC模板-->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <!--默认必须使用数据源-->
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <!--3.配置注入类-->
    <bean id="fruitDaoImpl" class="com.dao.FruitDaoImpl">
        <property name="jdbcTemplate" ref="jdbcTemplate"/>
    </bean>

    <!-- 依赖注入bean -->
    <bean id="fruitServiceImpl" class="com.service.FruitServiceImpl">
        <property name="fruitDaoImpl" ref="fruitDaoImpl"/>
    </bean>

	<!-- 把View类交给spring管理,并注入fruitServiceImpl -->
    <bean id="view" class="com.controller.View">
        <property name="fruitService" ref="fruitServiceImpl"/>
    </bean>
</beans>

以上就是配置spring,这样就完成了?不,还有关键的一步,把对象交给spring管理,那么我们还得要获取才行,就好像我们买东西,给钱了,那么东西肯定要拿走的(可能这个比喻不是很恰当)。那么怎么获取容器中的对象呢,我这里封装了一个简单的工具类,放在util包下,代码如下:

package com.util;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * @ClassName SpringBean
 * @Description 获取spring中的Bean对象
 **/

public class SpringBean {

    //获取spring容器中的bean
    public static Object getSpringBean(String objName){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        return applicationContext.getBean(objName); //根据Baen名称获取Bean
    }
}

    到这里,水果库存系统的进阶版就完成了,如果有小伙伴已完成以上操作,那么就可以启动程序,展示番自己的成果吧~~


写在最后

以上就是本篇文章的所有内容,在之前的水果库存系统(基础版)的代码上进行升级,相当于技术迭代,使该系统做到数据持久化。如果有兴趣的小伙伴而且对前端有些许基础,可以把视图层改为前端技术。那么本次的内容就到此结束了,如果以上对您有所收获,可动动您的灵动的小手留下足迹。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值