图书进销存系统(CS) 联系客服

发布时间 : 星期三 文章图书进销存系统(CS)更新完毕开始阅读4758ae4f2e3f5727a5e96277

第9章 图书进存销系统 ·13·

代码清单:code\\book\\src\\org\\crazyit\\book\\vo\\Concern.java

public class Concern extends ValueObject { //出版社名称 }

private String PUB_NAME; //出版社电话

private String PUB_TEL; //联系人

private String PUB_LINK_MAN; //简介

private String PUB_INTRO;

//省略各个属性的getter和setter方法

注意各个属性的命名,必须要与数据库中表的字段一致,由于继承了ValueObject类,因此不需要提供ID字段。按照建立Concern对象的方法,再去建立Type对象、Book对象,Type代表书本类,Book代表书类型。在Book类中需要注意的是,由于书表中有两个键,分别是种类的外键TYPE_ID_FK和出版社的外键PUB_ID_FK,同样地也提供这两个类属性,并不是提供种类的对象(Type)和出版社的对象(Concern),另外所有属性类型都需要为String。

Type的代码如下,代码清单:code\\book\\src\\org\\crazyit\\book\\vo\\Type.java

public class Type extends ValueObject { //名称 }

private String TYPE_NAME; //简介

private String TYPE_INTRO; //省略setter和getter方法

Book的代码如下,代码清单:code\\book\\src\\org\\crazyit\\book\\vo\\Book.java

public class Book extends ValueObject { private String BOOK_NAME; //书本名称 private String BOOK_INTRO; //简介 private String BOOK_PRICE; //书的单价 private String TYPE_ID_FK; //种类外键 private String PUB_ID_FK; //出版社外键 private String REPERTORY_SIZE; //存储量 private String IMAGE_URL; //图片url }

创建完三个基础数据表所对应的类后,接下来再去创建入库记录表对应的类、书的入库记录表对应的类、销售记录表对应的类和书的销售记录表对应的类。

入库记录类InRecord,代码清单:code\\book\\src\\org\\crazyit\\book\\vo\\InRecord.java

public class InRecord extends ValueObject { private String RECORD_DATE; //入库日期 //省略getter和setter方法 }

书的入库记录类BookInRecord,代码清单:code\\book\\src\\org\\crazyit\\book\\vo\\BookInRecord.java

public class BookInRecord extends ValueObject { private String BOOK_ID_FK; //对应书的外键, 从数据库查出来时有值 private String T_IN_RECORD_ID_FK; //对应销售记录外键 private String IN_SUM; //入库数量 //省略setter和getter方法 }

·14· 第9章 图书进存销系统

销售记录类SaleRecord,代码清单:code\\book\\src\\org\\crazyit\\book\\vo\\SaleRecord.java

public class SaleRecord extends ValueObject { private String RECORD_DATE; //交易日期 //省略setter和getter方法 }

书的销售记录类BookSaleRecord。

代码清单:code\\book\\src\\org\\crazyit\\book\\vo\\BookSaleRecord.java

public class BookSaleRecord extends ValueObject { private String BOOK_ID_FK; //该记录对应的书的外键 private String T_SALE_RECORD_ID_FK; //该记录对应的销售记录的外键 private String TRADE_SUM; //该记录所对应的书的销售数量 //省略setter和getter方法 }

到现在,与系统相关的各个表所对应的类都已经编写好了,下面小节,我们将讲解这些建立好的类在开发过程中所体现的作用。

9.4.2 编写配置读取类

由于本章涉及到数据库操作,因此与数据库相关的一些配置,例如对应数据库的相关驱动、数据库地址、用户名和密码,我们可以放到配置文件中,如果需要更换数据库或者地址,只需要修改这份配置文件即可。

建立配置文件jdbc.properties,内容如下:

//JDBC驱动

jdbc.driver=com.mysql.jdbc.Driver //连接地址

jdbc.url=jdbc:mysql://localhost:3306/book_system //数据库用户名 jdbc.user=book //密码

jdbc.pass=book

建立好该文件后,再编写类去读取该文件,获得所需要的值即可。用于读取配置的PropertiesUtil类,代码如下。

代码清单:code\\book\\src\\org\\crazyit\\book\\jdbc\\PropertiesUtil.java

public class PropertiesUtil { private static Properties properties = new Properties();//该记录所对应的书的销售数量 private static String CONFIG = \配置文件的路径 //读取资源文件, 设置输入流

private static InputStream is = PropertiesUtil.class.getResourceAsStream(CONFIG); public static String JDBC_DRIVER; //数据库驱动 public static String JDBC_URL; //jdbc连接url public static String JDBC_USER; //数据库用户名 public static String JDBC_PASS; //数据库密码 static { properties.load(is); //加载输入流 //获得配置的各个属性

JDBC_DRIVER = properties.getProperty(\JDBC_URL = properties.getProperty(\JDBC_USER = properties.getProperty(\JDBC_PASS = properties.getProperty(\

第9章 图书进存销系统

}

}

·15·

读取的各个配置的作用,将在9.4.3中作详细讲解。

9.4.3 编写JDBC操作类

JDBC是Java Data Base Connectivity的简称,是Java中进行数据库连接的技术。JDBC的API提供了标准统一的SQL数据存取接口,可以让程序员不需要关心如何去连接不同的数据库,只需为不同的数据库提供不同的驱动,就可以达到连接不同数据库的要求。

在9.4.2中,我们已经提供了配置,可以修改对应的配置文件来连接数据库,jdbc.properties文件中的jdbc.driver属性,就是数据库的连接驱动,在本例中我们使用了MySQL数据库,因此需要提供MySQL的数据库驱动包。本例中使用的驱动包版本为5.1.6,如果需要最新的驱动程序,请到http://dev.mysql.com/downloads/connector/j/5.1.html下载,下载后将驱动包加到环境变量中。除了配置驱动外,还需要配置数据库的连接地址、用户名和密码,jdbc.url=jdbc:mysql://服务器ip:3306/book_system,用户名密码为你的MySQL用户密码。

配置好了之后,我们可以开始着手编写数据库的操作类,但在那之前,我们需要明确这个类帮我做些什么。首先肯定是帮我们进行数据库连接,我们之前配置了连接的相关属性,但是程序并不知道我们需要怎样去连接,接着我们需要这个类帮我们提供查询、执行SQL等功能。确定好目标后,开始编写。

新建JDBCExecutor类,该类具有属性如下:

private static String DRIVER = PropertiesUtil.JDBC_DRIVER; //获得驱动 private static String URL = PropertiesUtil.JDBC_URL; //获得url

private static String USER = PropertiesUtil.JDBC_USER; //获得连接数据库的用户名 private static String PASS = PropertiesUtil.JDBC_PASS; //获得连接数据库的密码 private Connection connection; //连接对象

private static JDBCExecutor jdbcExecutor; //维护一个本类型的对象 private Statement stmt; //维护一个本类型的对象

注:以上代码的黑体部分,由于创建一个Connection对象需要耗费很大的资源,因此我们使用单态模式,让JDBCExecutor类维护一个JDBCExecutor对象,可以在构造器中创建Connection,由于JDBCExecutor是单态的,因此可以保证在应用中只创建一个Connection,单态模式将在下一小节中详细讲述。

下面在JDBCExecutor的构造器中创建各个对象,再提供一个方法返回JDBCExecutor的实例。 代码清单:code\\book\\src\\org\\crazyit\\book\\jdbc\\JDBCExecutor.java

//私有构造器

private JDBCExecutor() { //初始化JDBC驱动并让驱动加载到jvm中

Class.forName(DRIVER); //创建数据库连接

connection = DriverManager.getConnection(URL, USER, PASS); //创建Statement对象

stmt = connection.createStatement(); }

//提供一个静态方法返回本类的实例

public static JDBCExecutor getJDBCExecutor() { //如果本类所维护jdbcExecutor属性为空,则调用私有的构造器获得实例 }

if (jdbcExecutor == null) jdbcExecutor = new JDBCExecutor(); return jdbcExecutor;

·16· 第9章 图书进存销系统

注:在以上代码中,提供了一个JDBCExecutor的私有构造器,因为需要保持这个类只创建一次,因此不可提供public的构造器让其他类去创建JDBCExecutor的实例,外界只能通过它自己内部的一个静态方法创建JDBCExecutor实例。

编写执行查询的方法,代码清单:code\\book\\src\\org\\crazyit\\book\\jdbc\\JDBCExecutor.java

//执行一句查询的sql, 并返回ResultSet对象 public ResultSet executeQuery(String sql) { //利用Statement对象执行参数的sql }

ResultSet result = stmt.executeQuery(sql); return result;

在上面的代码中,并没有关闭ResultSet的代码,直接返回ResultSet对象,我们还需要对ResultSet对象进行一些处理,因此在这里不进行关闭操作,该方法只是简单的进行查询。

编写执行SQL的方法,代码清单:code\\book\\src\\org\\crazyit\\book\\jdbc\\JDBCExecutor.java

//执行单句INSERT、UPDATE 或 DELETE 语句, 如果执行INSERT时, 返回主键 public int executeUpdate(String sql) { int result = -1; //执行SQL语句 }

stmt.executeUpdate(sql); //获得主键

ResultSet rs = stmt.getGeneratedKeys();

while(rs.next()) result = rs.getInt(1); //返回最后一个主键 rs.close(); return result;

在以上代码中,将会返回执行该句SQL所产生的主键。到这里,我们的JDBCExecutor类已经编写完了。

9.4.4 创建数据转换工具类

在9.4.3中,JDBCExecutor中提供了一个executeQuery方法,该方法返回ResultSet对象,当时我们并没有关闭ResultSet,这是由于我们需要对该结果集进行一些封装。在本小节中将建立一个工具类,进该结果集进行封装,并返回对应的集合。

在9.4.1中,我们设计了各个表所对应的类,那么在封装的过程中,将结果集(ResultSet)中的某个值作为这些类(表对象)的属性,并负责创建这些对象,放到集合中去。新建DataUtil类,具体的代码如下。

代码清单:code\\book\\src\\org\\crazyit\\book\\commons\\DataUtil.java

//将rs中的值封装成一个集合

public static Collection getDatas(Collection result, ResultSet rs, Class clazz) { while (rs.next()) { //创建类的实例

Object vo = clazz.newInstance(); //获取本对象的属性

Field[] fields = clazz.getDeclaredFields(); //获取父类的属性

Field[] superFields = clazz.getSuperclass().getDeclaredFields(); //父类的属性和自己的属性相加

Field[] allFields = addFields(superFields, fields); //遍历所有的属性