1. 程式人生 > >實現javaWeb對資料庫的增刪改查-MVC開發思想-DAO層的實現

實現javaWeb對資料庫的增刪改查-MVC開發思想-DAO層的實現

  • 1.DAO原理圖

從右向左依次實現

  • 2.建立資料庫表

#建立資料庫
DROP DATABASE IF EXISTS myWebProject;
CREATE DATABASE myWebProject;
#使用資料庫
USE myWebProject;
#建立客戶表
CREATE TABLE customers(
	id INT PRIMARY KEY AUTO_INCREMENT,
	`name` VARCHAR(30) NOT NULL UNIQUE,
	address VARCHAR(30),
	phone VARCHAR(30)
);
DESC customers;
#查詢客戶表
SELECT * FROM customers;
  • 3.配置C3P0資料來源,實現執行緒池

3.1複製jar包到WEB-INF/lib目錄下

c3p0-0.9.5.2.jar

mchange-commons-java-0.2.11.jar

mysql-connector-java-5.1.46-bin.jar

3.2在src目錄下建立C3P0的配置檔案c3p0-config.xml並配置

<?xml version="1.0" encoding="UTF-8"?>


<c3p0-config>
  <!-- This app is massive! -->
  <named-config name="mvcapp"> 
  	<!-- 指定資料來源的基本屬性 -->
  	<property name="user">root</property>
  	<property name="password">root</property>
  	<property name="driverClass">com.mysql.jdbc.Driver</property>
  	<property name="jdbcUrl">jdbc:mysql://localhost:3306/myWebProject</property>
  
  	<!-- 若資料庫連線池中的連線數不夠時,一次建立多少個連線數 -->
    <property name="acquireIncrement">5</property>
    <!-- 初始化資料庫連線池時連線的數量 -->
    <property name="initialPoolSize">10</property>
    <!-- 資料庫連線池中最小的連線數 -->
    <property name="minPoolSize">10</property>
    <!-- 資料庫連線池中最大的連線數 -->
    <property name="maxPoolSize">50</property>

    <!-- C3P0資料庫連線池可以維護的statement的個數-->
    <property name="maxStatements">20</property> 
    <!-- 每個連線可以同時使用Statement物件的個數 -->
    <property name="maxStatementsPerConnection">5</property>
	</named-config>
</c3p0-config>
  • 4.在src目錄下建立一個包com.njupt.javaweb.db,並在其下建立JdbcUtils.java

package com.njupt.javaweb.db;

import java.sql.Connection;
import java.sql.SQLException;

import javax.sql.DataSource;

import com.mchange.v2.c3p0.ComboPooledDataSource;

/**
 * 
* 專案名稱:javaWebMVCProject 
* 類名稱:JbdcUtils 
* 類描述: JDBC操作的工具類
* 建立人:Administrator 
* 建立時間:2018年8月5日 下午6:52:33 
* 修改人:Administrator 
* 修改時間:2018年8月5日 下午6:52:33 
* 修改備註: 
* @version 1.0
 */
public class JdbcUtils {
	/**
	 * 因為使用C3P0資料庫連線池,不用關閉Statement與ResultSet,但是Connection需要關閉
	 * 關閉Connection
	 * @param connection
	 */
	public static void releaseConnection( Connection connection ) {
		if(connection!=null) {
			try {
				connection.close();
			} catch (Exception e) {
				// TODO: handle exception
				e.printStackTrace();
			}
		}
	}
	private static DataSource dataSource = null;
	//因為我們只需要一份datasource,所以寫在靜態程式碼塊內,當該java檔案被載入時執行一次
	static {
		dataSource=new ComboPooledDataSource("mvcapp");
	}
	/**
	 * 獲取資料來源的一個Connection物件
	 * @return Connection
	 * @throws SQLException 
	 */
	public static Connection getConnection() throws SQLException {
		return dataSource.getConnection();
	}
}

注意:靜態程式碼塊  

 static {
        dataSource=new ComboPooledDataSource("mvcapp");
    }

  • 5.在WEB-INF/lib目錄下匯入DBUtils的jar包,並在src目錄下建立一個包com.njupt.javaweb.dao,並在其下建立DAO.ava

commons-dbutils-1.7.jar

package com.njupt.javaweb.dao;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.sql.Connection;
import java.util.List;

import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;

import com.njupt.javaweb.db.JdbcUtils;

/**
 * 
* 專案名稱:javaWebMVCProject 
* 類名稱:DAO 
* 類描述: 封裝了基本的資料庫增刪改查(CRUD)的方法
* 		當前DAO無事務處理,直接在方法內過去連線
* 建立人:Administrator 
* 建立時間:2018年8月5日 下午6:07:43 
* 修改人:Administrator 
* 修改時間:2018年8月5日 下午6:07:43 
* 修改備註: 
* @version 1.0 
* @param <T>
 */
public class DAO<T> {
	//因為用到反射需要T的class類
	@SuppressWarnings("unused")
	private Class<T> clazz; 
	private QueryRunner queryRunner = new QueryRunner();
	/**
	 * DAO的構造器,在構造器內解析出泛型T的Class類
	 */
	public DAO() {
			Type superClass = this.getClass().getGenericSuperclass();
			if( superClass instanceof ParameterizedType ) {
				ParameterizedType parameterizedType = (ParameterizedType)superClass;
				Type [] typeArgs = parameterizedType.getActualTypeArguments();
				if( typeArgs != null && typeArgs.length > 0) {
					if( typeArgs[0] instanceof Class) {
						clazz = (Class)typeArgs[0];
					}
				}
			}
	}
	/**
	 * 獲取資料庫查詢後的某一個欄位的值,單行單列。例如獲取Name欄位的值,或者Count(*)記錄的條數
	 * @param sql 用於執行的sql語句
	 * @param args 填充SQL語句的佔位符
	 * @return 單行單列的值
	 */
	public <E> E getForValue( String sql , Object ... args ) {
		Connection connection = null;
		try {
			connection=JdbcUtils.getConnection();
			//返回資料對應的物件
			return queryRunner.query(connection,sql,new ScalarHandler<E>(),args);
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}finally {
			JdbcUtils.releaseConnection(connection);
		}
		return null;
	}
	/**
	 * 獲取由一組T的物件構成的List
	 * @param sql 用於執行的sql語句
	 * @param args 填充SQL語句的佔位符
	 * @return T的物件構成的List
	 */
	public List<T> getForList( String sql , Object ... args ){
		Connection connection = null;
		try {
			connection=JdbcUtils.getConnection();
			//返回資料對應的物件
			return queryRunner.query(connection,sql,new BeanListHandler<T>(clazz),args);
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}finally {
			JdbcUtils.releaseConnection(connection);
		}
		return null;
	}
	/**
	  * 獲取T的實體類物件,該物件與資料庫的記錄相一致
	  * 因為用到反射需要T的class類
	 * @param sql 用於執行的sql語句
	 * @param args 填充SQL語句的佔位符
	 * @return T的實體類物件
	 */
	public T get( String sql , Object ... args ) {
		Connection connection = null;
		try {
			connection=JdbcUtils.getConnection();
			//返回資料對應的物件
			System.out.println(connection);
			System.out.println(clazz);
			return queryRunner.query(connection,sql,new BeanHandler<T>(clazz),args);
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}finally {
			JdbcUtils.releaseConnection(connection);
		}
		return null;
	}
	/**
	 * 該方法封裝了,INSERT,DELETE,UPDATE相關的資料庫操作
	 * @param sql 用於執行的sql語句
	 * @param args 填充SQL語句的佔位符
	 */
	public void update( String sql , Object ... args ) {
		Connection connection = null;
		try {
			connection=JdbcUtils.getConnection();
			queryRunner.update(connection, sql, args);
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}finally {
			JdbcUtils.releaseConnection(connection);
		}
		
	}

}

這裡有個需要特別解釋的地方:

  • 6.在src目錄下建立一個包com.njupt.javaweb.business,在其下建立Customer.java實體類,與資料庫一一對應

package com.njupt.javaweb.dao;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.sql.Connection;
import java.util.List;

import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;

import com.njupt.javaweb.db.JdbcUtils;

/**
 * 
* 專案名稱:javaWebMVCProject 
* 類名稱:DAO 
* 類描述: 封裝了基本的資料庫增刪改查(CRUD)的方法
* 		當前DAO無事務處理,直接在方法內過去連線
* 建立人:Administrator 
* 建立時間:2018年8月5日 下午6:07:43 
* 修改人:Administrator 
* 修改時間:2018年8月5日 下午6:07:43 
* 修改備註: 
* @version 1.0 
* @param <T>
 */
public class DAO<T> {
	//因為用到反射需要T的class類
	@SuppressWarnings("unused")
	private Class<T> clazz; 
	private QueryRunner queryRunner = new QueryRunner();
	/**
	 * DAO的構造器,在構造器內解析出泛型T的Class類
	 */
	public DAO() {
			Type superClass = this.getClass().getGenericSuperclass();
			if( superClass instanceof ParameterizedType ) {
				ParameterizedType parameterizedType = (ParameterizedType)superClass;
				Type [] typeArgs = parameterizedType.getActualTypeArguments();
				if( typeArgs != null && typeArgs.length > 0) {
					if( typeArgs[0] instanceof Class) {
						clazz = (Class)typeArgs[0];
					}
				}
			}
	}
	/**
	 * 獲取資料庫查詢後的某一個欄位的值,單行單列。例如獲取Name欄位的值,或者Count(*)記錄的條數
	 * @param sql 用於執行的sql語句
	 * @param args 填充SQL語句的佔位符
	 * @return 單行單列的值
	 */
	public <E> E getForValue( String sql , Object ... args ) {
		Connection connection = null;
		try {
			connection=JdbcUtils.getConnection();
			//返回資料對應的物件
			return queryRunner.query(connection,sql,new ScalarHandler<E>(),args);
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}finally {
			JdbcUtils.releaseConnection(connection);
		}
		return null;
	}
	/**
	 * 獲取由一組T的物件構成的List
	 * @param sql 用於執行的sql語句
	 * @param args 填充SQL語句的佔位符
	 * @return T的物件構成的List
	 */
	public List<T> getForList( String sql , Object ... args ){
		Connection connection = null;
		try {
			connection=JdbcUtils.getConnection();
			//返回資料對應的物件
			return queryRunner.query(connection,sql,new BeanListHandler<T>(clazz),args);
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}finally {
			JdbcUtils.releaseConnection(connection);
		}
		return null;
	}
	/**
	  * 獲取T的實體類物件,該物件與資料庫的記錄相一致
	  * 因為用到反射需要T的class類
	 * @param sql 用於執行的sql語句
	 * @param args 填充SQL語句的佔位符
	 * @return T的實體類物件
	 */
	public T get( String sql , Object ... args ) {
		Connection connection = null;
		try {
			connection=JdbcUtils.getConnection();
			//返回資料對應的物件
			System.out.println(connection);
			System.out.println(clazz);
			return queryRunner.query(connection,sql,new BeanHandler<T>(clazz),args);
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}finally {
			JdbcUtils.releaseConnection(connection);
		}
		return null;
	}
	/**
	 * 該方法封裝了,INSERT,DELETE,UPDATE相關的資料庫操作
	 * @param sql 用於執行的sql語句
	 * @param args 填充SQL語句的佔位符
	 */
	public void update( String sql , Object ... args ) {
		Connection connection = null;
		try {
			connection=JdbcUtils.getConnection();
			queryRunner.update(connection, sql, args);
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}finally {
			JdbcUtils.releaseConnection(connection);
		}
		
	}

}
  • 7.在com.njupt.javaweb.dao包下建立與業務相關的介面CustomerDAO.java,並定義要實現的方法

package com.njupt.javaweb.dao;

import java.util.List;

import com.njupt.javaweb.business.Customer;

/**
 * 
* 專案名稱:javaWebMVCProject 
* 類名稱:CustomerDAO 
* 類描述: 業務介面,主要用來宣告與業務相關的方法
* 建立人:Administrator 
* 建立時間:2018年8月5日 下午7:00:43 
* 修改人:Administrator 
* 修改時間:2018年8月5日 下午7:00:43 
* 修改備註: 
* @version 1.0
 */
public interface CustomerDAO {
	public List<Customer> getAll();
	public void save( Customer customer);
	public Customer get( int id );
	public void delete( int id );
	public long getCountSameWithName( String name );
}
  • 8.在src目錄下建立一個包com.njupt.javaweb.bussimp,並在其下建立處理業務的java檔案,CustomerDAOJdbcImp.java

package com.njupt.javaweb.bussimp;

import java.util.List;

import com.njupt.javaweb.business.Customer;
import com.njupt.javaweb.dao.CustomerDAO;
import com.njupt.javaweb.dao.DAO;

public class CustomerDAOJdbcImp extends DAO<Customer> implements CustomerDAO{

	@Override
	public List<Customer> getAll() {
		// TODO Auto-generated method stub
		String sql = "SELECT * FROM customers";
		//CustomerDAOJdbcImp cus = new CustomerDAOJdbcImp();
		return this.getForList(sql);
	}

	@Override
	public void save(Customer customer) {
		// TODO Auto-generated method stub
		String sql = "INSERT INTO customers(name,address,phone) VALUES(?,?,?)";
		this.update(sql, customer.getName(),customer.getAddress(),customer.getPhone());
		
	}

	@Override
	public Customer get(int id) {
		// TODO Auto-generated method stub
		String sql = "SELECT * FROM customers WHERE id = ? ";
		return this.get(sql, id);
	}

	@Override
	public void delete(int id) {
		// TODO Auto-generated method stub
		String sql = "DELETE FROM customers WHERE id = ?";
		this.update(sql, id);
		
	}

	@Override
	public long getCountSameWithName(String name) {
		// TODO Auto-generated method stub
		String sql = "SELECT COUNT(*) FROM customers WHERE name = ?";
		return this.getForValue(sql, name);
	}

}

至此,Model層建立完畢,所有的有關資料庫操作的請求,都有CustomerDAOJdbcImp.java這個類來操作