使用Servlet+JDBC 開發java web應用


一說到java web 應用的開發,很多人肯定想到的是用spring mvc 、Struts2  這些熱門框架去開發,簡單高效,只要配置好框架,剩下的工作就是體力活了。

但是很多人用慣了框架,一但開發中遇到問題,就束手無策,究其原理是根本不理解java web 最基礎、最核心的東西。其實那些所謂的框架,其本質是在servlet和jdbc的

基礎上擴展功能,封裝常用的函數、以xml配置的方式提供給開發者使用。

 

言歸正傳,下面就介紹servlet和jdbc的使用:

 

在web2.5以前,servlet都是在web.xml中配置使用的,相信這個大家都很熟悉,如下:

<servlet>
    <servlet-name>testServlet</servlet-name>
    <servlet-class>com.qthh.web.servlet.TestServlet</servlet-class>
</servlet>
 
<servlet-mapping>
    <servlet-name>testServlet</servlet-name>
    <url-pattern>/test/list</url-pattern>
</servlet-mapping>

web3.0后,servlet的使用更加方便,支持注解了,如下:

@WebServlet("/test/list")
public class TestServlet extends HttpServlet {

這樣就不用再web.xml中配置那么一大堆了。

要開發java web 應用 ,首先你得搞清楚后台要做哪些事,也就是大家常說的分層。

最基本的分層就是:控制層+數據訪問層  

擴展一點的話就是:控制層(servlet)+服務層(業務邏輯)+數據訪問層(dao)+模型(java bean)

知道了這些,我們就開始一層一層的去解決,首先從數據訪問層開始。

 

 

 一.數據訪問層

       顧名思義,就是要操作數據庫,既然要操作數據庫,我們就要寫個類去做這個事,封裝常用的方法,JDBC為我們提供了操作數據庫的方法,我們需要了解JDBC的使用方法

       步驟如下:

       1.加載驅動:我們熟知的Class.forName

       2.驅動管理器建立連接:DriverManager.getConnection

       3.創建Statement(或PreparedStatement)對象

       4.執行操作:query或者update

       為了方便大家,直接貼出封裝部分代碼: 

          

public class DBHelper {
    
    private static final String DRIVENAME = "com.mysql.jdbc.Driver";
    private static final String URL = "jdbc:mysql://192.168.1.200:3306/web";
    private static final String USER = "root";
    private static final String PASSWORD = "123456";
    
    private Connection conn = null;
    private Statement st = null;
    private PreparedStatement ppst = null;
    private ResultSet rs = null;
    
    /**
     * 加載驅動
     */
    static{
        try {
            Class.forName(DRIVENAME).newInstance();
        } catch (Exception e) {
            System.out.println("驅動加載失敗:"+e.getMessage());
        }
    }
    

    /**
     * 連接數據庫
     * @return
     */
    public Connection getConn(){
        try {
            conn =  DriverManager.getConnection(URL,USER,PASSWORD);
        } catch (SQLException e) {
            System.out.println("數據庫連接失敗:"+e.getMessage());
        }
        return conn;
    }
    
    
    /**
     * 獲取結果集(無參)
     * @param sql
     * @return
     */
    private ResultSet getRs(String sql){
        conn = this.getConn();
        try {        
            st = conn.createStatement();
            rs = st.executeQuery(sql);
        } catch (SQLException e) {
            System.out.println("查詢(無參)出錯:"+e.getMessage());
        }
        return rs;
    }
    
    
    /**
     * 獲取結果集
     * @param sql
     * @param params
     * @return
     */
    private ResultSet getRs(String sql,Object[] params){
        conn = this.getConn();
        try {            
            ppst = conn.prepareStatement(sql);
            if(params!=null){
                for(int i = 0;i<params.length;i++){
                    ppst.setObject(i+1, params[i]);
                }
            }            
            rs = ppst.executeQuery();
        } catch (SQLException e) {
            System.out.println("查詢出錯:"+e.getMessage());
        }
        
        return rs;
    }
    
        
    /**
     * 查詢
     * @param sql
     * @param params
     * @return
     */
    public List<Object> query(String sql,Object[] params){
        
        List<Object> list = new ArrayList<Object>();
        ResultSet rs = null;
        if(params!=null){
            rs = getRs(sql, params);
        }else{
            rs = getRs(sql);
        }
        ResultSetMetaData rsmd = null;
        int columnCount = 0; 
            
        try {            
            rsmd = rs.getMetaData();  
            columnCount = rsmd.getColumnCount();            
            while(rs.next()){
                Map<String, Object> map = new HashMap<String, Object>();
                for(int i = 1;i<=columnCount;i++){
                    map.put(rsmd.getColumnLabel(i), rs.getObject(i));  
                }
                list.add(map);
            }
        } catch (SQLException e) {
            System.out.println("結果集解析出錯:"+e.getMessage());
        } finally {
            closeConn();
        }
        return list;
    }
    
    
    /**
     * 更新(無參)
     * @param sql
     */
    public int update(String sql){        
        int affectedLine = 0;//受影響的行數
        conn = this.getConn();
        try {        
            st = conn.createStatement();
            affectedLine = st.executeUpdate(sql);
        } catch (SQLException e) {
            System.out.println("更新(無參)失敗:"+e.getMessage());
        } finally {
            closeConn();
        }
        return affectedLine;
    }
    
    
    /**
     * 更新
     * @param sql
     * @param params
     * @return
     */
    public int update(String sql,Object[] params){
        int affectedLine = 0;//受影響的行數
        conn = this.getConn();
        try {
            ppst = conn.prepareStatement(sql);
            if(params!=null){
                for(int i = 0;i<params.length;i++){
                    ppst.setObject(i+1, params[i]);
                }
            }
            affectedLine = ppst.executeUpdate();
        } catch (SQLException e) {
            System.out.println("更新失敗:"+e.getMessage());
        } finally {
            closeConn();
        }
        return affectedLine;
    }
    
    
    private void closeConn(){
        
        if(rs!=null){
            try {
                rs.close();
            } catch (SQLException e) {
                System.out.println(e.getMessage());
            }
        }
        
        if(st!=null){
            try {
                st.close();
            } catch (SQLException e) {
                System.out.println(e.getMessage());
            }
        }
        
        if(ppst!=null){
            try {
                ppst.close();
            } catch (SQLException e) {
                System.out.println(e.getMessage());
            }
        }
        
        if(conn!=null){
            try {
                conn.close();
            } catch (SQLException e) {
                System.out.println(e.getMessage());
            }
        }
    }

}

 

      JDBC封裝好了,接下來,就是在dao層中定義接口,然后去實現接口

     

public interface TestDao {
    
    List<Object> query(String sql,Object[] params);
    
    int update(String sql,Object[] params);

}

 

public class TestDaoImpl implements TestDao {

    @Override
    public List<Object> query(String sql,Object[] params) {
        DBHelper db = new DBHelper();
        return db.query(sql, params);
    }

    @Override
    public int update(String sql,Object[] params) {
        DBHelper db = new DBHelper();
        return db.update(sql, params);
    }

}

以上就是一個很簡單的dao層示例。實際開發中,會對常用的方法進行封裝成baseDao,這里不做介紹。

 


二.服務層

     服務層也叫業務層,編寫業務邏輯的地方;關聯控制層和dao層,負責從dao層取數據,然后返回給控制層。實現方式和dao層類似,先定義接口,然后去實現接口。

     (這里肯定很多人有疑問,為啥非要定義接口,直接寫個類不就行了么。當然你這么做也是能實現功能,但是從設計規范和安全的角度的來講是不好的,以后也不方便維護。)

         

public interface TestService {
    
    List<Object> getTestList();//獲取列表
    
    int insertTest(Object[] params);//插入一條
    
    int modifyTest(Object[] params);//修改
    
    int deleteTest(Object[] params);//刪除

}
public class TestServiceImpl implements TestService {
    
    TestDao testDao = new TestDaoImpl();

    @Override
    public List<Object> getTestList() {
        String sql = "select * from test";
        return testDao.query(sql, null);
    }

    @Override
    public int insertTest(Object[] params) {
        String sql ="insert into test(name) values(?)";
        return testDao.update(sql, params);
    }

    @Override
    public int modifyTest(Object[] params) {
        String sql ="update test set name = ? where id = ?";
        return testDao.update(sql, params);
    }

    @Override
    public int deleteTest(Object[] params) {
        String sql ="delete from test where id = ?";
        return testDao.update(sql, params);
    }

}

 


三.控制層

     這一層是我們最熟悉的地方,創建一個servlet,文章一開始我們也提到了,至於他的作用,就不用我多說了,直接貼代碼

    

@WebServlet("/test/list")
public class TestServlet extends HttpServlet {
    
    private static final long serialVersionUID = 1L;
       
    TestService testService = new TestServiceImpl();
    
    
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/json; charset=utf-8");
        List<Object> list = testService.getTestList();
        PrintWriter out = null;
        System.out.println("list:"+list.toString());
        try {
            out = response.getWriter();
            out.write(list.toString());
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
        out.flush();
        out.close();
    }

    
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

}

       因為是例子,所以寫的很簡單。關於servlet如何返回不同的數據格式,比如json,將在后面的篇章中介紹。

 

 

 四. 模型 

       其實就是一個javabean,用來被填充數據的。如果我們做了orm(對象關系映射)的話,就不必操作數據庫,直接操作這個對象,也就是這里的模型。

       本案例沒用到,就不說了。

 

 

      麻雀雖小五臟俱全,到這里,web的整個后台已經完成了,接下來要做的就是發布到tomcat上測試一下。

     

      ok,正常運行。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM