![十三天學(xué)會(huì)java第十三天-網(wǎng)絡(luò)編程與設(shè)計(jì)模式_第1頁(yè)](http://file4.renrendoc.com/view/f226d85ab45fc1a2f163c3f66e2ee73d/f226d85ab45fc1a2f163c3f66e2ee73d1.gif)
![十三天學(xué)會(huì)java第十三天-網(wǎng)絡(luò)編程與設(shè)計(jì)模式_第2頁(yè)](http://file4.renrendoc.com/view/f226d85ab45fc1a2f163c3f66e2ee73d/f226d85ab45fc1a2f163c3f66e2ee73d2.gif)
![十三天學(xué)會(huì)java第十三天-網(wǎng)絡(luò)編程與設(shè)計(jì)模式_第3頁(yè)](http://file4.renrendoc.com/view/f226d85ab45fc1a2f163c3f66e2ee73d/f226d85ab45fc1a2f163c3f66e2ee73d3.gif)
![十三天學(xué)會(huì)java第十三天-網(wǎng)絡(luò)編程與設(shè)計(jì)模式_第4頁(yè)](http://file4.renrendoc.com/view/f226d85ab45fc1a2f163c3f66e2ee73d/f226d85ab45fc1a2f163c3f66e2ee73d4.gif)
![十三天學(xué)會(huì)java第十三天-網(wǎng)絡(luò)編程與設(shè)計(jì)模式_第5頁(yè)](http://file4.renrendoc.com/view/f226d85ab45fc1a2f163c3f66e2ee73d/f226d85ab45fc1a2f163c3f66e2ee73d5.gif)
版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
十三天學(xué)會(huì)java第十三天-網(wǎng)絡(luò)編程與設(shè)計(jì)模式分類:
十三天java2013-05-1823:33
53人閱讀
評(píng)論(0)
\o"收藏"收藏
\o"舉報(bào)"舉報(bào)行業(yè)數(shù)據(jù)服務(wù)器Java目錄\o"系統(tǒng)根據(jù)文章中H1到H6標(biāo)簽自動(dòng)生成文章目錄"(?)\o"展開"[+]聲明:此java系列筆記編輯整理于魔樂網(wǎng),原網(wǎng)頁(yè)有視頻同步(如果還有的話)./3.1、網(wǎng)絡(luò)編程(了解)
網(wǎng)絡(luò)編程指的就是通過(guò)網(wǎng)絡(luò)進(jìn)行程序數(shù)據(jù)操作,既然是網(wǎng)絡(luò)開發(fā),那么一定就分為用戶和服務(wù)兩端,而這兩個(gè)端的開發(fā)實(shí)際上就有以下的兩種不同的架構(gòu)(面試題:請(qǐng)解釋C/S和B/S的區(qū)別?):·
C/S(Client/Server):要開發(fā)兩套程序,一套是服務(wù)器端,另外一套是與之對(duì)應(yīng)的客戶端,但是這種程序在日后進(jìn)行維護(hù)的時(shí)候,是需要維護(hù)兩套程序,而且客戶端的程序更新也必須及時(shí),此類程序安全;·
B/S(Browser/Server):要開發(fā)一套程序,只開發(fā)服務(wù)器端的,客戶端使用瀏覽器進(jìn)行訪問(wèn),這種程序在日后進(jìn)行程序維護(hù)的時(shí)候只需要維護(hù)服務(wù)器端即可,客戶端不需要做任何的修改,此類程序使用公共端口,包括公共協(xié)議,所以安全性很差。
如果從網(wǎng)絡(luò)的開發(fā)而言,大的分類是以上的兩類,可是從現(xiàn)在的開發(fā)來(lái)講,更多的情況是針對(duì)于B/S程序進(jìn)行的開發(fā),或者可以這么理解:B/S程序的開發(fā)屬于網(wǎng)絡(luò)時(shí)代,而C/S程序的開發(fā)屬于單機(jī)時(shí)代。而對(duì)于WebService的開發(fā),實(shí)話而言,也屬于B/S結(jié)構(gòu)的程序(跨平臺(tái))。
而在日后學(xué)習(xí)Android開發(fā)的時(shí)候,如果要考慮安全性使用Socket,如果要考慮方便性,還是基于WEB的開發(fā)方便使用。而對(duì)于網(wǎng)絡(luò)的開發(fā)在Java中也分為兩種:TCP(傳輸控制協(xié)議,可靠的傳輸)、UDP(數(shù)據(jù)報(bào)協(xié)議),對(duì)于網(wǎng)絡(luò)開發(fā),本次只專注于TCP程序的實(shí)現(xiàn)。3.2、網(wǎng)絡(luò)程序的基本實(shí)現(xiàn)(了解)
如果要進(jìn)行網(wǎng)絡(luò)程序的開發(fā),那么首先應(yīng)該開發(fā)出的就是服務(wù)器端,本次的操作使用服務(wù)器端向客戶端輸出一個(gè)“HelloWorld.”的字符串信息,而如果要想完成服務(wù)器端的開發(fā),則需要包中的兩個(gè)類:
·
ServerSocket類:是一個(gè)封裝支持TCP協(xié)議的操作類,主要工作在服務(wù)器端,用于接收客戶端請(qǐng)求;
·
Socket類:也是一個(gè)封裝了TCP協(xié)議的操作類,每一個(gè)Socket對(duì)象都表示一個(gè)客戶端。
而現(xiàn)在必須觀察這兩個(gè)類之中的操作方法:
·
ServerSocket類的方法:No.方法名稱類型描述1publicServerSocket(intport)throwsIOException構(gòu)造開辟一個(gè)指定的端口監(jiān)聽,一般使用5000以上2publicSocketaccept()throwsIOException普通服務(wù)器端接收客戶端請(qǐng)求,通過(guò)Socket返回3publicvoidclose()throwsIOException普通關(guān)閉服務(wù)器端
·
Socket類的方法:No.方法名稱類型描述1publicSocket(Stringhost,intport)throwsUnknownHostException,IOException構(gòu)造指定要連接的主機(jī)(IP地址)和端口2publicOutputStreamgetOutputStream()throwsIOException普通取得指定客戶端的輸出對(duì)象,使用的時(shí)候肯定使用PrintStream裝飾操作3publicInputStreamgetInputStream()throwsIOException普通從指定的客戶端讀取數(shù)據(jù),使用Scanner操作范例:完成一個(gè)服務(wù)器端程序代碼package
demo;import
java.io.PrintStream;import
.ServerSocket;import
.Socket;public
class
HelloServer{
public
static
void
main(String[]args)
throws
Exception{
ServerSocketserver=
new
ServerSocket(9999);
//
在9999端口監(jiān)聽
System.out.println("服務(wù)開始啟動(dòng)...");
Socketclient=server.accept();
//
接收客戶端連接,進(jìn)入到阻塞狀態(tài)
PrintStreamout=
new
PrintStream(client.getOutputStream());
out.println("HelloWorld.");
//
向客戶端輸出
out.close();
//
輸出流的關(guān)閉
client.close();
//
關(guān)閉客戶端
server.close();
//
關(guān)閉服務(wù)器端
System.out.println("服務(wù)器已關(guān)閉...");
}}
現(xiàn)在服務(wù)器端已經(jīng)開發(fā)完成了,而現(xiàn)在的服務(wù)器端雖然是通過(guò)Java編寫的,但是使用的是TCP協(xié)議,所以可以利用系統(tǒng)命令的telnet進(jìn)行訪問(wèn)。
·
使用運(yùn)行方式輸入:telnet;
·
連接服務(wù)器:openip地址
端口,openlocalhost9999;
但是現(xiàn)在是利用了系統(tǒng)的工具完成的,那么在開發(fā)之中是不可能使用這工具,應(yīng)該自己去編寫客戶端。范例:編寫一個(gè)客戶端package
demo;import
.Socket;import
java.util.Scanner;public
class
HelloClient{
public
static
void
main(String[]args)
throws
Exception{
Socketclient=
new
Socket("localhost",9999);
Scannerscan=
new
Scanner(client.getInputStream());
scan.useDelimiter("\n");
if
(scan.hasNext()){
//
有數(shù)據(jù)
System.out.println("服務(wù)器的回應(yīng)數(shù)據(jù):"
+scan.next());
}
scan.close();
client.close();
}}
整個(gè)的操作就是一個(gè)輸出和輸入的過(guò)程,只是現(xiàn)在的輸出和輸入的來(lái)源在于網(wǎng)絡(luò),而不是像之前那樣是通過(guò)文件操作了。3.3、網(wǎng)絡(luò)開發(fā)的經(jīng)典模型
——
ECHO程序
這種開發(fā)模型的典型模式指的是客戶端要輸入信息,而后服務(wù)器端接收這端信息之后,前面增加一個(gè)“ECHO:”的信息再返回給客戶端,也就是說(shuō)現(xiàn)在的服務(wù)器端需要輸入和輸出數(shù)據(jù)。范例:編寫一個(gè)程序的基本模型package
demo;import
java.io.PrintStream;import
.ServerSocket;import
.Socket;import
java.util.Scanner;public
class
EchoServer{
public
static
void
main(String[]args)
throws
Exception{
ServerSocketserver=
new
ServerSocket(9999);
boolean
flag=
true;
System.out.println("服務(wù)器運(yùn)行...");
Socketclient=server.accept();
//
接收客戶端請(qǐng)求
Scanner
scan
=
new
Scanner(client.getInputStream());
PrintStreamout=
new
PrintStream(client.getOutputStream());
while
(flag){
if
(scan.hasNext()){
//
有內(nèi)容
Stringstr=scan.next();
if
("byebye".equalsIgnoreCase(str.trim())){
//
程序結(jié)束
out.println("ByeBye...");
flag=
false;
//
退出循環(huán)
}
out.println("ECHO:"
+str.trim());
//
回應(yīng)數(shù)據(jù)
}
}
System.out.println("服務(wù)器停止運(yùn)行...");
server.close();
}}
這個(gè)時(shí)候程序?qū)嶋H上是一種單線程的運(yùn)行狀態(tài),這樣的程序運(yùn)行起來(lái)只能夠?yàn)橐粋€(gè)用戶進(jìn)行服務(wù),所以如果希望一個(gè)服務(wù)器可以同時(shí)處理多個(gè)客戶的操作,那么就必須為其實(shí)現(xiàn)多線程的處理機(jī)制,讓每一個(gè)客戶端表示一個(gè)獨(dú)立的線程對(duì)象,每個(gè)線程對(duì)象有自己獨(dú)立的輸入輸出操作。范例:為服務(wù)器端增加多線程機(jī)制,使用匿名內(nèi)部類package
demo;import
java.io.IOException;import
java.io.PrintStream;import
.ServerSocket;import
.Socket;import
java.util.Scanner;public
class
EchoServer{
public
static
void
main(String[]args)
throws
Exception{
ServerSocketserver=
new
ServerSocket(9999);
boolean
flag=
true;
System.out.println("服務(wù)器運(yùn)行...");
while
(flag){
final
Socketclient=server.accept();
//
接收客戶端請(qǐng)求
new
Thread(new
Runnable(){
@Override
public
void
run(){
boolean
runFlag=
true;
try
{
Scanner
scan
=
new
Scanner(client.getInputStream());
PrintStreamout=
new
PrintStream(client.getOutputStream());
while
(runFlag){
if
(scan.hasNext()){
//
有內(nèi)容
Stringstr=scan.next();
if
("byebye".equalsIgnoreCase(str.trim())){
//
程序結(jié)束
out.println("ByeBye...");
runFlag=
false;
//
退出循環(huán)
}
out.println("ECHO:"
+str.trim());
//
回應(yīng)數(shù)據(jù)
}
}
}
catch
(IOExceptione){
e.printStackTrace();
}
try
{
client.close();
}
catch
(IOExceptione){
e.printStackTrace();
}
}
}).start();
}
System.out.println("服務(wù)器停止運(yùn)行...");
server.close();
}}
但是,在這個(gè)時(shí)候?qū)τ诰€程的控制也需要處理好,如果處理不好,可能就出現(xiàn)死鎖問(wèn)題了。4、總結(jié)
知道什么叫網(wǎng)絡(luò)編程就行了,暫時(shí)用不到。3、具體內(nèi)容
之前的所有內(nèi)容都在本處進(jìn)行總結(jié),而且對(duì)于之前的一些概念不清楚的東西(代碼會(huì)寫)那么都可以不用去看了,把本次程序弄會(huì)了,一切就都會(huì)了,后面也就都會(huì)了。3.1、程序分層(理解)
在一個(gè)完整的項(xiàng)目之中,對(duì)程序進(jìn)行合理的分層,可以讓開發(fā)變得更加的方便,也更加的具備層次感,每一層有每一層的開發(fā)人員,例如:可以簡(jiǎn)單的理解為美工
+
程序相分離。而實(shí)際上的分層操作,可以這樣參考:
如果按照含金量來(lái)講,首先把握住業(yè)務(wù)層是整個(gè)程序的實(shí)現(xiàn)關(guān)鍵,但是對(duì)于前臺(tái)顯示更加的重要。今天的主要任務(wù)是觀察業(yè)務(wù)層和數(shù)據(jù)層的開發(fā),而到了JavaWEB之后,才開始實(shí)現(xiàn)顯示層和控制層的開發(fā)。
在項(xiàng)目之中后臺(tái)的建立直接有著重要的地位,但是不同層之間最為重要的連接組成部分就是接口,所以整個(gè)代碼開發(fā)之中,對(duì)于后臺(tái)代碼就一定要有兩個(gè)組成接口(業(yè)務(wù)層接口,給以后的控制層使用、數(shù)據(jù)層接口,給以后的業(yè)務(wù)層使用)。
·
數(shù)據(jù)層(數(shù)據(jù)訪問(wèn)層,DataAccessObject):指的是執(zhí)行數(shù)據(jù)的具體操作,而現(xiàn)在的開發(fā)之中,大多數(shù)都是針對(duì)于數(shù)據(jù)庫(kù)的開發(fā),所以在數(shù)據(jù)層之中的主要任務(wù)是負(fù)責(zé)完成數(shù)據(jù)的CRUD,而在java之中,如果要想進(jìn)行數(shù)據(jù)的CRUD實(shí)現(xiàn),肯定使用java.sql.PreparedStatement接口;
·
業(yè)務(wù)層(業(yè)務(wù)對(duì)象,BusinessObject,BO,又或者將其稱為Service,服務(wù)層),服務(wù)層的主要目的是根據(jù)業(yè)務(wù)需求進(jìn)行數(shù)據(jù)層的操作,一個(gè)業(yè)務(wù)層要包含多個(gè)數(shù)據(jù)層的操作。
清楚了基本概念之后,那么新的問(wèn)題就該出現(xiàn)了,如何去區(qū)分業(yè)務(wù)層或者是數(shù)據(jù)層?下面以玉史先生吃飯為例,說(shuō)明一下。
如果說(shuō)現(xiàn)在某一個(gè)項(xiàng)目業(yè)務(wù)非常復(fù)雜,可能分為若干個(gè)子業(yè)務(wù),那么就還需要一個(gè)總的業(yè)務(wù)層操作。3.2、實(shí)例分析(重點(diǎn))
下面以emp數(shù)據(jù)表(empno、ename、job、hiredate、sal、comm,都是基本字段)為例分析一個(gè)操作,客戶要求可以實(shí)現(xiàn)如下的幾個(gè)功能:
·
【業(yè)務(wù)層】增加一個(gè)新雇員信息;
|-
〖數(shù)據(jù)層〗要根據(jù)增加的雇員編號(hào)查看此雇員是否存在;
|-
〖數(shù)據(jù)層〗如果雇員不存在則執(zhí)行插入操作,如果存在則不插入;
·
【業(yè)務(wù)層】修改一個(gè)雇員的信息;
|-
〖數(shù)據(jù)層〗直接傳入新的數(shù)據(jù)即可,如果沒有修改返回的更新行數(shù)是0;
·
【業(yè)務(wù)層】刪除一個(gè)雇員的信息;
|-
〖數(shù)據(jù)層〗直接傳入要?jiǎng)h除的雇員編號(hào)即可,如果沒有此雇員信息返回的是0;
·
【業(yè)務(wù)層】根據(jù)編號(hào)查詢一個(gè)雇員的信息;
|-
〖數(shù)據(jù)層〗返回一個(gè)雇員的完整信息;·
【業(yè)務(wù)層】取得全部雇員的信息,要求可以實(shí)現(xiàn)模糊查詢和分頁(yè)顯示,查詢結(jié)果除了返回?cái)?shù)據(jù)之外,還要求知道模糊或全部查詢時(shí)所返回的全部數(shù)據(jù)量:
|-
〖數(shù)據(jù)層〗模糊或查詢?nèi)繚M足條件的雇員數(shù)據(jù),多個(gè)數(shù)據(jù);
|-
〖數(shù)據(jù)層〗使用COUNT()進(jìn)行滿足條件的數(shù)據(jù)統(tǒng)計(jì)。
3.3、準(zhǔn)備階段(重點(diǎn))3.3.1
、VO類:負(fù)責(zé)數(shù)據(jù)的傳輸與包裝
但是現(xiàn)在有一個(gè)最為嚴(yán)重的問(wèn)題出現(xiàn)了,不同層之間(這些層除了數(shù)據(jù)層要操作SQL之外,那么其他層操作的數(shù)據(jù)都應(yīng)該是對(duì)象),所以應(yīng)該有一個(gè)負(fù)責(zé)傳輸?shù)臄?shù)據(jù)對(duì)象,這個(gè)對(duì)象可以稱為ValueObject(VO,POJO、TO、PO)。
但是,現(xiàn)在對(duì)于簡(jiǎn)單Java類的開發(fā)原則也發(fā)生了一些變化:
·
類名稱要和表名稱保持一致;
·
為了日后類的操作方便,所有的簡(jiǎn)單Java類必須實(shí)現(xiàn)java.io.Serializable接口;
·
類中不允許出現(xiàn)任何的基本數(shù)據(jù)類型,只能使用包裝類;
·
類之中的所有屬性都必須封裝,必須都編寫setter、getter;
·
類之中一定要提供有無(wú)參構(gòu)造方法。
在DAO的開發(fā)之中,所有的名稱都有嚴(yán)格規(guī)定,假設(shè)現(xiàn)在的項(xiàng)目的總包名稱為:cn.mldn.oracle,那么現(xiàn)在這個(gè)VO類的保存包名稱就應(yīng)該是cn.mldn.oracle.vo。范例:定義cn.mldn.oracle.vo.Emp類package
cn.mldn.oracle.vo;import
java.io.Serializable;import
java.util.Date;@SuppressWarnings("serial")public
class
Emp
implements
Serializable{
private
Integer
empno
;
private
String
ename
;
private
String
job
;
private
Date
hiredate
;
private
Double
sal
;
private
Double
comm
;
//setter、getter略,自己補(bǔ)充}3.3.2
、DatabaseConnection類:負(fù)責(zé)數(shù)據(jù)庫(kù)連接
既然現(xiàn)在要完成數(shù)據(jù)層的開發(fā),那么就一定需要數(shù)據(jù)庫(kù)的連接與關(guān)閉操作,可是如果將數(shù)據(jù)庫(kù)的連接和關(guān)閉都寫在每一個(gè)數(shù)據(jù)層之中,這樣代碼過(guò)于重復(fù),而且也不方便維護(hù),那么為了方便起見,現(xiàn)在定義一個(gè)DatabaseConnection的類,這個(gè)類專門負(fù)責(zé)取得和關(guān)閉數(shù)據(jù)庫(kù)連接。而這個(gè)類定義在cn.mldn.oracle.dbc包之中。范例:定義cn.mldn.oracle.dbc.DatabaseConnectionpackage
cn.mldn.oracle.dbc;import
java.sql.Connection;import
java.sql.DriverManager;import
java.sql.SQLException;/**
*
本類的主要功能是負(fù)責(zé)數(shù)據(jù)庫(kù)的連接與關(guān)閉的
*
@author
MLDN
*/public
class
DatabaseConnection{
private
static
final
String
DBDRIVER
=
"oracle.jdbc.driver.OracleDriver"
;
private
static
final
String
DBURL
=
"jdbc:oracle:thin:@localhost:1521:MLDN"
;
private
static
final
String
DBUSER
=
"scott"
;
private
static
final
String
PASSWORD
=
"tiger"
;
private
Connection
conn
=
null
;
//
保存連接對(duì)象
/**
*
構(gòu)造方法的主要目的是進(jìn)行數(shù)據(jù)庫(kù)連接,只要在程序之中實(shí)例化了DatabaseConnection對(duì)象
*
那么就表示要進(jìn)行數(shù)據(jù)庫(kù)的連接操作了,所以在構(gòu)造方法之中連接數(shù)據(jù)庫(kù)
*
在本構(gòu)造方法之中,如果出現(xiàn)了異常,將直接輸出異常信息,因?yàn)槿绻麛?shù)據(jù)庫(kù)連接都沒有了,根本就無(wú)法操作
*/
public
DatabaseConnection(){
try
{
Class.forName(DBDRIVER);
this.conn
=DriverManager.getConnection(DBURL,
DBUSER,
PASSWORD);
}
catch
(Exceptione){
e.printStackTrace();
}
}
/**
*
取得一個(gè)數(shù)據(jù)庫(kù)連接對(duì)象,這個(gè)對(duì)象在構(gòu)造方法中取得
*
@return
Connection接口對(duì)象
*/
public
ConnectiongetConnection(){
return
this.conn
;
}
/**
*
關(guān)閉連接,不管是否連接上,執(zhí)行此操作都不會(huì)出錯(cuò)
*/
public
void
close(){
if
(this.conn
!=
null){
//
取得了連接
try
{
//
關(guān)閉連接
this.conn.close();
}
catch
(SQLExceptione){
e.printStackTrace();
}
}
}}
如果在實(shí)際的工作之中,按照DAO最早提出的標(biāo)準(zhǔn),對(duì)于數(shù)據(jù)層的實(shí)現(xiàn)類還需要實(shí)現(xiàn)數(shù)據(jù)庫(kù)的移植操作。即:對(duì)于數(shù)據(jù)庫(kù)連接類應(yīng)該變?yōu)橐粋€(gè)專門負(fù)責(zé)連接的接口,就好象以下的形式一樣:public
interface
DatabaseConnection{
public
ConnectiongetConnection();
public
void
close();}
而后如果一個(gè)項(xiàng)目可能在Oracle或DB2下運(yùn)行,那么針對(duì)于這兩種數(shù)據(jù)庫(kù)分別定義一個(gè)接口實(shí)現(xiàn)類,以對(duì)應(yīng)兩個(gè)不同的數(shù)據(jù)庫(kù)連接。但是這種開發(fā)已經(jīng)和現(xiàn)在的模式有些出入了,而且特別的麻煩,所以在本次為了和日后的開發(fā)可以更好的聯(lián)系在一起,只是定義了一個(gè)類而已。3.4、開發(fā)數(shù)據(jù)層(重點(diǎn))3.4.1
、定義IEmpDAO接口:數(shù)據(jù)層開發(fā)標(biāo)準(zhǔn)
不同層之間的操作依靠的是接口,所以數(shù)據(jù)層的開發(fā)首先要定義出來(lái)的就是標(biāo)準(zhǔn)。那么既然是標(biāo)準(zhǔn)就需要定義的是一個(gè)接口,現(xiàn)在很明顯針對(duì)的是emp表,所以這個(gè)接口的名稱就應(yīng)該為“表名稱DAO”,即:EmpDAO,但是這里有一個(gè)問(wèn)題了,接口和類的命名要求是一致的,所以為了從名稱上區(qū)分出接口或者是類,則建議在接口名稱前增加一個(gè)字母“I”,表示Interface的含義,即:emp這張實(shí)體表的操作標(biāo)準(zhǔn)的接口名稱為:IEmpDAO,而且這個(gè)接口應(yīng)該保存在cn.mldn.oracle.dao包之中。
那么對(duì)于這個(gè)接口的開發(fā)主要是針對(duì)于數(shù)據(jù)的兩種操作(更新、查詢),所以從開發(fā)標(biāo)準(zhǔn)上對(duì)于命名也有著嚴(yán)格的要求,而且必須遵守,基本標(biāo)準(zhǔn)如下:
·
更新操作:以“doXxx()”的方式命名,例如:doCreate()、doUpdate()、doRemvoe();
·
查詢操作,因?yàn)椴樵儾僮鞣譃閮深悾?/p>
|-
數(shù)據(jù)查詢:以“findXxx()”或“findByXxx()”為主,例如:findAll()、findById()、findByJob();
|-
統(tǒng)計(jì)查詢:以“getXxx()”或“getByXxx()”為主,例如:getAllCount()、getByJobCount()。范例:編寫IEmpDAO接口的操作標(biāo)準(zhǔn)package
cn.mldn.oracle.dao;import
java.util.List;import
cn.mldn.oracle.vo.Emp;public
interface
IEmpDAO{
/**
*
執(zhí)行數(shù)據(jù)的增加操作
*
@param
vo
包含所要增加的數(shù)據(jù)的VO對(duì)象
*
@return
如果增加數(shù)據(jù)成功返回true,否則返回false
*
@throws
Exception
操作之中出現(xiàn)了異常,返回給被調(diào)用處執(zhí)行處理
*/
public
boolean
doCreate(Empvo)
throws
Exception;
/**
*
執(zhí)行數(shù)據(jù)的更新操作
*
@param
vo
包含了新數(shù)據(jù)的VO對(duì)象
*
@return
如果修改成功返回true,否則返回false
*
@throws
Exception
操作之中出現(xiàn)了異常,返回給被調(diào)用處執(zhí)行處理
*/
public
boolean
doUpdate(Empvo)
throws
Exception;
/**
*
刪除一個(gè)雇員的信息
*
@param
id
要?jiǎng)h除的雇員編號(hào)
*
@return
如果刪除成功返回true,否則返回false
*
@throws
Exception
操作之中出現(xiàn)了異常,返回給被調(diào)用處執(zhí)行處理
*/
public
boolean
doRemove(int
id)
throws
Exception;
/**
*
根據(jù)雇員編號(hào)查詢一個(gè)雇員的完整信息
*
@param
id
要查詢的雇員編號(hào)
*
@return
如果沒有指定的雇員編號(hào),返回值為null,<br>
*
如果有指定的雇員信息,則將所有的雇員信息包裝到Emp實(shí)例化對(duì)象之中返回。
*
@throws
Exception
操作之中出現(xiàn)了異常,返回給被調(diào)用處執(zhí)行處理
*/
public
EmpfindById(int
id)
throws
Exception;
/**
*
查詢?nèi)康墓蛦T信息
*
@return
多個(gè)雇員信息使用List返回,如果List集合的size()長(zhǎng)度為0,則表示沒有數(shù)據(jù)返回
*
@throws
Exception
操作之中出現(xiàn)了異常,返回給被調(diào)用處執(zhí)行處理
*/
public
List<Emp>findAll()
throws
Exception;
/**
*
分頁(yè)顯示所有雇員的信息,同時(shí)可以完成模糊查詢
*
@param
column
要模糊查詢的字段名稱
*
@param
keyWord
要模糊查詢的數(shù)據(jù),如果為空字符串(isEmpty()判斷為true,表示空字符串),則表示查詢?nèi)?/p>
*
@param
currentPage
當(dāng)前所在的頁(yè)
*
@param
lineSize
沒頁(yè)顯示的記錄長(zhǎng)度
*
@return
多個(gè)雇員信息使用List返回,如果List集合的size()長(zhǎng)度為0,則表示沒有數(shù)據(jù)返回
*
@throws
Exception
操作之中出現(xiàn)了異常,返回給被調(diào)用處執(zhí)行處理
*/
public
List<Emp>findAll(Stringcolumn,StringkeyWord,
int
currentPage,
int
lineSize)
throws
Exception;
/**
*
統(tǒng)計(jì)模糊查詢的數(shù)據(jù)結(jié)果,使用COUNT()函數(shù)進(jìn)行統(tǒng)計(jì)
*
@param
column
要模糊查詢的字段名稱
*
@param
keyWord
要模糊查詢的數(shù)據(jù),如果為空字符串(isEmpty()判斷為true,表示空字符串),則表示查詢?nèi)?/p>
*
@return
會(huì)根據(jù)數(shù)據(jù)量的多少返回?cái)?shù)據(jù)的長(zhǎng)度,如果沒有數(shù)據(jù)返回0
*
@throws
Exception
操作之中出現(xiàn)了異常,返回給被調(diào)用處執(zhí)行處理
*/
public
int
getAllCount(Stringcolumn,StringkeyWord)
throws
Exception;}
現(xiàn)在開發(fā)的標(biāo)準(zhǔn)只是滿足于程序需求的提出需要。3.4.2
、定義IEmpDAO接口的實(shí)現(xiàn)類
既然在接口中已經(jīng)定義了數(shù)據(jù)層的操作標(biāo)準(zhǔn),那么對(duì)于實(shí)現(xiàn)類只需要遵循數(shù)據(jù)層的CRUD操作即可,但是對(duì)于DAO接口的實(shí)現(xiàn)類需要有明確的定義,要求將其定義在:cn.mldn.oracle.dao.impl包之中。
范例:定義EmpDAOImpl子類
·
現(xiàn)在有如下一種的子類實(shí)現(xiàn)接口方式:
@Override
public
boolean
doCreate(Empvo)
throws
Exception{
DatabaseConnectiondbc=
new
DatabaseConnection();
Stringsql=
"INSERTINTOemp(empno,ename,job,hiredate,sal,comm)VALUES(?,?,?,?,?,?)";
PreparedStatementpstmt=dbc.getConnection().prepareStatement(sql);
pstmt.setInt(1,vo.getEmpno());
pstmt.setString(2,vo.getEname());
pstmt.setString(3,vo.getJob());
pstmt.setDate(4,
new
java.sql.Date(vo.getHiredate().getTime()));
pstmt.setDouble(5,vo.getSal());
pstmt.setDouble(6,vo.getComm());
if
(pstmt.executeUpdate()>0){
return
true
;
}
dbc.close();
return
false;
}
如果真的按照這種方式實(shí)現(xiàn)的程序,有兩個(gè)重要問(wèn)題:·
對(duì)于數(shù)據(jù)層之中給出的若干方法,由服務(wù)層調(diào)用,一個(gè)服務(wù)層要執(zhí)行N個(gè)數(shù)據(jù)層,那么每次執(zhí)行的時(shí)候打開一次關(guān)閉一次數(shù)據(jù)庫(kù)?·
按照異常的處理機(jī)制,如果現(xiàn)在執(zhí)行的過(guò)程之中出現(xiàn)了錯(cuò)誤,那么順著throws就結(jié)束調(diào)用了,數(shù)據(jù)庫(kù)就再也無(wú)法關(guān)閉了。
按照之前的分析,一個(gè)業(yè)務(wù)要進(jìn)行多個(gè)數(shù)據(jù)層操作,所以數(shù)據(jù)庫(kù)連接與關(guān)閉交給業(yè)務(wù)層做最合適,而數(shù)據(jù)層只需要有一個(gè)Connection對(duì)象就可以操作了,它不需要關(guān)心這個(gè)對(duì)象是從那里來(lái)的,怎么來(lái)的,只關(guān)心能不能使用。package
cn.mldn.oracle.dao.impl;import
java.sql.Connection;import
java.sql.PreparedStatement;import
java.sql.ResultSet;import
java.util.ArrayList;import
java.util.List;import
cn.mldn.oracle.dao.IEmpDAO;import
cn.mldn.oracle.vo.Emp;public
class
EmpDAOImpl
implements
IEmpDAO{
private
Connection
conn;
private
PreparedStatement
pstmt;
public
EmpDAOImpl(Connectionconn){
this.conn
=conn;
}
@Override
public
boolean
doCreate(Empvo)
throws
Exception{
Stringsql=
"INSERTINTOemp(empno,ename,job,hiredate,sal,comm)VALUES(?,?,?,?,?,?)";
this.pstmt
=
this.conn.prepareStatement(sql);
this.pstmt.setInt(1,vo.getEmpno());
this.pstmt.setString(2,vo.getEname());
this.pstmt.setString(3,vo.getJob());
this.pstmt.setDate(4,
new
java.sql.Date(vo.getHiredate().getTime()));
this.pstmt.setDouble(5,vo.getSal());
this.pstmt.setDouble(6,vo.getComm());
if
(this.pstmt.executeUpdate()>0){
return
true;
}
return
false;
}
@Override
public
boolean
doUpdate(Empvo)
throws
Exception{
Stringsql=
"UPDATEempSETename=?,job=?,hiredate=?,sal=?,comm=?WHEREempno=?";
this.pstmt
=
this.conn.prepareStatement(sql);
this.pstmt.setString(1,vo.getEname());
this.pstmt.setString(2,vo.getJob());
this.pstmt.setDate(3,
new
java.sql.Date(vo.getHiredate().getTime()));
this.pstmt.setDouble(4,vo.getSal());
this.pstmt.setDouble(5,vo.getComm());
this.pstmt.setInt(6,vo.getEmpno());
if
(this.pstmt.executeUpdate()>0){
return
true;
}
return
false;
}
@Override
public
boolean
doRemove(int
id)
throws
Exception{
Stringsql=
"DELETEFROMempWHEREempno=?";
this.pstmt
=
this.conn.prepareStatement(sql);
this.pstmt.setInt(1,id);
if
(this.pstmt.executeUpdate()>0){
return
true;
}
return
false;
}
@Override
public
EmpfindById(int
id)
throws
Exception{
Empemp=
null;
Stringsql=
"SELECTempno,ename,job,hiredate,sal,commFROMempWHEREempno=?";
this.pstmt
=
this.conn.prepareStatement(sql);
this.pstmt.setInt(1,id);
ResultSetrs=
this.pstmt.executeQuery();
if
(rs.next()){
emp=
new
Emp();
emp.setEmpno(rs.getInt(1));
emp.setEname(rs.getString(2));
emp.setJob(rs.getString(3));
emp.setHiredate(rs.getDate(4));
emp.setSal(rs.getDouble(5));
emp.setComm(rs.getDouble(6));
}
return
emp;
}
@Override
public
List<Emp>findAll()
throws
Exception{
List<Emp>all=
new
ArrayList<Emp>();
Stringsql=
"SELECTempno,ename,job,hiredate,sal,commFROMemp";
this.pstmt
=
this.conn.prepareStatement(sql);
ResultSetrs=
this.pstmt.executeQuery();
while
(rs.next()){
Empemp=
new
Emp();
emp.setEmpno(rs.getInt(1));
emp.setEname(rs.getString(2));
emp.setJob(rs.getString(3));
emp.setHiredate(rs.getDate(4));
emp.setSal(rs.getDouble(5));
emp.setComm(rs.getDouble(6));
all.add(emp);
}
return
all;
}
@Override
public
List<Emp>findAll(Stringcolumn,StringkeyWord,
int
currentPage,
int
lineSize)
throws
Exception{
List<Emp>all=
new
ArrayList<Emp>();
Stringsql=
"SELECT*FROM("
+
"SELECTempno,ename,job,hiredate,sal,comm,ROWNUMrnFROMempWHERE"
+column+
"LIKE?ANDROWNUM<=?)temp"
+
"WHEREtemp.rn>?";
this.pstmt
=
this.conn.prepareStatement(sql);
this.pstmt.setString(1,
"%"
+keyWord+
"%");
this.pstmt.setInt(2,currentPage*lineSize);
this.pstmt.setInt(3,(current1)*lineSize);
ResultSetrs=
this.pstmt.executeQuery();
while
(rs.next()){
Empemp=
new
Emp();
emp.setEmpno(rs.getInt(1));
emp.setEname(rs.getString(2));
emp.setJob(rs.getString(3));
emp.setHiredate(rs.getDate(4));
emp.setSal(rs.getDouble(5));
emp.setComm(rs.getDouble(6));
all.add(emp);
}
return
all;
}
@Override
public
int
getAllCount(Stringcolumn,StringkeyWord)
throws
Exception{
Stringsql=
"SELECTCOUNT(empno)FROMempWHERE"
+column+
"LIKE?";
this.pstmt
=
this.conn.prepareStatement(sql);
this.pstmt.setString(1,
"%"
+keyWord+
"%");
ResultSetrs=
this.pstmt.executeQuery();
if
(rs.next()){
return
rs.getInt(1);
}
return
0;
}}3.4.3
、定義DAO工廠類
由于不同層之間只能依靠接口取得對(duì)象,所以就一定需要定義工廠操作類,工廠類定義在cn.mldn.oracle.factory包之中,名稱為DAOFactory。范例:定義工廠類package
cn.mldn.oracle.factory;import
java.sql.Connection;import
cn.mldn.oracle.dao.IEmpDAO;import
cn.mldn.oracle.dao.impl.EmpDAOImpl;public
class
DAOFactory{
public
static
IEmpDAOgetIEmpDAOInstance(Connectionconn){
return
new
EmpDAOImpl(conn);
}}3.5、開發(fā)業(yè)務(wù)層(重點(diǎn))3.5.1
、開發(fā)業(yè)務(wù)層標(biāo)準(zhǔn)
業(yè)務(wù)層以后也是需要留給其他層進(jìn)行調(diào)用的,所以業(yè)務(wù)層定義的時(shí)候也需要首先定義出操作標(biāo)準(zhǔn),而這個(gè)標(biāo)準(zhǔn)也依然使用接口完成,對(duì)于業(yè)務(wù)層,接口命名要求:表名稱
+Service,例如:IEmpService,表示操作Emp表的業(yè)務(wù)。范例:在cn.mldn.oracle.service包中定義IEmpService接口package
cn.mldn.oracle.service;import
java.util.Map;import
cn.mldn.oracle.vo.Emp;public
interface
IEmpService{
/**
*
調(diào)用數(shù)據(jù)庫(kù)的增加操作,操作流程如下:<br>
*
<li>首先要使用IEmpDAO接口中的findById()方法,根據(jù)要增加的id查看指定的雇員信息是否存在;
*
<li>如果要增加的雇員信息不存在,則執(zhí)行IEmpDAO接口的doCreate()方法,并將結(jié)果返回;
*
@param
vo
包裝數(shù)據(jù)的對(duì)象
*
@return
如果增加成功,返回true,如果雇員編號(hào)存在或者是增加失敗,返回false
*
@throws
Exception
有異常交給被調(diào)用處處理
*/
public
boolean
insert(Empvo)
throws
Exception;
/**
*
執(zhí)行數(shù)據(jù)的更新操作,操作的時(shí)候直接調(diào)用IEmpDAO接口的doUpdate()方法,并將更新結(jié)果返回
*
@param
vo
包裝數(shù)據(jù)的對(duì)象
*
@return
如果修改成功,返回true,如果數(shù)據(jù)不存在或修改失敗,返回false
*
@throws
Exception
有異常交給被調(diào)用處處理
*/
public
boolean
update(Empvo)
throws
Exception;
/**
*
執(zhí)行數(shù)據(jù)的刪除操作,刪除操作的時(shí)候調(diào)用IEmpDAO接口的doRemove()方法
*
@param
id
要?jiǎng)h除雇員的id
*
@return
如果刪除成功,返回true,如果數(shù)據(jù)不存在或刪除失敗,則返回false
*
@throws
Exception
有異常交給被調(diào)用處處理
*/
public
boolean
delete(int
id)
throws
Exception;
/**
*
根據(jù)雇員的編號(hào)取得全部的信息
*
@param
id
雇員編號(hào)
*
@return
如果雇員存在則將數(shù)據(jù)包裝為Emp對(duì)象返回,如果數(shù)據(jù)不存在則返回null
*
@throws
Exception
有異常交給被調(diào)用處處理
*/
public
Empget(int
id)
throws
Exception;
/**
*
查詢?nèi)炕蛘呤悄:樵內(nèi)繑?shù)據(jù),查詢的同時(shí)可以返回滿足此查詢的數(shù)據(jù)量,在調(diào)用的時(shí)候需要執(zhí)行以下操作:<br>
*
<li>查詢?nèi)康墓蛦T信息:需要IEmpDAO接口的findAll()方法;
*
<li>查詢滿足條件的雇員數(shù)量:使用IEmpDAO接口的getAllCount()方法操作;
*
@param
column
模糊查詢的字段
*
@param
keyWord
模糊查詢的關(guān)鍵字
*
@param
currentPage
當(dāng)前所在頁(yè)
*
@param
lineSize
每頁(yè)顯示的數(shù)據(jù)長(zhǎng)度
*
@return
由于在進(jìn)行數(shù)據(jù)返回的時(shí)候,此方法要返回兩類數(shù)據(jù):List<Emp>、int,使用Map返回:<br>
*
<li>返回值1:key=allEmps,value=findAll();
*
<li>返回值2:key=empCount,value=getAllCount();
*
@throws
Exception
有異常交給被調(diào)用處處理
*/
public
Map<String,Object>list(Stringcolumn,StringkeyWord,
int
currentPage,
int
lineSize)
throws
Exception;}3.5.2
、定義業(yè)務(wù)層標(biāo)準(zhǔn)的實(shí)現(xiàn)類
如果現(xiàn)在要想實(shí)現(xiàn)業(yè)務(wù)層的標(biāo)準(zhǔn),必須有一個(gè)原則先把握?。阂粋€(gè)業(yè)務(wù)層的方法操作要調(diào)用多個(gè)數(shù)據(jù)層,同時(shí)每個(gè)業(yè)務(wù)要處理數(shù)據(jù)庫(kù)的打開和關(guān)閉。范例:定義標(biāo)準(zhǔn)實(shí)現(xiàn)類
——
cn.mldn.oracle.service.impl.EmpServiceImplpackage
cn.mldn.oracle.service.impl;import
java.sql.Connection;import
java.util.HashMap;import
java.util.Map;import
cn.mldn.oracle.dao.IEmpDAO;import
cn.mldn.oracle.dbc.DatabaseConnection;import
cn.mldn.oracle.factory.DAOFactory;import
cn.mldn.oracle.service.IEmpService;import
cn.mldn.oracle.vo.Emp;public
class
EmpServiceImpl
implements
IEmpService{
private
DatabaseConnection
dbc
=
new
DatabaseConnection();
@Override
public
boolean
insert(Empvo)
throws
Exception{
try
{
Connectionconn=
this.dbc.getConnection();
//
取得連接
IEmpDAOdao=DAOFactory.getIEmpDAOInstance(conn);
//
取得DAO接口對(duì)象
if
(dao.findById(vo.getEmpno())==
null){
//
沒有要查詢的雇員信息
return
dao.doCreate(vo);
//
返回DAO的結(jié)果
}
return
false;
//
數(shù)據(jù)存在,直接返回false
}
catch
(Exceptione){
throw
e;
}
finally
{
this.dbc.close();
}
}
@Override
public
boolean
update(Empvo)
throws
Exception{
try
{
return
DAOFactory.getIEmpDAOInstance(this.dbc.getConnection())
.doUpdate(vo);
}
catch
(Exceptione){
throw
e;
}
finally
{
this.dbc.close();
}
}
@Override
public
boolean
delete(int
id)
throws
Exception{
try
{
return
DAOFactory.getIEmpDAOInstance(this.dbc.getConnection())
.doRemove(id);
}
catch
(Exceptione){
throw
e;
}
finally
{
this.dbc.close();
}
}
@Override
public
Empget(int
id)
throws
Exception{
try
{
return
DAOFactory.getIEmpDAOInstance(this.dbc.getConnection())
.findById(id);
}
catch
(Exceptione){
throw
e;
}
finally
{
this.dbc.close();
}
}
@Override
public
Map<String,Object>list(Stringcolumn,StringkeyWord,
int
currentPage,
int
lineSize)
throws
Exception{
try
{
Map<String,Object>map=
new
HashMap<String,Object>();
map.put("allEmps",
DAOFactory.getIEmpDAOInstance(this.dbc.getConnection())
.findAll(column,keyWord,currentPage,lineSize));
map.put("empCount",
DAOFactory.getIEmpDAOInstance(this.dbc.getConnection())
.getAllCount(column,keyWord));
return
map;
}
catch
(Exceptione){
throw
e;
}
finally
{
this.dbc.close();
}
}}3.5.3
、定義Service工廠類
如果要取得IEmpService接口對(duì)象,一定也需要使用工廠類,避免耦合問(wèn)題。范例:定義cn.mldn.oracle.factory.ServiceFactory工廠類package
cn.mldn.oracle.factory;import
cn.mldn.oracle.service.IEmpService;import
cn.mldn.oracle.service.impl.EmpServiceImpl;public
class
ServiceFactory{
public
static
IEmpServicegetIEmpServiceInstance(){
return
new
EmpServiceImpl();
}}3.6、定義測(cè)試類
一切的程序完成之后,下面就需要編寫測(cè)試程序,對(duì)于測(cè)試程序現(xiàn)在有兩種方法完成:
·
方式一:可以直接編寫主方法,自己根據(jù)它的返回值結(jié)果進(jìn)行判斷是否成功;
·
方式二:利用JUNIT完成,這樣的做法標(biāo)準(zhǔn),而且也方便日后調(diào)試。
如果要使用JUNIT則就需要建立一個(gè)個(gè)的TestCase(測(cè)試用例),而且現(xiàn)在再進(jìn)行測(cè)試的時(shí)候,應(yīng)該首先選擇的是服務(wù)層接口,因?yàn)檫x擇不是針對(duì)于接口測(cè)試,而是針對(duì)于方法測(cè)試,方法就可以不用自己去編寫了。范例:編寫測(cè)試程序類package
cn.mldn.oracle.test;import
java.util.Date;import
java.util.Iterator;import
java.util.List;import
java.util.Map;import
junit.framework.TestCase;import
org.junit.Test;import
cn.mldn.oracle.factory.ServiceFactory;import
cn.mldn.oracle.vo.Emp;public
class
IEmpServiceTest{
@Test
public
void
testInsert(){
Empvo=
new
Emp();
vo.setEmpno(9988);
vo.setEname("張三");
vo.setJob("清潔工");
vo.setSal(300.0);
vo.setComm(200.0);
vo.setHiredate(new
Date());
try
{
TestCase.assertTrue(ServiceFactory.getIEmpServiceInstance().insert(
vo));
}
catch
(Exceptione){
e.printStackTrace();
}
}
@Test
public
void
testUpdate(){
Empvo=
new
Emp();
vo.setEmpno(8888);
vo.setEname("張三");
vo.setJob("清潔工");
vo.setSal(1000.0);
vo.setComm(600.0);
vo.setHiredate(new
Date());
try
{
TestCase.assertTrue(ServiceFactory.getIEmpServiceInstance().update(
vo));
}
catch
(Exceptione){
e.printStackTrace();
}
}
@Test
public
void
testDelete(){
try
{
TestCase.assertTrue(ServiceFactory.getIEmpServiceInstance()
.delete(8888));
}
catch
(Exceptione){
e.printStackTrace();
}
}
@Test
public
void
testGet(){
try
{
Empvo=ServiceFactory.getIEmpServiceInstance().get(7369);
TestCase.assertNotNull(vo);
System.out.println(vo.getEname());
}
catch
(Exceptione){
e.printStackTrace();
}
}
@Test
public
void
testList(){
try
{
Map<String,Object>map=ServiceFactory.getIEmpServiceInstance()
.list("ename",
"",1,5);
TestCase.assertNotNull(map);
System.out.println("總記錄數(shù):"
+map.get("empCount"));
@SuppressWarnings("unchecked")
List<Emp>all=(List<Emp>)map.get("allEmps");
Iterator<Emp>iter=all.iterator();
while
(iter.hasNext()){
Empemp=iter.next();
System.out.println(emp.getEname()+
","
+emp.getJob());
}
}
catch
(Exceptione){
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年度智能倉(cāng)儲(chǔ)卷簾門系統(tǒng)采購(gòu)及集成合同
- 2025年度區(qū)塊鏈技術(shù)應(yīng)用項(xiàng)目開發(fā)與許可合同
- 2025年休假村租賃協(xié)議模板
- 2025年建筑工程模板工程承包合同書
- 2025年信用卡債務(wù)履行協(xié)議
- 2025年金剛石膜工具項(xiàng)目立項(xiàng)申請(qǐng)報(bào)告模范
- 2025年血液系統(tǒng)用藥項(xiàng)目規(guī)劃申請(qǐng)報(bào)告模范
- 2025年街頭籃球項(xiàng)目規(guī)劃申請(qǐng)報(bào)告
- 2025年放射性藥品項(xiàng)目提案報(bào)告模式
- 2025年生活用橡膠制品:塑膠盒項(xiàng)目規(guī)劃申請(qǐng)報(bào)告范文
- 工業(yè)機(jī)器人編程語(yǔ)言:Epson RC+ 基本指令集教程
- 2024年同等學(xué)力申碩統(tǒng)考英語(yǔ)卷
- 六年級(jí)下冊(cè)音樂全冊(cè)教案湖南文藝出版社湘教版
- 2023.05.06-廣東省建筑施工安全生產(chǎn)隱患識(shí)別圖集(高處作業(yè)吊籃工程部分)
- 2024年上海高考數(shù)學(xué)真題試題(原卷版+含解析)
- JTG 3362-2018公路鋼筋混凝土及預(yù)應(yīng)力混凝土橋涵設(shè)計(jì)規(guī)范
- 電動(dòng)汽車用驅(qū)動(dòng)電機(jī)系統(tǒng)-編制說(shuō)明
- 江蘇卷2024年高三3月份模擬考試化學(xué)試題含解析
- 門診導(dǎo)診課件
- 2024年四川省成都市新都區(qū)中考英語(yǔ)一診試卷(含解析)
- 《樹立正確的“三觀”》班會(huì)課件
評(píng)論
0/150
提交評(píng)論