您的位置:首页 > 编程语言 > Java开发

关于Java小项目——图书管理系统的总结

2016-02-19 23:02 731 查看
====================

网上看完视频写完这个小项目后,总结一下自己遇到的问题。。。

一、开发环境

eclipse + widowbuilder


二、涉及到的技术

Java MVC模式

Swing

MySQL

JDBC

Java MVC模式

M——Model(模型)。用于处理应用程序数据逻辑的部分。建立相关的类来连接数据库存储数据,例如用户类,图书类,图书类别类,把能够抽象化成一个一个的类写在这一部分

V——View(视图)。所有用户看到的界面,写在这一部分。这次用windowbuilder的这一插件来写视图

C——Contraller(控制器)。这部分主要是用来连接Model和View这两部分的,关于用户交互的操作的方法函数写在这一部分

首先,创建了几个包用来写不同模块的代码!


com.luo.Model一个包用来写Model这一模块

com.luo.View一个包用来写View这一模块

com.luo.Dao一个包用来写Controller这一模块

另外,还创建com.luo.Util一个包用来封装相关的工具类,例如我们会重复需要连接数据库,这时候就先封装好一个连接数据库的那一部分的 工具类。后面连接起来就方便多了。

com.luo.Image这个包是用来存放项目中用到的图标和图片

http://www.easyicon.net/ —> 用来找图标的网站

MySQL部分

关联了bookTypeId和Id

也就是说BookType数据库的id 代表着 Book中类别的Id,例如类型1,类型7,其中1和7就是BookType中的id



在com.luo.Util中封装了连接数据库的一个DbUtil类

首先需要4个成员变量:

数据库的名字,”jdbc:mysql://localhost:3306/(这里写数据库的名字)”

MySQL的用户名

MySQL的密码

JDBC驱动的名字 “com.mysql.jdbc.Driver”

接下来是连接数据库的方法函数

通过Class调用forName()

然后通过DriverManager调用getConnection()

最后返回一个Connection类型值

还有关闭数据库的方法函数

通过传入的Connection类型的值调用Close()

/**
* 连接数据库工具
* @author Administrator
*
*/
public class DbUtil {

private String dbUrl = "jdbc:mysql://localhost:3306/db_book";
private String UserName = "root";
private String Password = "123456";
private String jdbcName = "com.mysql.jdbc.Driver";

/**
* 连接数据库
* @return
* @throws Exception
*/
public Connection getCon() throws Exception {
Class.forName(jdbcName);
Connection conn = DriverManager.getConnection(dbUrl, UserName, Password);
return conn;
}

/**
* 关闭数据库
* @param conn
* @throws Exception
*/
public void Closecon(Connection conn) throws Exception {
if( conn != null){
conn.close();
}
}


Model模块

这次的小项目分别建立了User类Book类BookType类。其中,后面需要用到这些类的构造方法传入参数,所以注意,要构造一个不带参数的构造函数,这样后面就可以new一个空的类了。

以下是其中一个用户类的代码,

public class User {

private int id;
private String userName;
private String password;

public User() {
super();
} //不带参数的构造函数

public User(String userName, String password) {
super();
this.userName = userName;
this.password = password;
} //带两个参数的构造函数

/**********************************
分别创建成员变量get()和set()方法
***********************************/
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}


还有一点,BooType类中重写了toString()的方法。当把BookType类的对象当作参数传进去,显示出来的并不是它里面的数据,而是它的地址。所以重写toString()方法来显示BookType类的对象里面的数据

后面只需用到BookType类中的一个成员变量BookTypeName

public String toString() {
return BookTypeName; //直接返回BookTypeName
}


Controller模块和JDBC

以下是其中一个Book类的数据交互的代码,也就是连接用户输入的数据和数据库里面的数据的操作

MySQL的语句,增删查改,String类型

调用prepareStatement()来预处理,

调用setString(),设置MySQL语句中?的内容

executUpdate(),返回int类型; 若execuQuer(); 返回ResultSet类型

package com.luo.Dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

import com.luo.Model.Book;
import com.luo.Model.BookType;
import com.luo.Util.StringUtil;

public class BookDao {

/**
* 图书添加
* @param con
* @param book
* @return
* @throws Exception
*/
public int Add(Connection con, Book book) throws Exception {
String sql = "insert into t_book values(null,?,?,?,?,?,?)";
PreparedStatement pstmt = con.prepareStatement(sql);
pstmt.setString(1, book.getBookName());
pstmt.setString(2, book.getAuthor());
pstmt.setString(3, book.getSex());
pstmt.setFloat(4, book.getPrice());
pstmt.setInt(5, book.getBookTypeId());
pstmt.setString(6, book.getBookDesc());
return pstmt.executeUpdate();
}

/**
* 查询
* @param con
* @param book
* @return
* @throws Exception
*/
public ResultSet list(Connection con, Book book) throws Exception{
StringBuffer sb = new StringBuffer("select * from t_book b,t_booktype bt where b.bookTypeId = bt.id");
if(StringUtil.isNotEmpty(book.getBookName())){
sb.append(" and b.bookName like '%"+ book.getBookName() +"%'");
}
if(StringUtil.isNotEmpty(book.getAuthor())){
sb.append(" and b.author like '%"+ book.getAuthor() +"%'");
}
if(book.getBookTypeId()!=null && book.getBookTypeId()!=-1){
sb.append(" and b.bookTypeId="+ book.getBookTypeId());
}
PreparedStatement pstmt = con.prepareStatement(sb.toString());
return pstmt.executeQuery();
}

/**
* 更新数据
* @param con
* @param book
* @return
* @throws Exception
*/
public int upDate(Connection con, Book book) throws Exception {
String sql = "UpDate t_book set bookName=?, author=?, sex=?, price=?, bookTypeId=?, bookDesc=? where id=?";
PreparedStatement pstmt = con.prepareStatement(sql);
pstmt.setString(1, book.getBookName());
pstmt.setString(2, book.getAuthor());
pstmt.setString(3, book.getSex());
pstmt.setFloat(4, book.getPrice());
pstmt.setInt(5, book.getBookTypeId());
pstmt.setString(6, book.getBookDesc());
pstmt.setInt(7, book.getId());
return pstmt.executeUpdate();
}

/**
* 删除数据
* @param con
* @param id
* @return
* @throws Exception
*/
public int Delete(Connection con, int id) throws Exception {
String sql = "Delete from t_book where id=?";
PreparedStatement pstmt = con.prepareStatement(sql);
pstmt.setInt(1, id);
return pstmt.executeUpdate();
}

/**
* 判断是否存在书
* @param con
* @param book
* @return
* @throws Exception
*/
public boolean existBook(Connection con, String bookTypeId) throws Exception {
String sql = "select * from t_book where bookTypeId =?";
PreparedStatement pstmt = con.prepareStatement(sql);
pstmt.setInt(1, Integer.parseInt(bookTypeId));
ResultSet rs = pstmt.executeQuery();
return rs.next();
}
}


View模块

登录界面

主界面

图书类别添加界面

图书类别管理界面

图书添加界面

图书维护界面

通过windowbuilder插件来创建一个Frame

登录界面通过登录按钮跳到主界面

以下是登录按钮响应事件的操作

/**
* 登录操作
* @param e
*/
private void loginActionPerformed(ActionEvent e) {
String userName = this.userNameTxt.getText();
String password = new String(this.passwordTxt.getPassword());
//判断输入是否为空
if(StringUtil.isEmpty(userName)) {
JOptionPane.showMessageDialog(null, "用户名不能为空");
return;
}
if(StringUtil.isEmpty(password)){
JOptionPane.showMessageDialog(null, "密码不能为空");
return;
}
Connection conn = null;
try {
//连接数据库
conn = dbUtil.getCon();
User user = new User(userName, password);
User correntUser = userdao.login(conn, user);
if(correntUser != null){
/**************************************
这里先调用dispose()的方法,把当前的界面关掉
再通过new出新的主界面,跳转到主界面上去
***************************************/
dispose();
new MainFrame().setVisible(true);

} else {
JOptionPane.showMessageDialog(null, "用户名或密码错误!");
}

} catch (Exception e1) {
e1.printStackTrace();
} finally {
try {
dbUtil.Closecon(conn);
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}


登录界面和主界面的类都是继承JFrame

从工具栏选择一个JDesktopPane放置到contenPane里面,将它重命名为table

点击menuBar的一个选项,让它弹出一个界面(通过windowbuilder插件创建一个JInternalFrame,该选项添加响应事件,通过table调用add()的方法把这个界面显示出来),这个界面的类继承JInternalFrame,只能出现在table里面

这里的BookTypeManagerFrame是其中一个继承JInternalFrame的类显示出的框会在主界面里面

//  监听菜单栏上的图书类别管理这一选项的响应
mntmNewMenuItem_2.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
BookTypeManagerFrame bookTypeManagerFrame = new BookTypeManagerFrame();//new出一个新的图书类别管理类
bookTypeManagerFrame.setVisible(true); //设置可见
table.add(bookTypeManagerFrame); //添加进来主界面上
}
});


这是主界面的结构图,menuBar和一个contenPane







我们可以拖入JTextArea来放置图这样一大段文字描述图书的内容

但是呢,一开始拖入JTextArea进来视图显示是没有边框

所以呢,要在该界面对应的代码中加入

bookTypeDesc.setBorder(new LineBorder(new java.awt.Color(12, 157, 185), 1, false));


点击按钮监听事件操作。比如点击添加键,就从数据库中获取数据显示在界面上,其实就是对数据库的操作和数据放在界面上显示的处理

getText()获取用户输入的内容

工具类DbUtil,连接数据库

调用Controller模块里面的类的方法,实现相关操作

连接完数据库记得关闭!

中间加上一些业务逻辑判断

这是项目中,获取数据在JTextField控件显示的小例子

至于重置编辑框为空的操作就是简单地重写setText(“”)一下;

//通过对按钮的监听,具体实现代码创建一个AddActionPerformed()方法写在外面,这里执行AddActionPerformed()方法
btnNewButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
AddActionPerformed(e);
}
});


/**
* 添加数据
* @param evt
*/
private void AddActionPerformed(ActionEvent evt) {
String Name = bookTypeName.getText();
String Desc = bookTypeDesc.getText();
if(StringUtil.isEmpty(Name)){
JOptionPane.showMessageDialog(null, "图书类别名称不能为空");
return;
}
BookType bookType = new BookType(Name, Desc);
Connection con = null;
try {
con = dbUtil.getCon();
int result = bookTypeDao.addBookType(con, bookType);
if(result == 1){
JOptionPane.showMessageDialog(null, "添加成功!");
reset();
} else {
JOptionPane.showMessageDialog(null, "添加失败!");
}

} catch (Exception e1) {
// TODO Auto-generated catch block
JOptionPane.showMessageDialog(null, "添加失败!");
e1.printStackTrace();
} finally{
try {
dbUtil.Closecon(con);
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}

}


用一个表格来显示数据。拖入scrollPane,然后在它里面拖入Jtable,通过Jtable的model属性设置表的标题与行列数。接着可以通过表格Jtable的mousePressed,来响应鼠标操作,从而对表中点击到的那一行的数据操作,显示在JTextField上

/**
* 填充列表
* @param book
*/
private void fillTable(Book book){
DefaultTableModel dtm = (DefaultTableModel) bookTable.getModel();
dtm.setRowCount(0);
Connection con = null;
try {
con = dbUtil.getCon();
ResultSet rs = bookDao.list(con, book);
while(rs.next()){
Vector v = new Vector();
v.add(rs.getString("id"));
v.add(rs.getString("bookName"));
v.add(rs.getString("author"));
v.add(rs.getString("sex"));
v.add(rs.getString("price"));
v.add(rs.getString("bookDesc"));
v.add(rs.getString("bookTypeName"));
dtm.addRow(v);
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}


this.fillTable(new Book()); //调用此填充表格的方法函数


点击鼠标响应事件

bookTypeTable.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
bookTypeTableMousePressed(e);
}
});


/**
* 点击图表显示事件
* @param evt
*/
private void bookTypeTableMousePressed(MouseEvent evt) {
int row = bookTypeTable.getSelectedRow(); //获取当前的行号
//界面上对应控件通过调用setText()来显示出那一行的数据
idTxt.setText((String) bookTypeTable.getValueAt(row, 0));
bookTypeNameTxt.setText((String) bookTypeTable.getValueAt(row, 1));
bookTypeDescTxt.setText((String) bookTypeTable.getValueAt(row, 2));
}


关于下面这两种选择的数据填充:





这两个控件分别重命名为s_bookTypeBox和m_bookTypeBox,通过这两个名字来调用addItem()函数填充数据

按照面向对象的思想,直接传入的参数是BookType类的对象,所以要重写该类的toString()方法(前面提到的)。

/**
* 填充bookType
* @param type
*/
private void fillBookType(String type){
Connection con = null;
BookType bookType = null;
try {
con = dbUtil.getCon();
ResultSet rs = bookTypeDao.list(con, new BookType());
if("search".equals(type)){
bookType = new BookType();
bookType.setBookTypeName("请选择...");
bookType.setId(-1);
this.s_bookTypeBox.addItem(bookType);
}
while(rs.next()){
bookType = new BookType();
bookType.setBookTypeName(rs.getString("bookTypeName"));
bookType.setId(rs.getInt("id"));
if("search".equals(type)){
this.s_bookTypeBox.addItem(bookType);
} else if("modify".equals(type)){
this.m_bookTypeBox.addItem(bookType);
}
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}


this.fillBookType("modify");
this.fillBookType("search");


补充一下上面用到的list()

模糊查询

/**
* 查询
* @param con
* @param bookType
* @return
* @throws Exception
*/
public ResultSet list(Connection con, BookType bookType) throws Exception{
StringBuffer sb = new StringBuffer("select * from t_booktype ");
if(StringUtil.isNotEmpty(bookType.getBookTypeName())){
sb.append("and bookTypeName like '%"+ bookType.getBookTypeName() +"%'");
}
PreparedStatement pstmt = con.prepareStatement(sb.toString().replaceFirst("and", "where"));
return pstmt.executeQuery();
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: