MVC案例
MVC案例分析:
- 没有业务层,直接Servlet调用Dao,所以也没有业务操作。所有在DAO直接获取Connection对象
-采用MVCDs设计模式
-使用到的技术:
mvc设计模式:JSP Servlet POJO
数据库使用Mysql
连接数据库使用C3P0数据库连接池
JDBC工具使用DBUtils
页面上的提示操作使用jQuery
技术难点:多个请求如何使用一个Servlet
模糊查询
在创建或者修改的情况,验证用户名是否已经被使用,并给出提示
基本架构

1.创建数据表
Create table customers(
id int primary key auto_increment,
name varchar(30) not null unique,
address varchar(30),
phone varchar(30)
);
为 name 字段添加唯一约束:
alter table customers add constraint name_uk unique(name);
2.加入 C3P0 数据源
C3p0
数据库驱动的 jar 包
c3p0-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config> <named-config name="helloc3p0">
<!--提供获取连接的四个基本信息 -->
<!--连接本地主机的话: jbdc:mysql://localhost:3306/test 可写成jbdc:mysql:///test -->
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/aff</property>
<property name="user">root</property>
<property name="password">123456</property> <!-- 对数据库连接池管理的基本信息 -->
<!-- 当数据库连接池中的连接数不够时,c3p0一次向数据库服务器申请的连接数 -->
<property name="acquireIncrement">5</property>
<!-- 初始化时的连接数 -->
<property name="initialPoolSize">10</property>
<!-- 维护的最少连接数 -->
<property name="minPoolSize">10</property>
<!-- 维护的最多的连接数 -->
<property name="maxPoolSize">100</property>
<!-- 最多维护的Satement的个数 -->
<property name="maxStatements">50</property>
<!-- 每个连接最多使用Statement的个数 -->
<property name="maxStatementsPerConnection">2</property> </named-config>
</c3p0-config>
3.编写 DAO、JdbcUtils工具类 和 CustomerDAO 接口
DAO
package com.aff.mvcapp.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.aff.mvcapp.db.JDBCUtilsC3P0; /**
* 封装了基本的CRUD方法,以供子类继承使用. 当前 DAO 直接在方法中获取数据库连接
*
* @param <T>:当前DAO处理的实体类的类型是什么
*/
public class DAO<T> {
private QueryRunner queryRunner = new QueryRunner(); private Class<T> clazz; public DAO() {
Type superclass = 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<T>) typeArgs[0];
}
}
}
} // 返回某一个字段的值
// 例如返回某一条记录的customerName,或返回数据表中有多少条记录等
public <E> E getForValue(String sql, Object args) {
Connection conn = null;
try {
conn = JDBCUtilsC3P0.getConnection();
return (E) queryRunner.query(conn, sql, new ScalarHandler(), args); } catch (Exception e) {
e.printStackTrace();
} finally {
JDBCUtilsC3P0.closeResource(conn, null, null);
}
return null;
} // 返回T 所对应的List
public List<T> getForList(String sql, Object... args) {
Connection conn = null;
try {
conn = JDBCUtilsC3P0.getConnection();
return queryRunner.query(conn, sql, new BeanListHandler<>(clazz), args); } catch (Exception e) {
e.printStackTrace();
} finally {
JDBCUtilsC3P0.closeResource(conn, null, null);
}
return null;
} // 返回对应 T 的一个实例类的对象
public T get(String sql, Object... args) {
Connection conn = null;
try {
conn = JDBCUtilsC3P0.getConnection();
return queryRunner.query(conn, sql, new BeanHandler<>(clazz), args);
} catch (Exception e) {
e.printStackTrace();
} finally {
JDBCUtilsC3P0.closeResource(conn, null, null);
}
return null; } // 封装了insert delete update操作
public void update(String sql, Object... args) {
Connection conn = null;
try {
conn = JDBCUtilsC3P0.getConnection();
queryRunner.update(conn, sql, args);
} catch (Exception e) {
e.printStackTrace();
} finally {
JDBCUtilsC3P0.closeResource(conn, null, null);
} } }
JdbcUtils工具类
JDBCUtilsC3P0.java
package com.aff.mvcapp.db;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.apache.commons.dbutils.DbUtils;
import com.mchange.v2.c3p0.ComboPooledDataSource; //使用C3P0数据库连接池
public class JDBCUtilsC3P0 {
// 把池子拿到外边,连接池一个就够,需要的连接从池子中拿
private static ComboPooledDataSource cbpds = new ComboPooledDataSource("helloc3p0"); public static Connection getConnection() throws SQLException {
Connection conn = cbpds.getConnection();
return conn;
}
public static void closeResource(Connection conn, PreparedStatement ps, ResultSet rs) {
// 7.资源的关闭
DbUtils.closeQuietly(conn);
DbUtils.closeQuietly(ps);
DbUtils.closeQuietly(rs);
}
}
CustomerDAO
package com.aff.mvcapp.dao;
import java.util.List;
import com.aff.mvcapp.domian.Customer;
public interface CustomerDAO { public List<Customer> gerAll(); public void save(Customer customer); public Customer get(Integer id); public void delete(Integer id); /**
* 返回和 name 相等的记录数
*
* @param name
* @return
*/
public long getCountWithName(String name);
public void update(Customer customer);
}
4.提供 CustomerDAO 接口的实现类:CustomerDAOImpl
CustomerDAOImpl
package com.aff.mvcapp.dao.impl;
import java.util.List;
import com.aff.mvcapp.dao.CustomerDAO;
import com.aff.mvcapp.dao.DAO;
import com.aff.mvcapp.domian.Customer; public class CustomerDAOImpl extends DAO<Customer> implements CustomerDAO { @Override
public List<Customer> gerAll() {
String sql = "select id, name, address, phone from customers";
return getForList(sql);
} @Override
public void save(Customer customer) {
String sql = "insert into customers(name,address,phone)values(?,?,?)";
update(sql, customer.getName(), customer.getAddress(), customer.getPhone());
} @Override
public Customer get(Integer id) {
String sql = "select id,name,address,phone from customers where id =?";
return get(sql, id);
} @Override
public void delete(Integer id) {
String sql = "delete from customers where id = ?";
update(sql, id); } @Override
public long getCountWithName(String name) {
String sql = "select count(id) from customers where name =?";
return getForValue(sql, name);
} public void update(Customer customer){
String sql ="update customers set name = ?,address = ?,phone = ? where id = ?";
update(sql,customer.getName(),customer.getAddress(),customer.getPhone(),customer.getId());
}
5.测试CustomerDAOImpl
TestCustomerDAOImpl
package com.aff.mvcapp.test;
import java.util.List;
import org.junit.Test;
import com.aff.mvcapp.dao.CustomerDAO;
import com.aff.mvcapp.dao.impl.CustomerDAOImpl;
import com.aff.mvcapp.domian.Customer; public class TestCustomerDAOImpl {
private CustomerDAO customerDAO = new CustomerDAOImpl(); @Test
public void testGerAll() {
List<Customer> list = customerDAO.gerAll();
list.forEach(System.out::println); } @Test
public void testSave() {
Customer customer = new Customer();
customer.setAddress("苏州");
customer.setName("芳芳");
customer.setPhone("1451326318489");
customerDAO.save(customer);
} @Test
public void testGetInteger() {
Customer cust = customerDAO.get(1);
System.out.println(cust);
} @Test
public void testDelete() {
customerDAO.delete(1);
} @Test
public void testGetCountWithName() {
long count = customerDAO.getCountWithName("芳芳");
System.out.println(count);
}
}
目录结构

MVC案例的更多相关文章
- 【JavaWeb】MVC案例之新闻列表
MVC案例之新闻列表 作者:白宁超 2016年6月6日15:26:30 摘要:本文主要针对javaweb基本开发之MVC案例的简单操作,里面涉及mysql数据库及表的创建,以及jsp页面和servle ...
- ASP.NET MVC案例教程(四)
ASP.NET MVC案例教程(四) 前言 通过前几篇文章,我们已经能比较自如的使用ASP.NET MVC来呈现页面和数据了.但是,有一个大问题没有解决:如何处理表单数据.例如,我们将要实现的公告发布 ...
- SpringBoot系列之三_一个完整的MVC案例
这一节让我们来做一个完整的案例. 我们将使用MyBatis作为ORM框架,并以非常简单的方式来使用MyBatis,完成一个完整的MVC案例. 此案例承接上一节,请先搭建好上一节案例. 一.数据库准备 ...
- ASP.NET MVC案例教程(五)
ASP.NET MVC案例教程(四) 前言 通过前几篇文章,我们已经能比较自如的使用ASP.NET MVC来呈现页面和数据了.但是,有一个大问题没有解决:如何处理表单数据.例如,我们将要实现的公告发布 ...
- ASP.NET MVC案例教程(二)
ASP.NET MVC案例教程(二) 让第一个页面跑起来 现在,我们来实现公告系统中的第一个页面——首页.它非常简单,只包括所有公告分类的列表,并且每个列表项是一个超链接.其中分类数据是用我们的Moc ...
- ASP.NET MVC案例教程(三)
ASP.NET MVC案例教程(二) 让第一个页面跑起来 现在,我们来实现公告系统中的第一个页面——首页.它非常简单,只包括所有公告分类的列表,并且每个列表项是一个超链接.其中分类数据是用我们的Moc ...
- ASP.NET MVC案例教程(一) 准备
ASP.NET MVC案例教程(一) 前言 ASP.NET MVC作为微软官方的MVC解决方案,推出有一段时间了.可以说自动推出以来,一直广受关注.在经历了漫长的Preview之后,前几天终于推出了其 ...
- [原创]java WEB学习笔记20:MVC案例完整实践(part 1)---MVC架构分析
本博客为原创:综合 尚硅谷(http://www.atguigu.com)的系统教程(深表感谢)和 网络上的现有资源(博客,文档,图书等),资源的出处我会标明 本博客的目的:①总结自己的学习过程,相当 ...
- [原创]java WEB学习笔记21:MVC案例完整实践(part 2)---DAO层设计
本博客为原创:综合 尚硅谷(http://www.atguigu.com)的系统教程(深表感谢)和 网络上的现有资源(博客,文档,图书等),资源的出处我会标明 本博客的目的:①总结自己的学习过程,相当 ...
随机推荐
- IO与反射机制总结
IO与反射机制全面总结 一.file类:属于java.io包中kkb 作用:操作文件或目录 file既可以表示文件,也可以表示目录,也可以表示盘符.利用他可以用来对文件进行操作. file中常用的构造 ...
- python 中关于无法导入自己写的类。解决方法
1.错误描述 之前在学习python的过程中,导入自己写入的包文件时.from 自己写的类,会发现没有弹出选择.并且全输入类名称后会发现类名与相关导入的方法会爆红.如图: 2.原因分析 pycharm ...
- 写给Android 混淆小白的快速混淆方法
为啥子要混淆 简单来说,Android 进行ProGuard,可以起到压缩,混淆,预检,优化的功能,虽然不能说更安全但还是一个不容忽视的环节. 开始混淆第一步 首先在build.gradle 中将混淆 ...
- PHP循环引用会遇到的坑
今天遇到这样一个问题: 如果foreach循环一个数组,引用去对它的元素做一些操作,会有什么问题吗? 比如 [1, 2, 3],foreach循环的时候,引用给每个元素 * 2,再去foreach输出 ...
- 003_python的str切片,str常用操作方法,for循环,集合,深浅copy
基础数据类型 基础数据类型,有7种类型,存在即合理. 1.int 整数 主要是做运算的 .比如加减乘除,幂,取余 + - * / ** %... 2.bool布尔值 判断真假以及作为条件变量 3.s ...
- 【Spark】通过创建DataFrame读取不同类型文件内容
文章目录 读取文本文件 第一种方法:通过RDD配合case class转换DataFrame 步骤 一.创建测试所需的文本文件 二.在spark-shell中执行以下操作 第二种方法:通过sparkS ...
- 【Hadoop离线基础总结】大数据集群环境准备
大数据集群环境准备 三台虚拟机关闭防火墙 centOS 7 service firewalld stop ->关闭防火墙 chkconfig firewalld off ->开机关闭防火墙 ...
- Linux 通过终端命令行切换系统语言
通过命令的形式修改系统的语言,比较详细的讲解了来龙去脉: 文章目录 0 前言 1 locale 文件 2 查找相关文件 3 解决方案 4 相关信息 4.1 locale属性的含义 4.2 LANGUA ...
- zabbix部署与配置
zabbix部署与配置 1.zabbix的web界面是基于php开发,所以创建lnmp环境来支持web界面的访问 yum install nginx php php-devel php-mysql p ...
- Mysql 常用函数(19)- mod 函数
Mysql常用函数的汇总,可看下面系列文章 https://www.cnblogs.com/poloyy/category/1765164.html mod 的作用 求余数,和%一样 mod的语法格式 ...