资源描述
第9章 图书进存销系统
9.1 项目简介
本章介绍如何开发一个CS结构的图书进存销系统,该系统的主要有出版社管理、书本管理、书的入库管理、销售管理等功能,通过这些简单的功能,可以让我们了解如何利用JDBC进行数据库操作、如何使用Java的反射机制以及如何对系统进行分层等知识点。
9.2 建立界面
在实现功能前,我们需要为这个系统建立界面和设计数据库,本小节将建立在这个小系统中所需要的各个界面。
9.2.1 登录界面
在进入系统前,我们需要经过简单的认证才能进入,因此需要提供一个简单的登录界面,当输入用户名和密码都正确时,就可以进入系统。需要建立的登录界面如图9.1所示。
图9.1 登录界面
界面非常的简单,只是两个输入框,一个按钮即可实现。帐号输入框使用的是JTextField类,而密码输入框使用的是JPasswordField类,使用JPasswordField对象并不会显示原始输入的字符。在本章中,我们将在最后再去实现用户的登录,先去实现系统的销售和入库功能。
9.2.2 销售管理界面
销售管理界面主要用于进行书的销售操作,添加一本需要交易的书、从交易列表中移除该书、进行交易等操作,在本界面的上半部分为交易记录列表,我们约定交易记录列表所显示的为今天进行的交易,并提供一个输入日期的输入框,可以根据日期进行查询该天的交易记录。本界面的下半部分为显示某笔交易的具体信息,包括该笔交易所涉及的金额、销售量、交易日期、交易所涉及的书等信息。初步的界面如图9.2所示。
图9.2 销售界面
如图9.2,销售管理界面的交易记录列表中,每列的字段分别为该交易所涉及的书本名、总价、交易日期、总数量。销售管理界面的下面部分,是显示具体某笔交易的界面,显示对应某笔交易的总价、交易日期、总数量、交易涉及书的列表,其中交易中涉及书的列表中,包括书的书名、单价、和本次交易中该本书出售的数量。交易中涉及的书列表下,可以选择书和输入书的数量,并提供添加和删除按钮,当选择了一本书并输入相应的交易数量,再点击添加时,即可向交易涉及的书列表中添加书的记录,当然也可以进行删除操作。在界面的最上面,有一个查询按键,可以输入日期进行交易记录查询。
注:具体某笔交易的界面(界面的下面部分),总价、交易日期和总数量是不可输入的,这是由于总价是由各本书的单价乘以交易数量得出来的,交易日期是当前交易时系统的时间为准的,总数量是各本书的交易数量总和,因此并不需要人手进行输入。
另外,如果在书本的下拉框中选择了某本书时,将会带出该本书的单介和库存,好让使用者在操作时对该本书的状况有所了解。
在本例中,每一个界面对应一个JPanel,每个界面都是一个JPanel类的子类,销售管理界面里面是一个JSplitPane对象,上面放一个个JScrollPane对象,下面部分也是一个JScrollPane对象。上面的JScrollPane对象主要存放一个JTable,下面的JScrollPane主要放一些Box对象进行布局,详细请看图书进存销系统代码清单中的SalePanel类。
9.2.3 入库管理界面
入库管理界面和销售管理界面的布局大致相同,只是其中的数据列和文字有所差距。入加管理界面如图9.3所示。
图9.3 库存管理界面
与销售管理界面类似,上面的列表是入库记录,一条入库记录包括入库时所涉及的书本、入库日期和入库书本的总数量。界面下面部分是具体某条入库记录的具体信息,包括入库日期、总数量和入库书本的列表,同样地,入库日期与总数量都不可以手动输入。在新增一条入库记录时,可以向书本列表添加和删除书本,表示该入库记录中所涉及的书本及对应的数量。
注:在选择某本书时,需要自动带出该书的库存。
在本例中,入库管理界面对应的类为RepertoryPanel类,是JPanel的子类。
9.2.4 书本管理界面
书本管理界面主要包括书本的查询、列表、查看等功能,书本在本例中作为基础数据的角色,主要用于销售和入库。这里需要注意的是,在新增一本书的时候,该书的库存为0,只有经过销售和入库才会对书的库存量产生影响。书的基本信息除了书名、价格介绍、所属出版社和书的种类外,还需要有书的图片,为简单起见,本例中的每本书只有一张图片,因此不需要另外建立表来存放书的图片。书本管理界面如图9.4所示。
图9.4 书本管理界面
书本管理界面上面的列表主要显示书本名称、简介、所属种类、出版社、库存数量和价格这些信息,此处的书本名称与销售管理(入库管理)界面中的书本名称有所区别,这里的书本名称的列宽较窄,这是由于销售(入库)中所涉及的是多本书,而书本管理界面中每一条书的记录只是代表一本书。
在界面的下方有一个表单,用于查看、修改和添加书本操作,表单的右边是书的图片显示区,用于显示书本所对应的缩略图,当用户点击缩略图的时候,可以弹出新的窗口用于展示大图。
与前面的界面一样,在程序中,我们新增一个BookPanel作为该界面。
9.2.5 种类管理界面
书的种类,表示一本书是属于哪个种类的,例如计算机、文学、法律等等,这些都是书的种类,我们提供一个种类管理界面,可以用于管理各个种类。种类在本例中与书本一样,属于基础数据。新增种类并不需要任何约束,只需要输入种类的名称即可。在书的管理界面中,如果需要添加一本书,必须选择该书所对应的种类。种类管理界面如图9.5所示。
图9.5 种类管理界面
如图9.5所示,种类管理界面并不复杂,上面是一个简单的列表,下面是普通的查看、新增与修改的表单。在程序中,我们新增一个TypePanel作为该界面。
9.2.6 出版社管理界面
添加一本书,除了需要有种类之外,还需要选择该书的出版社,我们提供一个出版社管理界面。如图9.6所示。
图9.6 出版社管理界面
出版社列表中,主要显示出版社名称、联系人、x和简介这些信息,下面的表单与前面几个界面的表单类似,都是用于查看、修改和新增。在程序中,我们新增一个ConcernPanel来表示这个界面。
从9.2.2到9.2.6的各个系统界面,都是存在于一个JFrame中,我们可以提供菜单,当点击了某个菜单的时候,JFrame中的各个JPanel对象隐藏,只显示对应的那个JPanel。
到此,我们所需要的界面已经全部完成了,在9.2.7中我们将对各个界面的代码进行优化,再去为主界面加上相应的菜单,我们的界面就全部完成。
9.2.7 修改界面代码
本例中涉及的各个界面,我们可以发现界面几乎都大同小异,界面上面部分是一个列表,下面是一个表单,因此,我们可以将这几个界面的共同部分提取出来,作为每个界面对象(JPanel)的父类,将一些可以重用的代码提升至父类,并可以使用“模板方法”,提供一些抽象的方法让各个子类去实现。
以下代码为各个界面对象的父类(CommonPanel)的代码。
代码清单:code\book\src\org\crazyit\book\ui\CommonPanel.java
private JTable table; //存放数据的table
protected Vector<Vector> datas; //列表数据
public void setJTable(JTable table) {
this.table = table;
}
public JTable getJTable() {
return this.table;
}
public Vector<Vector> getDatas() {
return datas;
}
public void setDatas(Vector<Vector> datas) {
this.datas = datas;
}
//将数据设置进JTable中
public void initData() {
if (this.table == null) return;
DefaultTableModel tableModel = (DefaultTableModel)this.table.getModel();
//将数据设入表格Model中
tableModel.setDataVector(getDatas(), getColumns());
//设置表格样式
setTableFace();
}
//刷新列表的方法
public void refreshTable() {
initData();
getJTable().repaint();
}
//获取表列集合, 由子类去实现
public abstract Vector<String> getColumns();
//设置列表的样式, 由子类去实现
public abstract void setTableFace();
//设置数据列表的方法,由子类去实现
public abstract void setViewDatas();
//清空界面下边的列表
public abstract void clear();
//给子类使用的方法, 用于获取一个列表的id列值
public String getSelectId(JTable table) {
int row = table.getSelectedRow();
int column = table.getColumn("id").getModelIndex();
String id = (String)table.getValueAt(row, column);
return id;
}
以上的代码,提供一个JTable的属性,这是因为每个界面中都有一个主要的列表对象,例如销售管理界面中的销售记录列表、书本管理界面中的书本列表等。注意代码中的黑体部分,都是由子类去实现的方法,getColumns()由子类去提供列表的列集合;setTableFace()是由子类去设置JTable的显示,例如需要设置某一列的宽度或者设置列表的行高等等;而setViewDatas()方法是重新去数据库读取数据,由子类去实现;clear()方法是刷新每个界面下边的表单,同样由子类去实现。在CommonPanel中提供了一个getSelectId方法,用来获得JTable属性中所选中的某一行中id列的值,也就是意味着在列表中,必须要有一个列名叫做id的列。
父类定义好规范之后,子类就可以根据不同的情况,给父类不同的列,让父类进行显示,除了需要提供列的集合外,还需要提供数据,也就是CommonPanel中的datas属性。我们这里提供了一个setViewDatas的方法,主要从数据库中读取相关的数据,再调用父类的initDatas方法构建列表。那么存放各个界面对象的JFrame类中,可以提供一个方法,当界面发生转换时,就调用setViewDatas方法,具体代码如下。
代码清单:code\book\src\org\crazyit\book\ui\MainFrame.java
//切换各个界面
private void changePanel(CommonPanel commonPanel) {
//移除当前显示的JPanel
this.remove(currentPanel);
//添加需要显示的JPanel
this.add(commonPanel);
//设置当前的JPanel
this.currentPanel = commonPanel;
this.repaint();
this.setVisible(true);
//调用CommonPanel的方法重新读取数据并刷新列表
commonPanel.setViewDatas ();
//清空界面下边的表单
commonPanel.clear();
}
以上代码的黑体部分,调各个界面对象父类的setVieweDatas方法重新读取数据并刷新列表,各个界面中转换时,当点击了对应的菜单后,再进行转换(调用changePanel方法)。
代码清单:code\book\src\org\crazyit\book\ui\MainFrame.java
private Action sale = new AbstractAction("销售管理", new ImageIcon("images/sale.gif")) {
public void actionPerformed(ActionEvent e) {
//调用转换的方法
changePanel(salePanel);
}
};
以上代码表示点击了销售管理的菜单后,就调用changePanel方法,转换界面并初始化数据。
另外,每个界面的主列表我们使用一个CommonJTable对象,该对象继承于JTable,我们并不需要让列表的每个单元格可以编辑,因此重写JTable的isCellEditable方法即可,代码如下。
代码清单:code\book\src\org\crazyit\book\ui\CommonJTable.java
public class CommonJTable extends JTable {
public CommonJTable(TableModel dm) {
super(dm);
//设置表格只能选择一行
getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
}
//重写父类的方法, 使所有的单元格不可编辑
public boolean isCellEditable(int row, int column) {
return false;
}
}
做了以上的准备工作后,就可以修改各个界面对应的类,去继承CommonPanel即可,实现getColumns()、setTableFace()、setViewDatas()和clear()方法,而数据暂时不必提供,下一节我们将开始设计数据库。
9.3 设计系统数据库
在9.2中我们已经建立了系统的相关界面,接下来,这一小节将设计这个系统的数据库。本例使用的是MySQL5.0作为数据库。在设计数据库前,我们可以确定,系统相关的表,从最基础开始,有出版社表、书的类型表、书表、入库记录表和销售记录表,其中,一条入库记录中涉及多本书,一条销售记录也涉及多本书,因此还需要书的入库记录表和书的销售记录表,一条书的入库记录对应一本书,该条书的入库记录属于某一条入库记录,可以理解成这是书与入库记录的关系表,同样地,书的销售记录与书的入库记录一样。
如果上面的文字难以理解,可以看下面的数据库结构,更有助于理解。在设计各个表前,我们需要创建数据库,在MySQL中,创建BOOK_SYSTEM数据库,具体的SQL语句如下:
-- 创建DATABASE
CREATE DATABASE IF NOT EXISTS BOOK_SYSTEM;
-- 使用BOOK_SYSTEM
USE BOOK_SYSTEM;
MySQL中的CREATE和USE语法可查看MySQL的帮助文档。
9.3.1 设计出版社表
在9.2.6中,我们已经建立了出版社的管理界面,现在只需要根据界面来设计数据库即可。我们在MySQL中建立表T_PUBLISHER,出版社表包括的字段有:
q ID:主键ID。
q PUB_NAME:出版社名称。
q PUB_TEL:x。
q PUB_LINK_MAN:联系人。
q PUB_INTRO:出版社简介。
由于出版社是最基础的数据,因此不需要其他的外键关系。以下为创建T_PUBLISHER这个表的SQL。
-- 出版社
CREATE TABLE IF NOT EXISTS `T_PUBLISHER` (
`ID` int AUTO_INCREMENT NOT NULL, -- 主键生成策略为自动增长
`PUB_NAME` varchar(50), -- 出版社名称
`PUB_TEL` varchar(50), -- x
`PUB_LINK_MAN` varchar(50), -- 联系人
`PUB_INTRO` varchar(200), -- 简介
PRIMARY KEY (`ID`) -- 声明主键
);
如果你有MySQL的一些管理工具,可以使用这些工具进行创建表,并不需要自己书写SQL语句,但笔者还是希望能够自己尝试去编写这些SQL,因为对于初学者而言,可以自己去编写这些SQL,无疑是对自己能力的一种提高。
9.3.2 设计种类表
种类表与出版社表一样,并不复杂,也没有任何的外键,根据9.2.5的界面,就可以确定需要哪些字段了。创建T_BOOK_TYPE表,包括以下的字段:
q ID:主键ID
q TYPE_NAME:种类的名称。
q TYPE_INTRO:种类的简介。
只有简单的三个字段,创建的SQL如下。
-- 书种类
CREATE TABLE IF NOT EXISTS `T_BOOK_TYPE` (
`ID` int AUTO_INCREMENT NOT NULL, -- 主键生成策略为自动增长
`TYPE_NAME` varchar(50), -- 种类名称
`TYPE_INTRO` varchar(200), -- 种类简介
PRIMARY KEY (`ID`)
);
9.3.3 设计书表
在9.2.4的界面中,我们可以看到,一本书所需要的字段包括:书名、简介、作者、所属种类、出版社、缩略图地址、库存和价格,种类表和出版社表已经在9.3.2与9.3.1中设计了,只需要为书表添加外键关系即可,新增表T_BOOK,以下为书表各个字段的描述:
q ID:主键ID
q BOOK_NAME:书的名字。
q BOOK_INTRO:书的简介。
q BOOK_PRICE:书的单价。
q TYPE_ID_FK:书所属的种类ID外键。
q PUB_ID_FK:出版社外键。
q IMAGE_URL:缩略图的地址。
q AUTHOR:作者名称。
q REPERTORY_SIZE:库存量。
这里需要注意一下,书的名字、简价、单价、所属的种类、出版社、缩略图和作者,都可以在界面中通过输入或者选择写入到数据库中,但是库存量是由销售与入库决定的,因此在修改书的时候,不可以设置书的库存量。创建该表的SQL如下。
-- 书
CREATE TABLE IF NOT EXISTS `T_BOOK` (
`ID` int AUTO_INCREMENT NOT NULL, -- ID字段,自增
`BOOK_NAME` varchar(50), -- 书名称
`BOOK_INTRO` varchar(200), -- 书简介
`BOOK_PRICE` double, -- 书的单价
`TYPE_ID_FK` int NOT NULL, -- 种类外键
`PUB_ID_FK` int NOT NULL, -- 出版社外键
`IMAGE_URL` varchar(200), -- 缩略图URL
`AUTHOR` varchar(200), -- 作者
`REPERTORY_SIZE` bigint(10), -- 库存数量
FOREIGN KEY (`TYPE_ID_FK`) REFERENCES `T_BOOK_TYPE` (`ID`), -- 声明种类的外键
FOREIGN KEY (`PUB_ID_FK`) REFERENCES `T_PUBLISHER` (`ID`), -- 声明出版社外键
PRIMARY KEY (`ID`)
);
9.3.4 设计入库记录表
在设计入库记录前,我们需要知道的是,一个入库记录,包含多本书的入库,也就是说,一次入库,有可能入库多本书。入库记录,只需要记录入库的时间即可,新建T_IN_RECORD表,该表的字段如下:
q ID:主键ID。
q RECORD_DATE:入库日期。
以下为创建该表的SQL。
-- 入库记录表, 一次入库会入多本书
CREATE TABLE IF NOT EXISTS `T_IN_RECORD` (
`ID` int AUTO_INCREMENT NOT NULL,
`RECORD_DATE` datetime, -- 入库日期
PRIMARY KEY (`ID`)
);
设计完入库记录后,我们还需要考虑,一次入库涉及了多本书,因此需要添加一个关系表,用来表示一次入库中所涉及的书。创建T_BOOK_IN_RECORD表,该表的字段如下:
q ID:该表的主键ID
q BOOK_ID_FK:书的外键,表示这一条书的入库记录所对应的书。
q T_IN_RECORD_ID_FK:入库记录的外键,表示这一条书的入库记录所对应的是哪一次入库,这个关系也表示了一次入库可以有多条书的入库记录。
q IN_SUM:这一条书的入库记录中对应的书的入库数量。
创建的SQL语句如下。
-- 书的入库记录
CREATE TABLE IF NOT EXISTS `T_BOOK_IN_RECORD` (
`ID` int AUTO_INCREMENT NOT NULL, -- ID自增
`BOOK_ID_FK` int, -- 入库的书
`T_IN_RECORD_ID_FK` int, -- 对应的入库记录
`IN_SUM` int(10), -- 入库数量
FOREIGN KEY (`BOOK_ID_FK`) REFERENCES `T_BOOK` (`ID`), -- 声明书的外键
FOREIGN KEY (`T_IN_RECORD_ID_FK`) REFERENCES `T_IN_RECORD` (`ID`), -- 声明入库记录外键
PRIMARY KEY (`ID`)
);
注:在入库表中,并没有提供入库总数量这个字段,这是由于入库总数量是各本书的入库数量的总和。因此并不需要在数据库中提供字段,只需要在程序中进行计算即可。
创建完了这两个表之后,就完成了书的入库相关表的设计。
9.3.5 设计销售记录表
销售记录表与入库记录表大同小异,都是需要创建一个销售表,再创建书的销售表。一条销售记录对应多条书的销售记录,一次销售所涉及多本书,与入库记录一样,都通过一个中关系表来体现这种关系。销售记录表的字段如下:
q ID:ID主键。
q RECORD_DATE:交易日期。
创建该表的SQL如下。
-- 交易记录表, 一个交易记录包括多个书的销售记录, 一次交易可能有多本书
CREATE TABLE IF NOT EXISTS `T_SALE_RECORD` (
`ID` int AUTO_INCREMENT NOT NULL,
`RECORD_DATE` datetime,-- 交易日期
PRIMARY KEY (`ID`)
);
创建了交易表后,再去设计书的交易表,具体字段与书的入库记录表相似:
q ID:主键ID
q BOOK_ID_FK:该条书的交易记录所对应的书。
q T_SALE_RECORD_ID_FK:该条书的交易记录所对应的交易记录。
q TRADE_SUM:该记录中对应的书的交易数量。
创建书的入库记录表的SQL如下。
-- 书的销售记录, 一条记录对应一本书
CREATE TABLE IF NOT EXISTS `T_BOOK_SALE_RECORD` (
`ID` int AUTO_INCREMENT NOT NULL,
`BOOK_ID_FK` int, -- 销售的书
`T_SALE_RECORD_ID_FK` int, -- 该书的销售记录所对应的交易记录
`TRADE_SUM` int(10), -- 销售数量
FOREIGN KEY (`BOOK_ID_FK`) REFERENCES `T_BOOK` (`ID`),
FOREIGN KEY (`T_SALE_RECORD_ID_FK`) REFERENCES `T_SALE_RECORD` (`ID`),
PRIMARY KEY (`ID`)
);
注:交易表中并没有提供交易总价和交易总数量这两个字段,这是由于这两个值是由各本书的交易量所决定的。
到此,数据库各个表的结构已经设计完成了,各个表的结构都十分简单,只有库存与销售两个模块的表相对复杂了一点。在下一节中,我们将讲解如何使用Java的反射进行对象与表的映射与使用JDBC进行数据库操作等知识。
9.4 开发前的准备工作
在9.3小节中,数据库已经设计好了,接下来可以准备开发的工作了。其实当设计好数据库,我们就可以进行开发,本小节中所讲的开发准备工作,是指编写一些公用的方法,例如JDBC的基本操作,包括查询、修改等。将一些可以重用的代码先编写好,再去进行业务开发,到业务开发的时候,可以事半功倍。
9.4.1 设计表的对应类
在9.3中,已经设计了系统所需要的各个表,包括出版社表、书种类表、书表等,那么现在,我们需要为这些表建立相应的对象,每一个表可以对应一个对象。可以为每个表的对象先建立一个父类,由于每个表中都有ID一列,因此我们可以建立一个父类,提供ID字段。
新建各个表对应对象的父类ValueObject,ValueObject的代码如下。
代码清单:code\book\src\org\crazyit\book\vo\ValueObject.java
public class ValueObject {
//ID字段,对应数据库中的ID列
private String ID;
//省略setter和getter方法
}
该类只提供了一个ID字段,并提供setter和getter方法,注意,ID属性必须与数据库中表的ID列名字对应,由于这个是各个表对象的父类,因此需要约定每个表的主键命名必须为ID,为什么需要这样,在下面章节将会详细讲述。
建立了父类ValueObject后,此时再去新建出版社所对应的实体Concern类,一个Concern对象代表一个出版社,该类继承于ValueObject,此外,出版社表中有的字段,都需要在这个类中反应出来。Concern类代码如下。
代码清单: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方法
}
销售记录类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 = "/cfg/jdbc.properties";//配置文件的路径
//读取资源文件, 设置输入流
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.driver");
JDBC_URL = properties.getProperty("jdbc.url");
JDBC_USER = properties.getProperty("jdbc.user");
JDBC_PASS = properties.getProperty("jdbc.pass");
}
}
读取的各个配置的作用,将在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,如果需要最新的驱动程序,请到xdev.mysqlx/downloads/connector/j/5.1.html下载,下载后将驱动包加到环境变量中。除了配置驱动外,还需要
展开阅读全文