-
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这个类来操作