亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > Java > 正文

總結:JAVA小項目——圖書管理系統

2019-11-11 06:00:38
字體:
來源:轉載
供稿:網友

總結:java小項目——圖書管理系統

一、用到的工具

1.eclipse+windowbuilder插件

2.MySQL數據庫+SQLyog

 

二、涉及的知識點

1. MVC設計模式

2. Swing

3. JDBC+MySQL

 

三、框架搭建

按照MVC設計模式在eclipse中新建項目,導入項目中要用到的圖標,在數據庫中創建表(以及表之間的主外鍵關聯),用JDBC知識成功連接數據庫。

 

【JAVA%20MVC】

即把一個應用的輸入、處理、輸出流程按照Model、View、Controller的方式進行分離,這樣一個應用被分成三個層——模型層、視圖層、控制層。

M——Model(模型)。業務流程/狀態的處理以及業務規則的制定。把抽象的概念化成一個個類,例如User、Book、BookType。

V——View(視圖)。視圖接收來自Model的數據并顯示給用戶,以及將用戶界面的輸入數據和請求傳遞給Controller和Model。此部分用windowbuilder插件來實現。

C——Controller(控制器)。這部分主要是用來連接Model和View這兩部分,控制層收到請求后,%20并不處理業務信息,它只把用戶的信息傳遞給相應的Model,告訴模型做什么,選擇符合要求的View返回給用戶。關于用戶交互的操作的方法函數寫在這一部分。

——包com.BookManager.dao用來寫Controller這一模塊;

——包com.BookManager.model用來寫Model這一模塊;

——包com.BookManager.view用來寫View這一模塊;

另外,將多次使用的工具類都寫在com.BookManager.util包中,如數據庫連接、判斷字符串是否為空。

 

【包images】

下載好圖標后,新建一個images包,將復制好的圖標直接ctrl+v粘貼進來即可。包images用來存放項目中用到的圖標和圖片(http://www.easyicon.net/ )

 

【數據庫創建表】

1.【varchar】數據庫創建表時,對于userName等項應設置成varchar數據類型,char是定長的字符,varchar[n]存儲大小為輸入數據字節的實際長度,而不是%20n%20個字節。

2.【主外鍵關聯】

主鍵的主要作用是將記錄和存放在其他表中的數據進行關聯,在這一點上,主鍵是不同表中各記錄間的簡單指針,不能有重復的,不允許為空。

外鍵是另一表的主鍵,可以有重復,可以是空值,用來和其他表建立聯系用的。所以說,如果談到了外鍵,一定至少涉及兩張表。外鍵約束主要用來維護兩個表之間數據的一致性。

在SQLyog軟件中,點擊“架構設計器”拖動要關聯的兩張表,如下圖所示。

【JDBC】

1.【數據庫中創建表】t_User,設置用戶名及密碼。

2.【驅動】下載MySQL相應的驅動包,新建jdbc文件夾,將包復制粘貼到此文件夾中,然后Build%20Path—>Addto%20Build%20Path,就將此包添加到項目中了。

3.【按MySQL格式寫代碼】封裝DbUtil類。代碼中按下快捷鍵ctrl+shift+o要導入sql的包時,應選擇jdbc的接口——java.sql.Connection,如下圖所示。

 

四、代碼總結

<一>Model模塊

在Model中將抽象概念Book、BookType、User用代碼變量描述出來,即創建實體的描述。

Alt+Shift+s彈出自動生成語句的菜單(創建成員變量get()和set()方法)。

用到包裝類,以便能將基本類型當作對象處理。

【特別注意】構造方法中形參的每一項(順序)都要與數據庫中相應表中的欄目名稱和類型保持一致。

此外,BooType類中重寫了toString()的方法。因為把BookType類的對象當作參數傳進去后,顯示出來的并不是它里面的數據,而是它的地址。所以重寫toString()方法來顯示BookType類的對象里面的數據。

 

<二>Controller模塊

連接用戶輸入的數據和數據庫里面的數據的操作。在其他類中用到這些類的方法時,要先new相應的對象。

1.用戶登錄——UserDao.java

實現用戶登錄數據庫功能,即輸入用戶名和密碼,如果數據庫的t_user表中含有匹配的用戶名和密碼,就能登錄成功。所以,此方法應該為User類型,傳入參數為數據庫連接和用戶——public User login(Connection con, Useruser)throws Exception{}

·先定義變量sql,賦予MySQL的原始語句;

·調用PRepareStatement()來預處理sql;

·調用setString(),設置MySQL語句中占位符的內容;

·調用executeQuery();返回ResultSet結果集。【注意】調用此方法后,已經執行了sql語句的查詢功能,即比對查詢數據庫中是否有將要輸入(占位符)的數據。而數據的接收(輸入數據)是在View模塊中實現的,兩個模塊的變量相互呼應。

·判斷查詢數據庫的結果集是否含有輸入的記錄if(rs.next()),如果有,則實例化用戶對象,并對其記錄進行設置。

 

public class UserDao {		public User login(Connection con,User user)throws Exception{		User resultUser = null;		/**		 * PreparedStatement接口是Statementd的子接口,用于預編譯SQL語句。		 * 預編譯后的SQL語句被存儲在PreparedStatement對象中,		 * 然后可以使用該對象多次高效率地執行該語句(比Statement的效率高)。		 * 		 * Statement執行SQL語句時不允許使用問號占位符參數		 * PreparedStatement執行SQL語句時可以使用占位符,執行SQL語句之前必須為這些參數傳入參數值		 * 		 * PreparedStatement也提供了execute()、executeUpdate()、executeQuery()三個方法執行SQL語句,		 * 不過他們無需參數,因為PreparedStatement已經存儲了預編譯的SQL語句		 */		String sql = "select*from t_user where userName=? and passWord=?";		PreparedStatement pstmt = con.prepareStatement(sql);		pstmt.setString(1, user.getUserName());		pstmt.setString(2, user.getPassword());				ResultSet rs = pstmt.executeQuery();		/**		 * 【注意】調用此方法后,已經執行了sql語句的查詢功能,		 * 即比對查詢數據庫中是否有將要輸入(占位符)的數據。		 * 而數據的接收(輸入數據)是在View模塊中實現的,		 * 兩個模塊的變量相互呼應。		 */		if(rs.next()){			resultUser = new User();			resultUser.setId(rs.getInt("id"));			resultUser.setUserName(rs.getString("userName"));			resultUser.setPassword(rs.getString("password"));		}		return resultUser;	}}

2.圖書類別操作——BookTypeDao.java

實現圖書類別的添加、刪除、查詢顯示和修改維護以及判斷此類別是否含有圖書。

【SQL語句拼接】因為是動態查詢,bookTypeName可能沒有值,因此涉及到判斷是否為空,所以要用“拼接”的方式來寫SQL語句——

·用StringBuffer暫存一下字符串;

·符合判斷條件時,用append拼接,拼接的SQL語句用and連接,之后再替換成where(因為在拼接的兩段SQL語句中,where的位置可能會造成多個if時的混亂,所以采用替換的方式來處理);

·用toString()將StringBuffer中的內容轉換成字符串,再將字符串內容的第一個and替換成where,即正式的SQL語句。

public ResultSet list(Connection con,BookType bookType) throws Exception{		StringBuffer sb = new StringBuffer("select*from t_bookType ");//用StringBuffer暫存一下字符串		if(StringUtil.isNotEmpty(bookType.getBookTypeName())){			//因為是動態查詢,bookTypeName可能沒有值,所以要用“拼接”的方式來寫SQL語句			sb.append(" and bookTypeName like '%" +bookType.getBookTypeName()+"%'");		}		//先用toString()將StringBuffer中的內容轉換成字符串,再將字符串內容的第一個and替換成where,即正式的SQL語句		//在拼接的兩段SQL語句中,where的位置可能會造成多個if時的混亂,所以采用替換的方式來處理		PreparedStatement pstmt = con.prepareStatement(sb.toString().replaceFirst("and", "where"));		return pstmt.executeQuery();	} 

3.圖書操作——BookDao.java

實現圖書的添加、查詢、刪除、修改。

兩個表的關聯查詢。

 

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());		/**		 * 【特別注意】對每一個"?"進行設置時都要與數據庫中t_book表中的欄目名稱和類型保持一致.		 * 比如:		 * 如果原t_book表中第6欄是price,則第六個"?"處就代表price,類型就是float,		 * 那么若執行pstmt.setString(6, book.getBookDesc());就會因為名稱和類型不一致而報錯		 */		pstmt.setString(2, book.getAuthor());		pstmt.setString(3, book.getSex());		pstmt.setInt(4, book.getBookTypeId());		pstmt.setString(5, book.getBookDesc());		pstmt.setFloat(6, book.getPrice());		return pstmt.executeUpdate();//為什么不能方法返回值為void,并把return去掉——————									//executUpdate()本身返回int類型,返回受影響的記錄條數。									//也便于后面根據返回值而進一步判斷執行	}		/**	 * 圖書信息查詢	 * @param con	 * @param book	 * @return	 * @throws Exception	 */	public ResultSet list(Connection con ,Book book)throws Exception{		//t_book表中的id關聯到了t_bookType表的bookTypeId,所以要執行兩個表的關聯查詢		//t_book表的外鍵等于t_bookType表的主鍵		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()+"%'");//like模糊查詢		}		if(StringUtil.isNotEmpty(book.getAuthor())){			sb.append(" and b.author like '%"+book.getAuthor()+"%'");// '% "關鍵詞" %' 比如 '%java%'		}		//此時才表示用戶選中了圖書類別。(類別選擇框中“請選擇”的ID在BookManageInterFrm中已設為-1)		if(book.getBookTypeId()!=null&&book.getBookTypeId()!=-1){			sb.append(" and b.bookTypeId="+book.getBookTypeId());		}//		PreparedStatement pstmt = con.prepareStatement(sb.toString().replaceFirst("and", "where"));		PreparedStatement pstmt = con.prepareStatement(sb.toString());//只能有一個where,所以不需要再把and替換成where		return pstmt.executeQuery();			}	/**	 * 圖書信息刪除	 * @param con	 * @param id	 * @return	 * @throws Exception	 */	public int delete(Connection con ,String id)throws Exception{		String sql = "delete from t_book where id=?";		PreparedStatement pstmt = con.prepareStatement(sql);		pstmt.setString(1, id);		return pstmt.executeUpdate();	}	/**	 * 圖書信息修改	 * @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=?,bookTypeId=?,bookDesc=?,price=?where id=?";		PreparedStatement pstmt = con.prepareStatement(sql);		pstmt.setString(1, book.getBookName());		pstmt.setString(2, book.getAuthor());		pstmt.setString(3, book.getSex());		pstmt.setInt(4, book.getBookTypeId());		pstmt.setString(5, book.getBookDesc());		pstmt.setFloat(6, book.getPrice());		pstmt.setInt(7, book.getId());//要注意sql語句中要有"where id=?"		return pstmt.executeUpdate();	}	}

<三>View模塊

借助windowbuilder插件,新建類時new—>other—>windowbuilder

記得將窗體部件重命名,以便代碼中當作對象調用方法。并且相關部件要在開頭聲明(有些自動生成的代碼沒有在開頭申明需要手動調整完善)

【表格顯示查詢結果】拖入scrollPane,然后在它里面拖入Jtable,通過Jtable的model屬性設置表的標題與行列數,注意一定要與數據庫中的順序類型保持一致。

/**	 * 顯示結果表單	 * @param book	 */	private void fillTable(Book book){		DefaultTableModel dtm = (DefaultTableModel) bookTable.getModel();//提前將table組件改名		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.getInt("id"));				v.add(rs.getString("bookName"));				v.add(rs.getString("author"));				v.add(rs.getString("sex"));				v.add(rs.getString("bookTypeName"));//與數據庫的順序、名稱保持一致				v.add(rs.getString("bookDesc"));				v.add(rs.getFloat("price"));				dtm.addRow(v);			}					}catch(Exception e){			e.printStackTrace();		}finally{			try {				dbUtil.closeCon(con);			} catch (SQLException e) {				// TODO Auto-generated catch block				e.printStackTrace();			}		}	}

【初始化下拉框】

/**	 * 初始化下拉框	 * @param type	 */	private void fillBookType(String type){		Connection con = null;		try{			con = dbUtil.getCon();			ResultSet rs = bookTypeDao.list(con, new BookType());			//在選擇下拉框里添加未選擇時的"請選擇"			if("search".equals(type)){				BookType bookType = new BookType();				bookType.setBookTypeName("請選擇");				bookType.setId(-1);//設置新添加的"請選擇"的ID為-1				this.s_bookTypeJcb.addItem(bookType);//將此項添加到下拉框中			}			while(rs.next()){				BookType bookType = new BookType();				bookType.setBookTypeName(rs.getString("bookTypeName"));				bookType.setId(rs.getInt("id"));				if("search".equals(type)){					this.s_bookTypeJcb.addItem(bookType);				}else if("modify".equals(type)){					this.bookTypeJcb.addItem(bookType);				}			}		}catch(Exception e){			try {				dbUtil.closeCon(con);			} catch (SQLException e1) {				// TODO Auto-generated catch block				e1.printStackTrace();			}		}	}

【JRadioButton】要執行右鍵,setButtonGroup將兩個JRadioButton按鈕加入到一個組中,才能實現二選一(非此即彼)。

【表格點擊對應顯示】

/**	 * 表格行點擊事件處理	 * 將選中的行的信息分別顯示到面板中相應的項里	 * @param met	 */	private void bookTableMousePressed(MouseEvent met) {		int row = this.bookTable.getSelectedRow();//獲取的是行號		//要與數據庫中的各項順序一致		this.idTXT.setText((Integer) bookTable.getValueAt(row, 0)+"");//【注意】id在fillTable方法中是getInt類型													//所以此處應為Integer類型,但是setText方法里面是String類型													//采取的辦法就是【(Integer)+""】形式來轉成String。否則報錯。													//下面Float同理		this.bookNameTXT.setText((String) bookTable.getValueAt(row, 1));		this.authorTXT.setText((String) bookTable.getValueAt(row, 2));		//"性別"是獲取后在選項前勾選的,不能直接設置文本顯示		String sex = (String) bookTable.getValueAt(row, 3);		if("男".equals(sex)){			this.manJrb.setSelected(true); 		}		if("女".equals(sex)){			this.femaleJrb.setSelected(true);		}		//"圖書類別"是下拉框顯示,也不能直接設置文本顯示		String bookTypeName = (String) bookTable.getValueAt(row, 4);		int n = bookTypeJcb.getItemCount();//下拉框bookTypeJcb中有n個項		for(int i=0;i<n;i++){//遍歷n個項,如果其中第i項(item)的名稱與點擊行的bookTypeName相同,則下拉框顯示此i項			BookType item = (BookType) bookTypeJcb.getItemAt(i);//【注意】此處獲取的是圖書類別對象,不是圖書類別名稱			if(item.getBookTypeName().equals(bookTypeName)){				this.bookTypeJcb.setSelectedIndex(i);//下拉框顯示此i項			}		}		this.bookDescTXT.setText((String) bookTable.getValueAt(row, 5));		this.priceTXT.setText((Float) bookTable.getValueAt(row, 6)+"");	}【圖書信息修改】

/**	 * 圖書修改事件處理	 * @param evt	 */	private void bookUpdateActionPerformed(ActionEvent evt) {		String id = idTXT.getText();//因為id是int類型,所以創建對象時傳入參數要進行類型轉換Integer.parseInt(id)		if(StringUtil.isEmpty(id)){			JOptionPane.showMessageDialog(null, "請選擇要修改的圖書");			return;		}		String bookName = this.bookNameTXT.getText();		String bookDesc = this.bookDescTXT.getText();		String author = this.authorTXT.getText();		String price = this.priceTXT.getText();		if(StringUtil.isEmpty(bookName)){			JOptionPane.showMessageDialog(null, "圖書名稱不能為空");			return;//不能少了return		}		if(StringUtil.isEmpty(author)){			JOptionPane.showMessageDialog(null, "圖書作者不能為空");			return;//不能少了return		}		if(StringUtil.isEmpty(price)){			JOptionPane.showMessageDialog(null, "圖書價格不能為空");			return;//不能少了return		}		String sex = "";		if(manJrb.isSelected())			sex = "男";		if(femaleJrb.isSelected())			sex = "女";				BookType bookType = (BookType) bookTypeJcb.getSelectedItem();		int bookTypeId = bookType.getId();		Book book = new Book( Integer.parseInt(id), bookName,  author,  sex,  bookTypeId,  bookDesc, Float.parseFloat(price) );				Connection con = null;		try{			con = dbUtil.getCon();			int updateNum = bookDao.update(con, book);			if(updateNum==1){				JOptionPane.showMessageDialog(null, "圖書修改成功");				resetValue();				this.fillTable(new Book());//實時修改刷新表單			}else{				JOptionPane.showMessageDialog(null, "圖書修改失敗");			}		}catch(Exception e){			e.printStackTrace();			JOptionPane.showMessageDialog(null, "圖書修改失敗");		}finally{			try {				dbUtil.closeCon(con);			} catch (SQLException e) {				// TODO Auto-generated catch block				e.printStackTrace();			}		}	}	private void resetValue() {		this.idTXT.setText("");		this.bookNameTXT.setText("");		this.authorTXT.setText("");		this.priceTXT.setText("");		this.bookDescTXT.setText("");		this.manJrb.setSelected(true);		if(this.bookTypeJcb.getItemCount()>0)//圖書類別不為空		{			this.bookTypeJcb.setSelectedIndex(0);//表單第一項選中		}	}


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
久热精品视频在线| 国产精品视频色| 国产精品久久色| 欧美在线视频免费播放| 97精品视频在线| 久久精品电影网| 国产91av在线| 亚洲精品一区二区三区不| 久久精品国产久精国产思思| 欧美国产日韩一区二区在线观看| 操日韩av在线电影| 精品久久久久久久中文字幕| 国产亚洲精品va在线观看| 国产97在线亚洲| 亚洲欧美综合区自拍另类| 亚洲一区二区三区在线视频| 久久综合久久八八| 最近更新的2019中文字幕| 久久国产精彩视频| 91av视频在线播放| 欧美理论在线观看| 国产亚洲日本欧美韩国| 国产精品欧美在线| 日韩免费av片在线观看| 国产+成+人+亚洲欧洲| 懂色av影视一区二区三区| 欧美激情喷水视频| 国产福利精品av综合导导航| 久久久精品视频成人| 97视频在线观看成人| 美女av一区二区三区| 精品精品国产国产自在线| 欧美激情一级二级| 在线观看日韩视频| 91精品中文在线| 久久大大胆人体| 国产美女主播一区| 欧美高跟鞋交xxxxxhd| 欧美激情2020午夜免费观看| 欧美一级电影免费在线观看| 久久青草精品视频免费观看| 成人黄色在线播放| 自拍亚洲一区欧美另类| 国产成人亚洲综合91| 亚洲国产精品久久精品怡红院| 国产精品电影在线观看| 亚洲性av在线| 欧美日韩精品在线观看| 国产精品网红福利| 国产91精品高潮白浆喷水| 91超碰中文字幕久久精品| 精品国产电影一区| 全色精品综合影院| 日本在线精品视频| 亚洲男人av在线| 久久精品国产久精国产思思| 5252色成人免费视频| 亚洲美女免费精品视频在线观看| 日产精品99久久久久久| 日韩经典中文字幕在线观看| 中文字幕欧美国内| 欧美一级大胆视频| 欧美中文字幕在线播放| 日韩动漫免费观看电视剧高清| 亚洲色图美腿丝袜| 亚洲国产成人精品女人久久久| 欧美性xxxxxxx| 国产精品v片在线观看不卡| 亚洲人成在线免费观看| 国产亚洲福利一区| 中文字幕欧美精品日韩中文字幕| 国产日韩av在线播放| 国产精品高清在线| 国产精品久久在线观看| 韩国国内大量揄拍精品视频| 美女久久久久久久| 国产一区二区三区中文| 日本久久精品视频| 国产精品免费观看在线| 欧美成人一区二区三区电影| 欧美理论电影在线观看| 国产在线观看不卡| 久久最新资源网| 欧美日韩亚洲系列| 久久国产精品免费视频| 久久精品国产96久久久香蕉| 亚洲高清一二三区| 欧美精品一区二区免费| 亚洲福利视频网| 久久久天堂国产精品女人| 久久韩国免费视频| 日韩在线视频播放| 国内揄拍国内精品少妇国语| 国产视频精品在线| 色伦专区97中文字幕| 亚洲3p在线观看| 日本午夜精品理论片a级appf发布| 成人黄色av免费在线观看| 另类少妇人与禽zozz0性伦| 欧美激情第99页| 亚洲精品电影网| 亚洲香蕉伊综合在人在线视看| 亚洲精品一区在线观看香蕉| 日韩中文字幕国产精品| 欧美日韩免费看| 国产成人高清激情视频在线观看| 久久国产精品视频| 亚洲国语精品自产拍在线观看| 欧美性猛交xxx| 亚洲伊人一本大道中文字幕| 国产精品偷伦一区二区| 九九九久久国产免费| 欧美一级淫片videoshd| 日韩精品视频观看| 91免费在线视频网站| 26uuu另类亚洲欧美日本一| 全亚洲最色的网站在线观看| 国产又爽又黄的激情精品视频| 深夜福利一区二区| 国产精品成人va在线观看| 日本成人精品在线| 欧美激情2020午夜免费观看| 日韩成人高清在线| 国产午夜精品视频免费不卡69堂| 伊人伊成久久人综合网小说| 欧美极品美女电影一区| 国产日韩精品综合网站| 91网在线免费观看| 亚洲国产精品小视频| 色婷婷综合久久久久中文字幕1| 欧美疯狂性受xxxxx另类| 亚洲另类xxxx| 亚洲国产美女精品久久久久∴| 久久久久久成人| 久久韩国免费视频| 国内精品久久久久久久| 欧美激情第三页| 国模私拍视频一区| 国产精品久久久久久中文字| 69久久夜色精品国产69| 色哟哟入口国产精品| 69av在线视频| 欧美刺激性大交免费视频| 成人网在线免费看| 日本韩国在线不卡| 另类美女黄大片| 97视频网站入口| 成人国内精品久久久久一区| 欧美激情久久久久久| 欧美激情一二三| 国产一区二区三区在线看| 欧美激情精品久久久久久黑人| 国产精品高潮呻吟久久av无限| 26uuu久久噜噜噜噜| 精品久久久久久亚洲国产300| xvideos亚洲人网站| 久久99久久99精品中文字幕| 日韩在线视频线视频免费网站| 亚洲成人精品视频在线观看| 久久精彩免费视频| 国产一区二区三区在线观看视频| 国产欧美欧洲在线观看| 久久久久久亚洲精品| 欧美激情乱人伦|