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)的系统教程(深表感谢)和 网络上的现有资源(博客,文档,图书等),资源的出处我会标明 本博客的目的:①总结自己的学习过程,相当 ...
随机推荐
- 题目分享R
题意:有n只蚂蚁在木棍上爬行,每只蚂蚁的速度都是每秒1单位长度,现在给你所有蚂蚁初始的位置(蚂蚁运动方向未定),蚂蚁相遇会掉头反向运动,让你求出所有蚂蚁都·掉下木棍的最短时间和最长时间. 分析:(其实 ...
- kafka-eagle监控kafka
最近想做一个kafka监控,本来准备用zabbix来监控的,需要重复造轮子,本来准备用kafka-Manager的,在GitHub上无意发现了kafka-eagle,看了官方介绍准备试一下..... ...
- SpringCloudStream学习(一)RabbitMQ基础
应公司大佬要求,学习一下SpringCloudStream,作为技术储备.这几天也看了这方面的资料,现在写一篇笔记,以做总结.文章会从RabbitMQ基础讲起,到SpringCloudStream结束 ...
- react中this.setState的理解
this.setState作用? 在react中要修改this.state要使用this.setState,因为this.state只是一个对象,单纯的修改state并不会触发ui更新.所以我们需要用 ...
- Try-Catch包裹的代码异常后,竟然导致了产线事务回滚!
导读:一段被try-catch包裹后的代码在产线稳定运行了200天后忽然发生了异常,而这个异常竟然导致了产线事务回滚.这期间究竟发生了什么?日常在项目过程中该如何避免事务异常?就在这个时候,老板拿着 ...
- Windows命令行:xcopy、move、rename
Windows命令行,xcopy复制粘贴,move剪切粘贴,rename/ren重命名.当简单事情重复做时,Windows命令行有用武之地了.批命令中,暂时用不到的行,用两个冒号注释掉. 不同路径下, ...
- Python:日薪工资计算
劳动者离职,当天要结清工资,实际操作是当天算清,三日内结清.有的公司省人力和吃利息,统一计算,统一下月月底发放. 有时要验算下离职工资,用Python操作一番,输入计时天数.请假小时.加班小时.基本工 ...
- python语法学习第十天--类与对象
python面向对象语言 对象=属性+方法 OO(Object oriented面向对象)的特征: ①封装,信息隐蔽技术②继承:class A(BaseClass):③多态 类:图纸 class ...
- 【系列】Python编程思想(1):Python简介与开发环境搭建
李宁老师的 开始学习. 本系列文章深入介绍了Python的各种技术,堪称是目前最全的Python教程.主要目的是让读者可以了解Python的各种核心技术,包括各种Python函数库.本教程使用Py ...
- 搭建私有镜像仓库registry 2.0
搭建 docker run -d -p 5000:5000 --restart=always --name registry2 registry:2 就可以将自己的镜像 push到这个私有的镜像仓库 ...