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)的系统教程(深表感谢)和 网络上的现有资源(博客,文档,图书等),资源的出处我会标明 本博客的目的:①总结自己的学习过程,相当 ...
随机推荐
- LeetCode 刷题1---两数之和
/** 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标. 你可以假设每种输入只会对应一个答案.但是,你不能重复利用这个数组中 ...
- jquery-----ajax的几种方法
$.get(url,function(data,status){ if(status == 'success'){ layer.msg(data,{shift:1,time:2000},functio ...
- Android 仿百度手机助手首页滑动效果
今天看到百度手机助手首页上的滑动效果非常nice,主要功能归结为: 1.当手指上划时,顶部搜索栏随手指移动距离而缩小到隐藏,隐藏后内容还是可以继续移动 2.手指下滑时,当显示内容达到第一个时,顶部搜索 ...
- java ->多线程_线程同步、死锁、等待唤醒机制
线程安全 如果有多个线程在同时运行,而这些线程可能会同时运行这段代码.程序每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,就是线程安全的. l 我们通过一个案例,演示线 ...
- Anaconda3中的Jupyter notebook添加目录插件
学习python和人工智能的相关课程时安装了Anaconda3,想在Jupyter notebook中归纳整理笔记,为了方便日后查找想安装目录(Table of Contents, TOC)插件,查找 ...
- es6中class类的全方面理解
传统的javascript中只有对象,没有类的概念.它是基于原型的面向对象语言.原型对象特点就是将自身的属性共享给新对象.这样的写法相对于其它传统面向对象语言来讲,很有一种独树一帜的感脚!非常容易让人 ...
- Office 2016 英文版(VOL版)下载
Office 2016 英文版(大客户版)下载磁力链接: 1.专业版(含project.visio) ProPlus, Project Pro, Visio Pro (x86-x64) magnet: ...
- Spark Streaming 整合 Flume
Spark Streaming 整合 Flume 一.简介二.推送式方法 2.1 配置日志收集Flume 2.2 项目依赖 2.3 Spark Strea ...
- 【DevCloud · 敏捷智库】如何拆分用户故事
提起用户故事拆分,我们听得最多的就是INVEST原则(关于INVEST原则可以参考文章“用户故事等于需求说明”——你一定没有写好用户故事),但很多人面临的问题是拿到一个较大的用户故事时,该如何拆分才能 ...
- 微信小程序入门知识点总结
微信小程序入门知识点总结 前情介绍 微信小程序就不多介绍了,我们想要开发微信小程序首先得到微信公众平台 下方的小程序处注册相关账号并登录,接着填写小程序相关资料.在设置处可找到AppID用以开发微 ...