主要是用了开源的JDBC连接池c3p0+DBUtils+El+jstl里得taglib标签实现变量传输
三层结构+MVC模式
步骤
数据库准备
CREATE DATABASE stus;
USE stus;
CREATE TABLE stu (
sid INT PRIMARY KEY AUTO_INCREMENT,
sname VARCHAR (20),
gender VARCHAR (5),
phone VARCHAR (20),
birthday DATE,
hobby VARCHAR(50),
info VARCHAR(200)
);
查询
- 先写一个index 页面, 里面放一个超链接 。 (web层——view模式)
< a href="StudentListServlet"> 学生列表显示 </ a>
-
写Servlet, 接收请求, 去调用 Service , 由service去调用dao (web层——controll模式)
-
封装的学生对象 bean——(业务逻辑层——Model模式)
-
先写Dao , 做Dao实现——(业务逻辑层——Model模式)
Dao接口:查询所有学生
@return List
public interface StudentDao {
List<Student> findAll() throws SQLException ;
}
public class StudentDaoImpl implements StudentDao {
Dao实现: 查询所有学生
@throws SQLException
@Override
public List<Student> findAll() throws SQLException {
QueryRunner runner = new QueryRunner(JDBCUtil02.getDataSource());//DButils
return runner.query("select * from stu", new BeanListHandler<Student>(Student.class));
}
}
- 再Service , 做Service的实现。(业务逻辑层——Model模式)
学生的业务处理规范
查询所有学生
@return List
public interface StudentService {
List<Student> findAll() throws SQLException ;
}
学生业务实现
public class StudentServiceImpl implements StudentService{
@Override
public List<Student> findAll() throws SQLException {
StudentDao dao = new StudentDaoImpl();
return dao.findAll();
}
}
- 在servlet 存储数据,并且做出页面响应。(web层——controll模式)
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
try {
//1. 查询出来所有的学生
StudentService service = new StudentServiceImpl();
List<Student> list = service.findAll();
//2. 先把数据存储到作用域中
request.setAttribute("list", list); //注意四大作用域知识点
//3. 跳转页面
request.getRequestDispatcher("list.jsp").forward(request, response);
}
catch (SQLException e) {
e.printStackTrace();
}
}
-
在list.jsp上显示数据
EL + JSTL + 表格
El和jstl: 简化jsp页面中的java代码,增强jsp页面的功能
EL表达式:${“aa”}代替输出<%=request.getAttribute(“aa”)%>
jstl:apache出品的标签库语言
使用步骤:
1.导入jar包
2.在页面上引入标签库
<%@ taglib prefix=“c” uri=“http://java.sun.com/jsp/jstl/core” %>
forEach标签的高级使用 :在页面上遍历数组,单列集合和map
格式
<c:forEach items=“从域中通过el获取集合” var=“n”>
${n}
</c:forEach>
例子:
<c:forEach items="${list }" var="stu">
<tr align="center">
<td>${stu.sid }</td>
<td>${stu.sname }</td>
<td>${stu.gender }</td>
<td>${stu.phone }</td>
<td>${stu.birthday }</td>
<td>${stu.hobby }</td>
<td>${stu.info }</td>
</tr>
</c:forEach>
增加
-
先跳转到增加的页面 , 编写增加的页面 Add.jsp
-
点击添加,提交数据到AddServlet . 处理数据。
(1)获取客户端提交上来的数据|
爱好的value 值有多个,需要转换成字符串
request.getParameter("hobby");
String[] hobby = request.getParameterValues("hobby") ---> String[]
String value = Arrays.toString(hobby): // 爱好, 篮球, 足球 |
日期格式需要转换,String–Date
Date date= new SimpleDateFormat("yyyy-MM-dd").parse(birthday);
-
调用service,service调用dao,完成数据持久化, 添加到数据库
添加学生Service规范@param student 需要添加到数据库的学生对象
@throws SQLException
void insert(Student student) throws SQLException ;
添加学生Service实现
@Override
public void insert(Student student) throws SQLException {
StudentDao dao = new StudentDaoImpl();
dao.insert(student);
}
添加学生dao
@param student 需要添加到数据库的学生对象
@throws SQLException
void insert(Student student) throws SQLException ;
添加学生 dao实现
@Override
public void insert(Student student) throws SQLException {
QueryRunner runner = new QueryRunner(JDBCUtil02.getDataSource());
runner.update("insert into stu values(null , ?,?,?,?,?,?)" ,
student.getSname(),
student.getGender(),
student.getPhone(),
student.getHobby(),
student.getInfo(),
student.getBirthday()
);
}
添加到数据库
Student student = new Student(sname, gender, phone, hobby,info, date);
StudentService service = new StudentServiceImpl();
service.insert(student);
3 跳转到列表页
完成了这些存储工作后,需要跳转到列表页面。
如果直接跳转到list.jsp页面上, 那么这个页面会重新翻译一次,上面的那个request的请求存放的数据是没有了,没有什么内容显示。
request.getRequestDispatcher("list.jsp").forward(request, response); //没有什么内容显示。
应该先跳转到查询所有学生信息的那个Servlet, 由那个Servlet再去跳转到列表页面。
//servlet除了能跳jsp之外。 还能跳servlet
request.getRequestDispatcher("StudentListServlet").forward(request, response);
} catch (Exception e) {
e.printStackTrace();
}
删除
-
点击超链接,弹出一个询问是否删除的对话框,如果点击了确定,那么就真的删除。
<a href="#" onclick="doDelete(${stu.sid})">删除</a>
让超链接,执行一个js方法
<script type="text/javascript">
function doDelete(sid) {
/* 如果这里弹出的对话框,用户点击的是确定,就马上去请求Servlet。
如何知道用户点击的是确定。
如何在js的方法中请求servlet。 */
var flag = confirm("是否确定删除?");
if(flag){
//表明点了确定。 访问servlet。 在当前标签页上打开 超链接,
//window.location.href="DeleteServlet?sid="+sid;
location.href="DeleteServlet?sid="+sid;
}
}
</script>
-
在js访问里面判断点击的选项,然后跳转到servlet。
-
servlet收到了请求,然后去调用service , service去调用dao
更新
-
点击列表上的更新, 先跳转到一个EditServlet
在这个Servlet里面,先根据ID 去查询这个学生的所有信息出来。 -
跳转到更新的页面。 ,然后在页面上显示数据
<tr> <td>姓名</td> <td><input type="text" name="sname" value="${stu.sname }"></td> </tr> <tr> <td>性别</td> <td> <!-- 如果性别是男的, 可以在男的性别 input标签里面, 出现checked , 如果性别是男的, 可以在女的性别 input标签里面,出现checked --> <input type="radio" name="gender" value="男" <c:if test="${stu.gender == '男'}">checked</c:if>>男 <input type="radio" name="gender" value="女" <c:if test="${stu.gender == '女'}">checked</c:if>>女 </td> </tr> <tr> <td>爱好</td> <td> <!-- 爱好: 篮球 , 足球 , 看书 因为爱好有很多个, 里面存在包含的关系 --> <input type="checkbox" name="hobby" value="游泳" <c:if test="${fn:contains(stu.hobby,'游泳') }">checked</c:if>>游泳 <input type="checkbox" name="hobby" value="篮球" <c:if test="${fn:contains(stu.hobby,'篮球') }">checked</c:if>>篮球 <input type="checkbox" name="hobby" value="足球" <c:if test="${fn:contains(stu.hobby,'足球') }">checked</c:if>>足球 <input type="checkbox" name="hobby" value="看书" <c:if test="${fn:contains(stu.hobby,'看书') }">checked</c:if>>看书 <input type="checkbox" name="hobby" value="写字" <c:if test="${fn:contains(stu.hobby,'写字') }">checked</c:if>>写字 </td> </tr>
-
修改完毕后,提交数据到UpdateServlet
提交上来的数据是没有带id的,所以我们要手动创建一个隐藏的输入框, 在这里面给定id的值, 以便提交表单,带上id。
<form method="post" action="UpdateServlet">
<input type="hidden" name="sid" value="${stu.sid }">
</form>
- 获取数据,调用service, 调用dao.```
模糊查询
1.点击list.jsp页面上的姓名或性别 或者两者查询
<form action="SearchStudentServlet" method="post">
<table border="1" width="700">
<tr >
<td colspan="8">
按姓名查询:<input type="text" name="sname"/>
按性别查询:<select name="sgender">
<option value="">--请选择--
<option value="男">男
<option value="女">女
</select>
<input type="submit" value="查询">
</td>
</tr>
</table>
</form>
2.跳转到模糊查询的SearchStudentServlet,接收Name和Gender.
//模糊查找的时候,如果输入中文字符,未设置兼容语言,也无法查到数据
request.setCharacterEncoding("UTF-8");
//1. 取到了要查询的关键数据 姓名 , 性别。
String sname= request.getParameter("sname");
String sgender= request.getParameter("sgender");
3.调用service查找
//2. 找service去查询
StudentService service = new StudentServiceImpl();
List<Student> list = service.searchStudent(sname, sgender);
Service调用Dao实现:
public List<Student> searchStudent(String sname, String sgender) throws SQLException {
return new StudentDaoImpl().searchStudent(sname, sgender);
}
Dao实现:
/*
* 这里要分析一下:
* 如果只有姓名 ,select * from stu where sname like ? ;
* 如果只有性别 , select * from stu where gender = ?
*
* 如果两个都有 select * from stu where sname like ? and gender=?
*
* 如果两个都没有就查询所有。
*
*/
public List<Student> searchStudent(String sname, String sgender) throws SQLException {
QueryRunner runner = new QueryRunner(JDBCUtil02.getDataSource());
String sql = "select * from stu where 1=1 ";
List<String> list = new ArrayList<String> ();
//1,判断有没有姓名, 如果有,就组拼到sql语句里面
if(!TextUtils.isEmpty(sname)){
sql = sql + " and sname like ?";
//注意sql的where like的模糊查询用法 %代表零个或多个字符
list.add("%"+sname+"%");
}
//2,判断有没有性别,有的话,就组拼到sql语句里面。
if(!TextUtils.isEmpty(sgender)){
sql = sql + " and gender = ?";
list.add(sgender);
}
return runner.query(sql , new BeanListHandler<Student>(Student.class) ,list.toArray() );
}
4.将查找后的数据跳转到list.jsp显示
//3. 跳转界面。列表界面
request.getRequestDispatcher(“list.jsp”).forward(request, response);
问题
1.首先安装Mysql
遇到一直卡在"start service"的
直接关掉 在安装程序里打开就可以安装上了
2.安装Mysql数据库建模工具 workbench
提示You are running workbench on unsupport system.
我用的Mysql是5.1
下载的workbench是8.0 这个平台不支持5.1
所以下载了6.3的workbench就ok了
3.在用jdbc驱动mysql数据库时
没有把jdbc.properties拷贝在src下
拷贝到src之后就连接上了
4.在对数据库进行增加时,增加语句是没有按照数据里的字段名添加的,当各字段数据类型不同时,增加参数的顺序需要与数据库的字段顺序一致,否则会无法解析而报错。 (格式保持一致)
下图要保证getBirthday在数据库Date格式的字段里。
5.在对数据库进行更新时,由于需要核实每个字段所对应更新的内容,因此字段名与程序的sql语句参数不能有差别,负责无法更新
错误:
因为数据库里的phone 多了一个空号没发现 而导致无找到phone列 而出现异常