注:本文内容是建立在佟刚老师的JavaWeb教程上写的,如有侵犯,联系删除
sql语句
Create table customers(
id int primary key auto_increment,
name varchar(30) not null unique,
address varchar(30),
phone varchar(30)
);
1、现在src目录下建立一个 c3p0-config.xml ,在里面添加如下代码
com.mysql.jdbc.Driver
jdbc:mysql://localhost:3306/data?serverTimezone=GMT
root
123456
10
30
100
10
200
2、JdbcUtils工具类实现连接池的链接和关闭
public class JdbcUtils {
/**
* 释放Connection 连接
* @param connection
*/
public static void releaseConnection(Connection connection){
}
private static DataSource dataSource = null;
static {
dataSource = new ComboPooledDataSource("mvcapp");
}
/**
* 返回一个Connection 对象
* @return
*/
public static Connection getConnection(){
Connection conn=null;
try {
conn=dataSource.getConnection();
} catch (SQLException e) {
e.printStackTrace();
}
return conn;
}
}
注意:c3p0-config.xml的 < named-config name="mvcapp">
应该与JdbcUtils的dataSource = new ComboPooledDataSource("mvcapp");
相匹配
编写 DAO、JdbcUtils工具类 、 CustomerDAO 接口和CustomerDAO 接口的实现类:CustomerDAOJDBCImpl,请见源码。
多个请求使用一个Servlet有两种方法:
1、在同一个Servlet后面接不同的method,例如:
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取对应的操作方式,例如:customerServlet?method=delete
String method = req.getParameter("method");
switch (method){
case "add": add(req,resp);break;
case "query": query(req,resp);break;
case "delete": delete(req,resp);break;
case "update": update(req,resp);break;
}
}
//add、query、delete分别是CustomerDAO的具体实现方法
private void delete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String idStr = req.getParameter("id");
int id = 0;
//try-catch 作用防止id不能转化为整数;若不能,则id=0
try {
id = Integer.parseInt(idStr);
customerDAO.delete(id);
} catch (NumberFormatException e) {
e.printStackTrace();
}
resp.sendRedirect("query.do");
}
虽然这种方法也经常被使用,但是有明显的缺点:
①、当添加一个请求时,需要在 Servlet 中修改两处代码:switch、添加方;
②、在请求后面暴露了请求的方式,不私密,存有安全隐患。
2、利用 *do 的Servlet映射方式,实现多个请求使用一个Servle
在这里要注意一下,Servlet映射的配置样式
:
customerServlet
cqy.dao.mvc.servlet.CustomerServlet
customerServlet
*.do
在CustomerServlet里实现如下(这部分的反射调用对应的方法不是很理解):
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1、获取ServletPath:/edit.do 或 addCustomer.do 等
String servletPath = req.getServletPath();
//System.out.println(servletPath);
//2、去除 / 和 do, 得到类似于 edit 或 addCustomer 这样的字符串
String methodName = servletPath.substring(1);
methodName = methodName.substring(0,methodName.length()-3);
//System.out.println(methodName);
try {
//3、利用反射获取methodName 对应的方法
Method method = getClass().getDeclaredMethod(methodName,HttpServletRequest.class,HttpServletResponse.class);
//4、利用反射调用对应的方法
method.invoke(this,req,resp);
} catch (Exception e){
resp.sendRedirect("error.jsp");
}
}
//method.invoke(this,req,resp);是调用delete等方法
private void delete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String idStr = req.getParameter("id");
int id = 0;
//try-catch 作用防止id不能转化为整数;若不能,则id=0
try {
id = Integer.parseInt(idStr);
customerDAO.delete(id);
} catch (NumberFormatException e) {
e.printStackTrace();
}
resp.sendRedirect("query.do");
}
根据页面上name,address和phone来进行匹配,调用CustomerDAOpublic List
来实现
private void query(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 获取模糊查询的请求参数
String name = req.getParameter("name");
String address = req.getParameter("address");
String phone = req.getParameter("phone");
//封装成 CriteriaCustomer
CriteriaCustomer criteriaCustomer = new CriteriaCustomer(name,address,phone);
//1、调用CustomerDAO 的 getAll()方法 得到 Customer 的集合
//List customers = customerDAO.getAll();
List customers =customerDAO.getForListWithCriteriaCustomer(criteriaCustomer);
//2、把Customer 的集合放入request中
req.setAttribute("customers",customers);
//3、转发页面到 index.jsp(不能使用重定向)
req.getRequestDispatcher("/index.jsp").forward(req,resp);
}
上面的方法与普通的查询方法无异,下面才是我们实现模糊查询的重点
public List getForListWithCriteriaCustomer(CriteriaCustomer cc)在CustermDAOJdbcImpl实现类的实现
@Override
public List getForListWithCriteriaCustomer(CriteriaCustomer cc) {
String sql = "SELECT id,name,address,phone FROM customers where " +
" name like ? and address like ? and phone like ?";
//cc.getName()==null?"%%":"%"+cc.getName()+"%"
// 修改了CriteriaCustomer 的getter 方法:使其返回的字符串中含有 "%%"
//若返回值为 null 则返回 "%%" ,若不为 null 则返回 “%” + value + “%” ,value 位原来的值
return getForList(sql,cc.getName(),cc.getAddress(),cc.getPhone());
}
注意到上面的SQL语句:
String sql = "SELECT id,name,address,phone FROM customers where " +
" name like ? and address like ? and phone like ?";
采用了与的方法来匹配
而且采用了一个 CriteriaCustomer 类来把搜索的数据收集打包起来,CriteriaCustomer 类包括name、address和phone等私有成员,这些成员的setter方法为(以getName为例):
public String getName() {
if(name == null)
name = "%%";
else
name = "%" + name +"%";
return name;
}
为什么采取这样的setter方法呢?
这样是为了使得SQL语句中 ***%%***匹配(相似)方法得以实现。
在这一部分,由于佟刚老师的IDE是eclipse,而用的idea,在MVC工程中引入jQuery的方式不一样,导致我被坑了好久T_T
那么在idea工程中,在JSP中改如何引入jQuery呢?
最简单的添加方式就是,直接在JSP中写入:
然后,将鼠标光标放在这行代码上按下Alt+enter。具体可以看这个教程(传送门)。
不过,引入后可能还要到一个地方删除掉,这个要看到时候是否会报什么错误。
js+jQuery实现:“确定要删除 xx 的信息吗?”
方法①
方法②
至此,这个MVC小项目就结束啦!