package s2jsp.bysj.dao; //此類所在包的名稱
專注于為中小企業(yè)提供網(wǎng)站建設(shè)、做網(wǎng)站服務(wù),電腦端+手機(jī)端+微信端的三站合一,更高效的管理,為中小企業(yè)普洱免費(fèi)做網(wǎng)站提供優(yōu)質(zhì)的服務(wù)。我們立足成都,凝聚了一批互聯(lián)網(wǎng)行業(yè)人才,有力地推動(dòng)了成百上千家企業(yè)的穩(wěn)健成長(zhǎng),幫助中小企業(yè)通過(guò)網(wǎng)站建設(shè)實(shí)現(xiàn)規(guī)模擴(kuò)充和轉(zhuǎn)變。
import java.sql.Connection; //導(dǎo)入Connection類
import java.sql.PreparedStatement; //導(dǎo)入PreparedStatement類
import java.sql.ResultSet; //導(dǎo)入ResultSet類
import java.util.ArrayList; //導(dǎo)入ArrayList類
import java.util.List; //導(dǎo)入List類
import s2jsp.bysj.entity.Users; //導(dǎo)入U(xiǎn)sers實(shí)體類
public class UserDao extends BaseDao { //UserDao類繼承了BaseDao類
private Connection conn; //聲明私有變量:Connection對(duì)象
private PreparedStatement pstmt; //聲明私有變量:PreparedStatement對(duì)象
private ResultSet rs; //聲明私有變量:ResultSet數(shù)據(jù)集對(duì)象
/**
* 根據(jù)用戶名和密碼,查找相關(guān)用戶信息
* @return Users類的對(duì)象:用戶對(duì)象
*@userName 用戶名
*@password 用戶密碼
*/
public Users findUsers(String userName, String password) {
Users user = null; //聲明實(shí)體類Users對(duì)象
String sql = "select * from users where userName=? and password=? "; //定義sql變量,此變量用來(lái)代替執(zhí)行的SQL語(yǔ)句
try { //將會(huì)發(fā)生異常的代碼放在了try{}catch{}塊中
conn = this.getConn(); //初始化了Connection對(duì)象:conn,getConn()方法是繼承自BaseDao的方法
pstmt = conn.prepareStatement(sql); //初始化PreparedStatement對(duì)象:pstmt
pstmt.setString(1, userName); //為SQL語(yǔ)句中的參數(shù)1設(shè)置值
pstmt.setString(2, password); //為SQL語(yǔ)句中的參數(shù)2設(shè)置值
rs = pstmt.executeQuery(); //用PreparedStatement的對(duì)象的executeQuery()方法初始化ResultSet對(duì)象:rs
if (rs.next()) { //如果ResultSet的next()方法返回true,則說(shuō)明目標(biāo)數(shù)據(jù)庫(kù)中的下一行有數(shù)據(jù)
user = new Users(); //初始化Users實(shí)體類,此類準(zhǔn)備用來(lái)初始化其域
user.setUserID(rs.getInt("userID")); //用數(shù)據(jù)庫(kù)中的值初始化Users實(shí)體類中的UserID字段
user.setUserName(userName); //用數(shù)據(jù)庫(kù)中的值初始化Users實(shí)體類中的UserName字段
user.setPassword(password); //用數(shù)據(jù)庫(kù)中的值初始化Users實(shí)體類中的Password字段
user.setStatus(rs.getInt("status")); //用數(shù)據(jù)庫(kù)中的值初始化Users實(shí)體類中的Status字段
}
} catch (Exception e) { //catch內(nèi)使用了Exception異常根類的printStackTrace()方法:表示將錯(cuò)誤信息打印在堆棧上
e.printStackTrace();
} finally { //finally塊中的語(yǔ)句表示始終要執(zhí)行的語(yǔ)句,并且在try語(yǔ)句塊后執(zhí)行
this.closeAll(conn, pstmt, rs); //try語(yǔ)句塊中執(zhí)行完畢或發(fā)生異常則使用closeAll()關(guān)閉所有使用到的數(shù)據(jù)庫(kù)連接對(duì)象,此處省略this也可以,conn是Connection對(duì)象,pstmt是PreparedStatement對(duì)象,rs是ResultSet對(duì)象
}
return user; //此方法最后返回Users實(shí)體類的對(duì)象,注:如果方法定義有返回值則一定要加此關(guān)鍵字
}
/**
* 判斷數(shù)據(jù)庫(kù)中當(dāng)前用戶名是否存在
* @param userName 用戶名
* @return 存在返回true,否則返回false
*/
public boolean findUsers(String userName){ //此方法用來(lái)查找傳入的用戶是否存在,返回一個(gè)布爾類型的值,true表示存在,false表示不存在
String sql = "select * from users where userName=? "; //定義SQL語(yǔ)句并放入sql變量中,這樣的好處是簡(jiǎn)化了代碼的長(zhǎng)度和復(fù)用的便利
try {
conn = this.getConn(); //用BaseDao類的getConn()方法初始化Connection對(duì)象:conn
pstmt = conn.prepareStatement(sql); //用Connection對(duì)象的prepareStatement()方法初始化PreparedStatement對(duì)象:pstmt
pstmt.setString(1, userName); //設(shè)置SQL語(yǔ)句參數(shù)1的值:userName
rs = pstmt.executeQuery(); //使用PreparedStatement對(duì)象的executeQuery()方法初始化ResultSet對(duì)象:rs
if (rs.next()) { //如果數(shù)據(jù)庫(kù)中有記錄則返回true,此時(shí)方法停止
return true;
}
} catch (Exception e) {
e.printStackTrace(); //將錯(cuò)誤信息打印到控制臺(tái)
} finally {
this.closeAll(conn, pstmt, rs); //關(guān)閉所有使用到的數(shù)據(jù)庫(kù)連接對(duì)象,此處可省略this關(guān)鍵字
}
return false; //最后的返回值可以是任意布爾類型的值
}
/**
* 添加用戶信息
* @param userName
* @param password
* @return 操作數(shù)據(jù)庫(kù)影響行數(shù)
*/
public int insertUser(String userName, String password,int status) { //插入一個(gè)用戶的方法,此方法類的參數(shù)跟數(shù)據(jù)庫(kù)中強(qiáng)制不為空的列是一一對(duì)應(yīng)的
String sql = "insert into users values(?,?,?) "; //定義SQL語(yǔ)句
String[] params = new String[] { userName, password ,status+""}; //定義字符串?dāng)?shù)組用來(lái)存放傳入的參數(shù),因?yàn)閭魅氲膮?shù)可能不止一個(gè)所以定義一個(gè)字符串?dāng)?shù)組來(lái)存放,困了余下的代碼都差不多所以我簡(jiǎn)單寫(xiě)了
return this.executeSQL(sql, params);
}
/**
* 查找所有的注冊(cè)用戶信息
* @return 用戶列表
*/
public List selectAllUser(){
List list=new ArrayList(); //實(shí)例化一個(gè)ArrayList對(duì)象,因?yàn)锳rrayList是List對(duì)象的子類
String sql = "select * from users ";
try {
conn = this.getConn();
pstmt = conn.prepareStatement(sql);
rs = pstmt.executeQuery();
while(rs.next()) {
Users user = new Users();
user.setUserID(rs.getInt("userID"));
user.setUserName(rs.getString("userName"));
user.setPassword(rs.getString("password"));
user.setStatus(rs.getInt("status"));
list.add(user);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
this.closeAll(conn, pstmt, rs);
}
return list; //此方法返回一個(gè)List對(duì)象
}
/**
* 根據(jù)用戶ID,進(jìn)行刪除操作
* @param userID
* @return 執(zhí)行SQL語(yǔ)句所影響的數(shù)據(jù)庫(kù)行數(shù)
*/
public int deleteUserByID(String userID){
String sql="delete from users where userID = ? "; //?號(hào)表示占位符號(hào)此處要用一個(gè)變量表示
String[] param = new String[]{ userID };
return this.executeSQL(sql, param);
}
}
//PreaparedStatement和Statement比較而言,PreparedStatement更適合于做修改插入的操作,應(yīng)為此類是預(yù)編譯的類,他的執(zhí)行效率要高于Statement類。而普通的查詢則使用Statement就可以了。
//ResultSet是結(jié)果集的意思,他用來(lái)存放從數(shù)據(jù)庫(kù)中讀取到的所有數(shù)據(jù),他用next()方法來(lái)確定下一行是否還有數(shù)據(jù),用返回的布爾類型值類表示。使用ResultSet對(duì)象的getXX(index)方法獲取程序從數(shù)據(jù)庫(kù)中讀取到的值,index為參數(shù)位置,從1開(kāi)始,1對(duì)應(yīng)數(shù)據(jù)中第一個(gè)字段。
//Connection是連接的意思,他的PreparedStatement和createStatement分別用來(lái)初始化PreaparedStatement對(duì)象和Statement對(duì)象。為SQL語(yǔ)句中的參數(shù)賦值用PreparedStatement對(duì)象的setXX(index,值)方法,參數(shù)位置從1開(kāi)始遞增。
//List是一個(gè)接口,ArrayList是實(shí)現(xiàn)了List接口的類,也可以其為L(zhǎng)ist的子類,所以List lst=new ArrayList();是一種編譯時(shí)多態(tài)的表現(xiàn),是完全允許的。其返回的是ArrayList子類的對(duì)象。ArrayList一般用來(lái)對(duì)數(shù)據(jù)的遍歷查詢,而LinkedList則比較擅長(zhǎng)于增刪改,他們都是集合,在此處用來(lái)存放實(shí)體類的對(duì)象。
//try{}catch{}finally{}就不用我多說(shuō)了吧!用來(lái)捕捉容易發(fā)生異常的代碼段,一些拋出異常的類是要求強(qiáng)制捕捉的,如果不捕捉編輯器會(huì)報(bào)告一個(gè)錯(cuò)誤。finally{}塊中的代碼是無(wú)論代碼執(zhí)行正確與否則都會(huì)執(zhí)行,此處用來(lái)對(duì)數(shù)據(jù)庫(kù)連接對(duì)象執(zhí)行關(guān)閉操作。
//其實(shí)我也是一個(gè)初學(xué)者,說(shuō)了這么多也許還有很多沒(méi)說(shuō)到的地方,當(dāng)然這段代碼如果要解釋完全是要牽扯到很多Java知識(shí),應(yīng)為篇幅和個(gè)人精力和知識(shí)量有限,先說(shuō)到這兒了,各位也請(qǐng)多多包涵,多多指正吧!
package org.dao;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.Date;
import org.dbc.DBManageer;
import org.dbc.DBUtil;
import org.vo.CardInfo;
public class CardInfoDao {
public void testResultSetMetaData() {
String sql = "select * from cardinfo";
Connection con = new DBUtil().getConnection();
PreparedStatement ps = null;
ResultSetMetaData rsmd = null;
ResultSet rs = null;
try {
ps = con.prepareStatement(sql);
rs = ps.executeQuery();
rsmd = rs.getMetaData();
for (int i = 1; i rsmd.getColumnCount(); i++) {
System.out.print(" 數(shù)據(jù)類型名:" + rsmd.getColumnClassName(i));
System.out.print(" 別名:" + rsmd.getColumnLabel(i));
System.out.print(" 列名:" + rsmd.getColumnName(i));
System.out.print(" 數(shù)據(jù)類型:" + rsmd.getColumnTypeName(i));
System.out.println(" 數(shù)據(jù)類型:" + rsmd.getColumnType(i));
}
while (rs.next()) {
// 通過(guò)反射可以對(duì)VO對(duì)象(CardInfo)自動(dòng)賦值
// for(...)
// CardInfo ci=new CardInfo();
// ci.setId(rs.getInt(columnIndex))
/*
* CardInfo ca = new CardInfo(); Class cc = ca.getClass();
*/
/*Class? c = Class.forName("org.vo.CardInfo");
CardInfo ca = (CardInfo) c.newInstance();
ca.setCardId(rs.getString("cardId"));
ca.setCustomerName(rs.getString("customerName"));
ca.setCurrentMoney(rs.getFloat("currentMoney"));
ca.setOpenDate(rs.getDate("openDate"));
System.out.println(ca);//ok */
//加載一個(gè)CardInfo類
Class c = Class.forName("org.vo.CardInfo");
Object o = c.newInstance(); //獲得它的一個(gè)實(shí)例
//定義String類的對(duì)象數(shù)組
Class[] params = new Class[] { String.class};
//定義float類的對(duì)象數(shù)組
Class[] floatparams = new Class[] { float.class};
//定義Date(util)類的對(duì)象數(shù)組
Class[] dateparams = new Class[] { Date.class};
//獲得setCardId方法
Method me = c.getMethod("setCardId", params);
//實(shí)例方法的參數(shù)
Object []ostr = new Object[]{rs.getString("cardId")};
//如果底層方法是靜態(tài)的,那么可以忽略指定的 obj 參數(shù)。該參數(shù)可以為 null。
//如果底層方法所需的形參數(shù)為 0,則所提供的 args 數(shù)組長(zhǎng)度可以為 0 或 null。
//o 調(diào)用方法的對(duì)象 ostr 方法調(diào)用的參數(shù)
me.invoke(o, ostr);
//獲得setCustomerName方法
Method name = c.getMethod("setCustomerName", params);
Object []cusname = new Object[]{rs.getString("customerName")};
name.invoke(o,cusname);
//獲得setCurrentMoney方法
Method money = c.getMethod("setCurrentMoney", floatparams);
Object []cusmoney = new Object[]{rs.getFloat("currentMoney")};
money.invoke(o,cusmoney);
//獲得setOpenDate方法
Method date = c.getMethod("setOpenDate",dateparams);
Object []openDate = new Object[]{rs.getDate("openDate")};
date.invoke(o, openDate);
//打印
System.out.println(o);
}
} catch (SQLException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
}catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
public void showResultSet() {
String sql = "select * from cardinfo";
Connection con = new DBManageer().getConnection();
PreparedStatement ps = null;
try {
ps = con.prepareStatement(sql, ResultSet.TYPE_SCROLL_SENSITIVE,
ResultSet.CONCUR_UPDATABLE);
ResultSet rs = ps.executeQuery();
System.out.println("---依次讀取------");
while (rs.next()) {
CardInfo ca = new CardInfo();
ca.setCardId(rs.getString("cardId"));
ca.setCustomerName(rs.getString("customerName"));
ca.setCurrentMoney(rs.getFloat("currentMoney"));
ca.setOpenDate(rs.getDate("openDate"));
System.out.println(ca);
}
System.out.println("---倒讀------");
while (rs.previous()) {
CardInfo ca = new CardInfo();
ca.setCardId(rs.getString("cardId"));
ca.setCustomerName(rs.getString("customerName"));
ca.setCurrentMoney(rs.getFloat("currentMoney"));
ca.setOpenDate(rs.getDate("openDate"));
System.out.println(ca);
}
rs.absolute(3);// 定位倒第幾行
rs.updateString("customerName", "star");
// rs.updateRow();
rs.beforeFirst();
while (rs.next()) {
CardInfo ca = new CardInfo();
ca.setCardId(rs.getString("cardId"));
ca.setCustomerName(rs.getString("customerName"));
ca.setCurrentMoney(rs.getFloat("currentMoney"));
ca.setOpenDate(rs.getDate("openDate"));
System.out.println(ca);
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
①dao到底是一個(gè)類還是一個(gè)接口?我看有的程序?qū)懗深愑械膶?xiě)成接口,到底哪個(gè)好?
答:dao通常是設(shè)計(jì)模式里面的一個(gè)名詞,在MVC模式里充當(dāng)?shù)氖菙?shù)據(jù)持久層,也稱為模型層(M)。所用持術(shù)很多,具體可以找一些設(shè)計(jì)模式的資料查看,目前市場(chǎng)上最流行的M層的兩個(gè)技術(shù)是ibatis、hibernate框架。要區(qū)分類和接口很簡(jiǎn),直接看類名前面的關(guān)鍵字“class”是一個(gè)類,“interface”是一個(gè)接口。到底哪個(gè)好就要看項(xiàng)目的設(shè)計(jì)了,一般大型的項(xiàng)目都用接口,接口方便括展。
②這是書(shū)上的一段代碼,我想知道怎么只有setter沒(méi)有g(shù)etter?
答:如果使用spring管理been,set方法是spring依賴注入所必需的方法,setter用于設(shè)置值,getter用于取值。
③return的返回值如果是注釋的方法會(huì)怎樣?二者有什么區(qū)別?
答:無(wú)意義代碼。無(wú)需糾結(jié)。如果非要說(shuō)會(huì)怎么樣,按照代碼邏輯,會(huì)返回“0”。區(qū)別在于,注釋那句返回“0”,下面那句執(zhí)行查詢sql返回查詢結(jié)果。
④還是return返回值:new Object[]{userName,password}里的大括號(hào)是什么?以前沒(méi)見(jiàn)過(guò)這么寫(xiě)代碼,請(qǐng)大神解釋!
答:Object[]是一個(gè)Object類型的一維數(shù)組,大括號(hào)里面是給數(shù)組賦的兩個(gè)初始值,object[0]=userName,object[1]=password。如果不清楚可以看看數(shù)組的語(yǔ)法結(jié)構(gòu)。
希望可以幫到你。
你好,dao層統(tǒng)一寫(xiě),具體的業(yè)務(wù)寫(xiě)在service層中。因?yàn)槟氵€可能有判斷登錄,注冊(cè),他們的實(shí)現(xiàn)是不一樣的。下面給出一個(gè)dao的例子:
package org.fit.dao;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.fit.ex.SysException;
public class Dao {
private static final String DRIVER=
"com.mysql.jdbc.Driver";
private static final String URL=
"jdbc:mysql://localhost:3306/cateweb";
private static final String USER="root";
private static final String PASSWORD="0";
public Dao() throws SysException{
try {
Class.forName(DRIVER);
} catch (ClassNotFoundException e) {
e.printStackTrace();
throw new SysException("驅(qū)動(dòng)沒(méi)有找到!") ;
}
}
private Connection conn;
private PreparedStatement pt;
private ResultSet rs;
public ResultSet query(String sql,Object... paramValues)
throws SQLException{
try {
conn=DriverManager.getConnection(URL,USER,PASSWORD);
pt=conn.prepareStatement(sql);
if(paramValues!=null){
for(int i=0;iparamValues.length;i++){
pt.setObject(i+1, paramValues[i]);
}
}
rs=pt.executeQuery();
return rs;
} catch (SQLException e) {
e.printStackTrace();
this.close();
throw e;
}
}
public int update(String sql,Object... paramValues)
throws SQLException{
try{
conn=DriverManager.getConnection(URL,USER,PASSWORD);
pt=conn.prepareStatement(sql);
if(paramValues!=null){
for(int i=0;iparamValues.length;i++){
pt.setObject(i+1, paramValues[i]);
}
}
return pt.executeUpdate();
}finally{
this.close();
}
}
public void close(){
try {
if(rs!=null){
rs.close();
}
} catch (Exception e) {}
rs=null;
try {
if(pt!=null){
pt.close();
}
} catch (Exception e) {}
pt=null;
try {
if(conn!=null){
if(!conn.isClosed())conn.close();
}
} catch (Exception e) {}
conn=null;
}
}
DAO類都是進(jìn)行數(shù)據(jù)操作的類,
是對(duì)于數(shù)據(jù)庫(kù)中的數(shù)據(jù)做增刪改查等操作的代碼。
DAO(DataAccessObject)數(shù)據(jù)訪問(wèn)對(duì)象是一個(gè)面向?qū)ο蟮臄?shù)據(jù)庫(kù)接口,它顯露了MicrosoftJet數(shù)據(jù)庫(kù)引擎(由MicrosoftAccess所使用),并允許VisualBasic開(kāi)發(fā)者通過(guò)ODBC像直接連接到其他數(shù)據(jù)庫(kù)一樣,直接連接到Access表。DAO最適用于單系統(tǒng)應(yīng)用程序或小范圍本地分布使用。
DAO層一般有接口和該接口的實(shí)現(xiàn)類,接口用于規(guī)范實(shí)現(xiàn)類,實(shí)現(xiàn)類一般用于用于操作數(shù)據(jù)庫(kù)!一般操作修改,添加,刪除數(shù)據(jù)庫(kù)操作的步驟很相似,就寫(xiě)了一個(gè)公共類DAO類,修改,添加,刪除數(shù)據(jù)庫(kù)操作時(shí)直接調(diào)用公共類DAO類。
擴(kuò)展資料:
DAO(DataAccessObject)是一個(gè)數(shù)據(jù)訪問(wèn)接口,數(shù)據(jù)訪問(wèn):顧名思義就是與數(shù)據(jù)庫(kù)打交道。夾在業(yè)務(wù)邏輯與數(shù)據(jù)庫(kù)資源中間。
在核心J2EE模式中是這樣介紹DAO模式的:為了建立一個(gè)健壯的J2EE應(yīng)用,應(yīng)該將所有對(duì)數(shù)據(jù)源的訪問(wèn)操作抽象封裝在一個(gè)公共API中。用程序設(shè)計(jì)的語(yǔ)言來(lái)說(shuō),就是建立一個(gè)接口,接口中定義了此應(yīng)用程序中將會(huì)用到的所有事務(wù)方法。在這個(gè)應(yīng)用程序中,當(dāng)需要和數(shù)據(jù)源進(jìn)行交互的時(shí)候則使用這個(gè)接口,并且編寫(xiě)一個(gè)單獨(dú)的類來(lái)實(shí)現(xiàn)這個(gè)接口在邏輯上對(duì)應(yīng)這個(gè)特定的數(shù)據(jù)存儲(chǔ)。
訪問(wèn)對(duì)象
DAO(數(shù)據(jù)訪問(wèn)對(duì)象)是一種應(yīng)用程序編程接口(API),存在于微軟的VisualBasic中,它允許程序員請(qǐng)求對(duì)微軟的Access數(shù)據(jù)庫(kù)的訪問(wèn)。DAO是微軟的第一個(gè)面向?qū)ο蟮臄?shù)據(jù)庫(kù)接口。DAO對(duì)象封閉了Access的Jet函數(shù)。通過(guò)Jet函數(shù),它還可以訪問(wèn)其他的結(jié)構(gòu)化查詢語(yǔ)言(SQL)數(shù)據(jù)庫(kù)。
參考資料:百度百科-dao