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

首頁 > 編程 > Java > 正文

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

2019-11-11 06:04:25
字體:
來源:轉載
供稿:網友

總結: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
欧美伊久线香蕉线新在线| 国产精品jvid在线观看蜜臀| 亚洲 日韩 国产第一| 国产精品露脸自拍| 日韩中文第一页| 色伦专区97中文字幕| 亚洲人成绝费网站色www| 91中文在线视频| 亚洲最新在线视频| 91av在线不卡| 国产精品狠色婷| 亚洲va男人天堂| 91在线观看免费高清完整版在线观看| 91精品免费久久久久久久久| 亚洲人成网在线播放| 国产成人a亚洲精品| 久久福利网址导航| 精品综合久久久久久97| 久久久91精品国产一区不卡| 国产精品伦子伦免费视频| 久久这里有精品视频| 国产精品成人一区| 国产精品成人国产乱一区| 国产69精品久久久| 91av视频在线| 狠狠爱在线视频一区| 亚洲在线一区二区| 精品成人av一区| 欧美俄罗斯性视频| 最近2019年中文视频免费在线观看| 国产97色在线| 国产丝袜一区视频在线观看| 久久亚洲综合国产精品99麻豆精品福利| 国产精品久久久久久久天堂| 日韩精品免费在线播放| 视频一区视频二区国产精品| 国产成人福利网站| 成人激情视频在线观看| 色悠久久久久综合先锋影音下载| 中文字幕亚洲二区| 国产成人精品a视频一区www| 国产精品视频网站| 丁香五六月婷婷久久激情| 久久免费成人精品视频| 夜夜狂射影院欧美极品| 欧美第一页在线| 欧美激情欧美激情在线五月| 亚洲人成亚洲人成在线观看| 狠狠色狠色综合曰曰| 日韩黄色在线免费观看| 欧美成人激情在线| 精品中文字幕视频| 欧美大奶子在线| 亚洲第一色在线| 国产乱肥老妇国产一区二| 欧美成人午夜激情在线| 亚洲毛片在线免费观看| 国产精品美女999| 欧美激情在线有限公司| 国产精品伦子伦免费视频| 日韩av最新在线观看| 色哟哟网站入口亚洲精品| 国产精品色视频| 日韩av在线网站| 狠狠躁夜夜躁人人爽超碰91| xxxx欧美18另类的高清| 日本精品久久久久影院| 国产精品久久久久久久久久久新郎| 精品久久久久久久大神国产| 中文字幕在线看视频国产欧美| 日本国产高清不卡| 日韩国产精品亚洲а∨天堂免| 国产亚洲人成网站在线观看| 久久久之久亚州精品露出| 国产精品激情自拍| 久久综合伊人77777蜜臀| 91精品视频在线播放| 欧美激情第一页xxx| 日韩欧美国产视频| 日韩欧美一区二区三区| 九九视频这里只有精品| 亚洲日韩欧美视频一区| 国产精品户外野外| 国产精品国产自产拍高清av水多| 国产日韩av在线| 欧美在线性视频| 国产91精品最新在线播放| 亚洲精品成人久久久| 国产精品高潮呻吟久久av无限| 国产精品嫩草视频| 亚洲三级黄色在线观看| 欧美日本精品在线| 国产亚洲欧美一区| 国a精品视频大全| 俺也去精品视频在线观看| 亚洲欧美日韩直播| 精品呦交小u女在线| 久久全球大尺度高清视频| 国产精品第三页| 亚洲欧美日韩一区二区三区在线| 欧美大尺度激情区在线播放| 国内精品久久久久久久| 亚洲欧洲一区二区三区在线观看| 久久中文字幕在线| 国产精品永久免费视频| 黄网站色欧美视频| 中文字幕亚洲综合久久| 日韩av电影中文字幕| 国产精品久久在线观看| 国产乱人伦真实精品视频| 久久综合网hezyo| 成人免费视频网址| 国产精品久久av| 亚洲美女www午夜| 国产成人精品一区二区三区| 韩国v欧美v日本v亚洲| 亚洲第一精品夜夜躁人人躁| 久久久国产精彩视频美女艺术照福利| 久久精品精品电影网| 国产69精品久久久| 这里只有视频精品| 亚洲精品视频久久| 亚洲va欧美va在线观看| 亚洲一区二区中文字幕| 欧美黑人国产人伦爽爽爽| 国产精品视频在线观看| 97国产在线观看| 欧美激情伊人电影| 亚洲第一av网站| 亚洲精品美女在线观看| 日韩精品在线私人| 大荫蒂欧美视频另类xxxx| 国产综合福利在线| 日韩av电影院| 日韩欧中文字幕| 国产一区二区三区在线观看网站| 一区二区中文字幕| 亚洲欧美日韩图片| 亚洲欧美日韩精品久久奇米色影视| 热re91久久精品国99热蜜臀| 国产亚洲成精品久久| 国产香蕉一区二区三区在线视频| 色婷婷综合久久久久中文字幕1| 91精品国产免费久久久久久| 中文欧美日本在线资源| 777国产偷窥盗摄精品视频| 久久免费国产精品1| 黄色成人av在线| 国产日韩在线看片| 久久这里有精品视频| 777精品视频| 国产精品普通话| 1769国内精品视频在线播放| 日韩中文字幕在线看| 日本久久久久久| 国产精品视频xxxx| 精品国产自在精品国产浪潮| 欧美国产亚洲精品久久久8v| 亚洲精品久久久久久久久| 激情久久av一区av二区av三区| 日韩欧美精品网站| 亚洲欧洲第一视频| 欧美性色19p| 久久久国产视频91|