====================
eclipse + widowbuilder
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/ —> 用来找图标的网站
关联了bookTypeId和Id
也就是说BookType数据库的id 代表着 Book中类别的Id,例如类型1,类型7,其中1和7就是BookType中的id
在com.luo.Util中封装了连接数据库的一个DbUtil类
首先需要4个成员变量:
接下来是连接数据库的方法函数
还有关闭数据库的方法函数
/**
* 连接数据库工具
* @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();
}
}
这次的小项目分别建立了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
}
以下是其中一个Book类的数据交互的代码,也就是连接用户输入的数据和数据库里面的数据的操作
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();
}
}
通过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));
点击按钮监听事件操作。比如点击添加键,就从数据库中获取数据显示在界面上,其实就是对数据库的操作和数据放在界面上显示的处理
这是项目中,获取数据在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();
}