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)的系统教程(深表感谢)和 网络上的现有资源(博客,文档,图书等),资源的出处我会标明 本博客的目的:①总结自己的学习过程,相当 ...
随机推荐
- 集训模拟赛-1-T2
好了不要在铺垫了直接整吧就 题目拿来!!!!!!! 倒水 (water) (256MB,1s) [问题描述] 你有一个水桶(记为 0),两个杯子(记为 1,2).水桶中的水量无限,容量也无限.1 号杯 ...
- E. A Simple Task
E. A Simple Task 这个题目的意思是 给你一个由小写字母组成的字符串,有两种操作 i j k 如果k==1 那么就是就把i 到 j 的这个区间非递减排序. i j k如果k==2 那么就 ...
- 惠普服务器ipmi配置方法
个人感觉惠普ipmi搞的比戴尔的好 惠普的ipmi口在服务器上的端口名称叫ilo 1.开机按F8进入ilo. 注:按晚了,会进入磁盘阵列配置页面,开机画面显示出来ilo相关的信息之后就要按F8. 2. ...
- spring内嵌jetty容器,实现main方法启动web项目
Jetty 是一个开源的servlet容器,它为基于Java的web容器,例如JSP和servlet提供运行环境.Jetty是使用Java语言编写的,它的API以一组JAR包的形式发布.开发人员可以将 ...
- Angular 从入坑到挖坑 - Router 路由使用入门指北
一.Overview Angular 入坑记录的笔记第五篇,因为一直在加班的缘故拖了有一个多月,主要是介绍在 Angular 中如何配置路由,完成重定向以及参数传递.至于路由守卫.路由懒加载等&quo ...
- Airtable base
PC端习惯了SQL Server Express.Access数据库的强大,安卓端再去用Microsoft Office.WPS,能让你怀疑人生.使用Airtable是个不错的方案,workspace ...
- 设计模式之GOF23原型模式02
利用序列化和反序列化完成深复制 ByteArrayOutputStream bos=new ByteArrayOutputStream(); ObjectOutputStream oos=new O ...
- Dubbo对Spring Cloud说:来老弟,我要拥抱你
项目地址 https://github.com/yinjihuan/kitty-cloud 前言 Kitty Cloud 开源后有以为朋友在 GitHub 上给我提了一个 issues,问为什么项目中 ...
- delete old data in elasticsearch
delete old data in elasticsearch 0.正文. 其实很简单,就是用他的rest api 发一个delete 请求到 localhost:9200/[indices] [i ...
- 【雕爷学编程】Arduino动手做(5)---热敏温度传感器模块
37款传感器与模块的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是不止37种的.鉴于本人手头积累了一些传感器模块,依照实践(动手试试)出真知的理念,以学习和交流为目的,这里准备逐 ...