通過(guò)代理類(lèi)實(shí)現(xiàn)java連接數(shù)據(jù)庫(kù)(使用dao層操作數(shù)據(jù))實(shí)例分享
首先,我們?cè)谝粋€(gè)java文件中定義要存儲(chǔ)的結(jié)構(gòu)類(lèi)型:
import java.util.Date ;
/**
*
* @author Nero
*/
public class Emp {
private int empno ;
private String ename ;
private String job ;
private Date hiredate ;
private float sal ;
public void setEmpno(int empno){
this.empno = empno ;
}
public void setEname(String ename){
this.ename = ename ;
}
public void setJob(String job){
this.job = job ;
}
public void setHiredate(Date hiredate){
this.hiredate = hiredate ;
}
public void setSal(float sal){
this.sal = sal ;
}
public int getEmpno(){
return this.empno ;
}
public String getEname(){
return this.ename ;
}
public String getJob(){
return this.job ;
}
public Date getHiredate(){
return this.hiredate ;
}
public float getSal(){
return this.sal ;
}
}
下面我們定義一個(gè)數(shù)據(jù)庫(kù)連接類(lèi),負(fù)責(zé)向數(shù)據(jù)庫(kù)發(fā)起連接。java連接數(shù)據(jù)庫(kù)需要驅(qū)動(dòng)包,我們可以自行下載,測(cè)試的時(shí)候我使用的是mysql-connector-java-5.0.5-bin.jar。在運(yùn)行程序的時(shí)候Eclipse會(huì)提示需要加載的數(shù)據(jù)庫(kù)驅(qū)動(dòng)包,一些是類(lèi)似于"org.gjt.mm.mysql.Driver" 之類(lèi)的標(biāo)準(zhǔn)包,一般來(lái)說(shuō)我們選擇工作目錄里的驅(qū)動(dòng)包就可以了。
import java.sql.Connection ;
import java.sql.DriverManager ;
/**
*
* @author Nero
*/
public class DatabaseConnection {
private static final String DBDRIVER = "org.gjt.mm.mysql.Driver" ;
private static final String DBURL = "jdbc:mysql://localhost:3306/mldn" ;
private static final String DBUSER = "root" ;
private static final String DBPASSWORD = "root" ;
private Connection conn ;
public DatabaseConnection() throws Exception {
Class.forName(DBDRIVER) ;
this.conn = DriverManager.getConnection(DBURL,DBUSER,DBPASSWORD) ;
}
public Connection getConnection(){
return this.conn ;
}
public void close() throws Exception {
if(this.conn != null){
try{
this.conn.close() ;
}catch(Exception e){
throw e ;
}
}
}
}
接下來(lái)我們定義一個(gè)接口,這個(gè)接口能夠幫助我們輕松地實(shí)現(xiàn)代理方法。接口內(nèi)的方法只有三個(gè):插入、查找全部和通過(guò)ID查找。
import java.util.* ;
/**
*
* @author Nero
*/
public interface IEmpDAO {
public boolean doCreate(Emp emp) throws Exception ;
public List<Emp> findAll(String keyWord) throws Exception ;
public Emp findById(int empno) throws Exception ;
}
然后呢,我們繼承這個(gè)接口,實(shí)現(xiàn)具體數(shù)據(jù)庫(kù)的操作類(lèi),都是一些很基本的數(shù)據(jù)庫(kù)操作,沒(méi)啥好說(shuō)的。主要要注意的是構(gòu)造函數(shù)那里,參數(shù)使用Connection對(duì)象,后面使用這個(gè)類(lèi)的時(shí)候要傳入前面定義的數(shù)據(jù)庫(kù)連接類(lèi)DatabaseConnection中的函數(shù)getConnection()返回的Connection對(duì)象。
import java.sql.* ;
/**
*
* @author Nero
*/
public class EmpDAOImpl implements IEmpDAO{
private Connection conn = null ;
private PreparedStatement pstmt = null ;
public EmpDAOImpl(Connection conn)
{
this.conn = conn;
}
public boolean doCreate(Emp emp) throws Exception{
boolean flag = false;
String sql = "INSERT INTO emp(empno,ename,job,hiredate,sal) VALUES(?,?,?,?,?)";
this.pstmt = this.conn.prepareStatement(sql);
this.pstmt.setInt(1, emp.getEmpno());
this.pstmt.setString(2,emp.getEname()) ;
this.pstmt.setString(3,emp.getJob()) ;
this.pstmt.setDate(4,new java.sql.Date(emp.getHiredate().getTime())) ;
this.pstmt.setFloat(5,emp.getSal()) ;
if(this.pstmt.executeUpdate() > 0)
{
flag = true;
}
this.pstmt.close();
return flag;
}
public List<Emp> findAll(String keyWord) throws Exception{
List<Emp> all = new ArrayList<Emp>();
String sql = "SELECT empno,ename,job,hiredate,sal FROM emp WHERE ename LIKE ? OR job LIKE ?";
this.pstmt = this.conn.prepareStatement(sql);
this.pstmt.setString(1,"%"+keyWord+"%"); //轉(zhuǎn)義字符
this.pstmt.setString(2,"%"+keyWord+"%");
ResultSet rs = this.pstmt.executeQuery(sql);
Emp emp = null;
while(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.getFloat(5)) ;
all.add(emp);
}
this.pstmt.close();
return all;
}
public Emp findById(int empno) throws Exception{
Emp emp = null ;
String sql = "SELECT empno,ename,job,hiredate,sal FROM emp WHERE empno=?" ;
this.pstmt = this.conn.prepareStatement(sql) ;
this.pstmt.setInt(1,empno) ;
ResultSet rs = 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.getFloat(5)) ;
}
this.pstmt.close() ;
return emp ;
}
}
下面我們看看代理類(lèi)的實(shí)現(xiàn),個(gè)人覺(jué)得到這里就比較有意思了。在這個(gè)類(lèi)里面,聲明了一個(gè)數(shù)據(jù)庫(kù)連接類(lèi)DatabaseConnection的對(duì)象,一個(gè)數(shù)據(jù)庫(kù)應(yīng)用類(lèi)EmpDAOImpl對(duì)象,用DatabaseConnection對(duì)象初始化EmpDAOImpl對(duì)象,然后在代理類(lèi)的每個(gè)函數(shù)中都使用EmpDAOImpl對(duì)象去調(diào)用從同一接口繼承而來(lái)的方法,這樣即對(duì)具體實(shí)現(xiàn)方法進(jìn)行了一定程度的隱藏。
import java.sql.* ;
/**
*
* @author Nero
*/
public class EmpDAOProxy implements IEmpDAO{
private DatabaseConnection dbc = null ;
private EmpDAOImpl dao = null ;
public EmpDAOProxy() throws Exception{
this.dbc = new DatabaseConnection();
this.dao = new EmpDAOImpl(this.dbc.getConnection());
}
public boolean doCreate(Emp emp) throws Exception{
boolean flag = false;
try{
if(this.dao.findById(emp.getEmpno()) == null)
{
flag = this.dao.doCreate(emp);
}
}catch(Exception e)
{
throw e;
}finally{
this.dbc.close();
}
return flag;
}
public List<Emp> findAll(String keyWord) throws Exception{
List<Emp> all = null ;
try{
all = this.dao.findAll(keyWord) ;
}catch(Exception e){
throw e ;
}finally{
this.dbc.close() ;
}
return all ;
}
public Emp findById(int empno) throws Exception{
Emp emp = null ;
try{
emp = this.dao.findById(empno) ;
}catch(Exception e){
throw e ;
}finally{
this.dbc.close() ;
}
return emp ;
}
}
這還不是全部,我們可以再加一個(gè)工廠類(lèi)來(lái)實(shí)現(xiàn)工廠模式:
/**
*
* @author Nero
*/
public class DAOFactory {
public static IEmpDAO getIEmpDAOInstance() throws Exception{
return new EmpDAOProxy() ;
}
}
這個(gè)工廠類(lèi)有什么用呢?最后我們?cè)谥黝?lèi)文件中進(jìn)行調(diào)用,可以看看工廠類(lèi)有什么作用:
/**
*
* @author Nero
*/
public class TestDAOInsert {
public static void main(String args[]) throws Exception{
Emp emp = null ;
for(int x=0;x<5;x++){
emp = new Emp() ;
emp.setEmpno(1000 + x) ;
emp.setEname("中文顯示測(cè)試 - " + x) ;
emp.setJob("程序員 - " + x) ;
emp.setHiredate(new java.util.Date()) ;
emp.setSal(500 * x) ;
DAOFactory.getIEmpDAOInstance().doCreate(emp) ;
}
}
}
可見(jiàn)具體的實(shí)現(xiàn)方法隱藏得比較好,通過(guò)工廠類(lèi)調(diào)用get方法獲取代理類(lèi),代理類(lèi)調(diào)用特定方法,然后由代理類(lèi)內(nèi)的具體操作對(duì)象去調(diào)用具體的操作方法。
其實(shí)這些東西看起來(lái)會(huì)覺(jué)得很簡(jiǎn)單,但是自己設(shè)計(jì)的時(shí)候往往會(huì)忘記。主要是因?yàn)橛玫貌欢喟?,一開(kāi)始總是要強(qiáng)迫自己想起來(lái)去做,然后慢慢地才能變成一種習(xí)慣。
相關(guān)文章
如何使用Spring Boot ApplicationRunner解析命令行中的參數(shù)
這篇文章主要介紹了使用Spring Boot ApplicationRunner解析命令行中的參數(shù),本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2018-12-12
java實(shí)現(xiàn)pgsql自動(dòng)更新創(chuàng)建時(shí)間與更新時(shí)間的兩種方式小結(jié)
本文主要介紹了java實(shí)現(xiàn)pgsql自動(dòng)更新創(chuàng)建時(shí)間與更新時(shí)間的兩種方式小結(jié),主要包括通過(guò)數(shù)據(jù)庫(kù)自身實(shí)現(xiàn)以及通過(guò)mybatisplus的TableField注解添加,具有一定的參考價(jià)值,感興趣的可以了解一下2024-01-01
SpringBoot動(dòng)態(tài)Feign服務(wù)調(diào)用詳解
Feign是Netflix公司開(kāi)發(fā)的一個(gè)聲明式的REST調(diào)用客戶端; Ribbon負(fù)載均衡、 Hystrⅸ服務(wù)熔斷是我們Spring Cloud中進(jìn)行微服務(wù)開(kāi)發(fā)非?;A(chǔ)的組件,在使用的過(guò)程中我們也發(fā)現(xiàn)它們一般都是同時(shí)出現(xiàn)的,而且配置也都非常相似2022-12-12
MyBatis批量插入幾千條數(shù)據(jù)為何慎用foreach
這篇文章主要介紹了MyBatis批量插入幾千條數(shù)據(jù)為何慎用foreach問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-10-10
springboot 通過(guò)代碼自動(dòng)生成pid的方法
這篇文章主要介紹了springboot 通過(guò)代碼自動(dòng)生成pid的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-07-07
Spring中@PropertySource的使用方法和運(yùn)行原理詳解
這篇文章主要介紹了Spring中@PropertySource的使用方法和運(yùn)行原理詳解,PropertySource注解可以方便和靈活的向Spring的環(huán)境容器(org.springframework.core.env.Environment?Environment)中注入一些屬性,這些屬性可以在Bean中使用,需要的朋友可以參考下2023-11-11
Java如何實(shí)現(xiàn)數(shù)據(jù)壓縮所有方式性能測(cè)試
本文介紹了多種壓縮算法及其在Java中的實(shí)現(xiàn),包括LZ4、BZip2、Deflate、Gzip和7z等,LZ4以其高效的壓縮和解壓縮速度而受到青睞,特別是在大數(shù)據(jù)處理場(chǎng)景中,通過(guò)對(duì)比不同壓縮算法的性能和壓縮率,我們選擇了最適合當(dāng)前項(xiàng)目需求的壓縮工具2025-02-02
Java HashMap源碼及并發(fā)環(huán)境常見(jiàn)問(wèn)題解決
這篇文章主要介紹了Java HashMap源碼及并發(fā)環(huán)境常見(jiàn)問(wèn)題解決,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-09-09
解決java后臺(tái)登錄前后cookie不一致問(wèn)題
本文主要介紹了java后臺(tái)登錄前后cookie不一致的解決方案,具有很好的參考價(jià)值,需要的朋友一起來(lái)看下吧2016-12-12

