每次写博客前总是喜欢写一段前言,这次的寒假答辩总结已经过去很久,我也迟迟没有去总结,如果不是组长的要求,我还不知道要拖到什么时候,这是一个不好的习惯。而对于这次的答辩,我也比较水,不上心吧,这是我的一个缺点,总是想说有时间好好做一下,可每次都是快到时间了,才去做,没有准备,没有提前了解,就直接随心所欲的去做,然后做的差不多了(其实很差),觉得“嗯,很麻烦,不想搞了,如果时间充足的话我要再做一遍”。可结果却是:你很害怕重新再来一遍,你不敢面对了,甚至不想再提起他,因为你会愧疚。这样真的很不好,这段时间状态都不是很好,或许,你真的可以从这个项目重新开始。 这次就好好总结细节,弄懂每一块知识,下周可以开展得更加顺利。 |
一、连接数据库,储存信息
1、创建数据库,创建好你要用的表,列名以及约束条件。
2、连接数据库,连接数据库里面有几个点我解释一下
private static String DRIVER = "com.mysql.cj.jdbc.Driver"; //DRIVER呢,就是一个驱动类
private static String USER = "root"; //USER呢就是登录用户名,比如说,你从cmd进入数据库输入的是:mysql -u root -p,那这个root就是你的登录用户名(我是这样理解的,或者也可以自定义,比如说你以sa登录,或者定义的其他登录名也可以)
private static String PASSWORD = "root"; //PASSWORD就是你的登录密码
private static String URL = "jdbc:mysql://localHost:3306/qmx?serverTimezone=GMT&&useSSL=false";
//URL就是驱动的地址,localHost:3306是服务器的地址,qmx是数据库名称,?号后面是参数,其中ServerTimezone=GMT是指定时区(北京时间东八区),否则会报错。
//SSL(Secure Socked Layer:安全套接字层)利用数据加密、身份验证和消息完整性验证机制,为基于TCP等可靠连接的应用层协议提供安全保证。而在连接数据库时,最好加上useSSL = true 或 false,否则会出现警告甚至错误。
OK,这只是我们定义的几个参数,下面才是我们真正要开始的链接部分:
public static Connection getConnection() throws CalssNotFountExption, SQLException{
Class.forName(DRIVER); //返回一个类,在这里就是返回驱动类,加载MySQL
System.out.println("测试数据库成功"); //进行测试
Connection connection = DriverManager.getConnection(URL,USER,PASSWORD);
//通过DriverManager中的getConnection(url,user,password)方法进行连接数据库
System.out.println("连接数据库成功"); //进行测试
return connection;
}
3、关闭数据库
如果不关闭数据库的话,那么这个连接将会一直被占用,直到连接池中的连接耗尽为止,
public static void closeConnection(Connection connection,PreparedStatement ps,ResultSet rs){
if(connection != null){
try { connection.close(); }
catch (SQLException e) { e.printStackTrace(); }
}
if(ps != null){
try { ps.close(); }
catch (SQLException e) { e.printStackTrace(); }
}
if(rs != null){
try { rs.close(); }
catch (SQLException e) { e.printStackTrace(); }
}
}
//简单解释一下PreparedStatement和ResultSet的含义,其实我也不太理解,PreparedStatement是用来执行SQL查询语句的API之一,ResultSet接口也是对数据库的查询操作,是处理查询结果集的。
好,数据库连接这一步基本完成,下面开始往里面储存信息
3、建立一个实体类,这个实体类里面主要就是你要存在你的数据库表里面的信息,并添加这些实体的get和set方法。
4、添加信息并保存。
(1)添加信息,这一块我看我写的以及其他人写的有三种写法,我就选一个我认为比较好的方法讲吧。
public void addStudent(studentEntity studentEntity) throws SQLException {
Jdbc jdbc = new Jdbc(); //Jdbc是对加载MySQL的//这种是直接在方法里就连接了数据库,而我写的一种是添加一个参数,然后在你调用这个方法之前再连接数据库,我觉得是先把数据库连接好了,后面就不用再次连接比较好
Connection connection = jdbc.getConnection(); //连接数据库
String sql = "insert into qmx(name,xuehao,xueyuan,zhuanye,qq,phone,sex,zubie) value(?,?,?,?,?,?,?,?)";
pst = connection.prepareStatement(sql); //加载sql语句
pst.setString(1, studentEntity.getName()); //setString()是给第几个数进行赋值
pst.setString(2, studentEntity.getXuehao());
pst.setString(3, studentEntity.getXueyuan());
pst.setString(4, studentEntity.getZhuanye());
pst.setString(5, studentEntity.getQq());
pst.setString(6, studentEntity.getPhone());
pst.setString(7, studentEntity.getSex());
pst.setString(8, studentEntity.getZubie());
pst.executeUpdate(); //对数据库执行的增删改操作
jdbc.closeConnection(); //关闭数据库
};
(2)然后就是Servlet层的信息获取
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//这两句是为了保证求情和响应的编码为utf-8
response.setCharacterEncoding("utf-8");
request.setCharacterEncoding("utf-8");
Users user = new Users();//request.getParameter("")是获取字段内容,其中""里面是你的input的name的名字
String name = request.getParameter("username");
String xuehao = request.getParameter("xuehao");
String xueyuan = request.getParameter("xueyuan");
String zhuanye = request.getParameter("zhuanye");
String qq = request.getParameter("qq");
String phone = request.getParameter("phone");
String sex = request.getParameter("sex");
String hobby = request.getParameter("hobby");//下面set就是向里面添加信息
user.setName(name);
user.setXuehao(xuehao);
user.setXueyuan(xueyuan);
user.setZhuanye(zhuanye);
user.setQq(qq);
user.setPhone(phone);
user.setSex(sex);
user.setHobby(hobby);
//下面就是调用addStudent()方法,向数据库中保存信息
UserDao dao = new UserDao();
String forward = null;
boolean flag = dao.addStudent(user);
if(flag){
forward = "/D_qmx/success.jsp"; //这个就是定义要跳转的页面
RequestDispatcher rd = request.getRequestDispatcher(forward); //请求转发
rd.forward(request, response);
}
}
至此,一个保存信息的也就写完了,它的跳转过程呢就是:从jsp页面 —— Servlet —— 调用service里面的方法 ——到DAO层连接数据库
有了前面的铺垫,下面增删改查应该会容易些吧。
二、管理员的登录
1、首先要查询输入的账号密码是否存在于表里面,返回的内容是输入的信息
public messages login(messages mess) { //messages就是管理员信息的实体类
Connection con=null;
PreparedStatement ps=null;
ResultSet rs=null;
try {
//1.获取数据库的连接
con = qmxDao.getConnection();
//2.书写sql语句
String sql="select * from message where 账号 = ? and 密码=?";
//3.预编译
ps=con.prepareStatement(sql);
//4.设置值
ps.setString(1, mess.getName());
ps.setString(2, mess.getPassword());
//5.执行sql语句
rs=ps.executeQuery();
messages messes=null;
if(rs.next()){
messes = new messages();
//从数据库中获取值到实体类的setter方法中
messes.setName(rs.getString("账号"));
messes.setPassword(rs.getString("密码"));
return mess;
}else{
return null;
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
2、Servlet层信息判断并进行页面跳转
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setCharacterEncoding("utf-8");
request.setCharacterEncoding("utf-8");
messages user= new messages();
//获取用户名和密码
String name = request.getParameter("zhanghao");
String password = request.getParameter("password");
//测试数据
//获取login.jsp页面提交的账号和密码设置到实体类中
user.setName(name);
user.setPassword(password);
//引入数据交互层,获取UserDao实例
UserDao dao = new UserDao();
messages us = dao.login(user);
// //测试返回的值
// System.out.println(us);
String forward = null;
// 判断user是否为空
if(us != null){
// 转发到success.jsp页面
forward = "/D_qmx/success.jsp";
RequestDispatcher rd = request.getRequestDispatcher(forward);
rd.forward(request, response);
}else{
// 登录失败
forward = "/D_qmx/error.jsp";
RequestDispatcher rd = request.getRequestDispatcher(forward);
rd.forward(request, response);
}
doGet(request, response);
}
三、管理员的查询功能
这一步是比较奇葩的一步,因为我把sql语句和jsp语句写在了一起,,,为了更好的说明,我把jsp页面的信息全粘了下来,查询的用黑体标了出来。
<body>
//sql:setDataSource是用于生成一个数据源,var是表示数据库的变量
<sql:setDataSource var="snapshot" driver="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/qmx?serverTimezone=GMT&&useSSL=false&&useUnicode=true"
user="root" password="root"/>//sql:query 是用于运行SQL select语句的,dataSource是用于连接数据库的,var是代表数据库的变量
<sql:query dataSource="${snapshot}" var="result">
SELECT * from qmx;
</sql:query>
<div class="container download">
<form class="header">
<input type="text" placeholder="按学号查询" id="a1">
<input type="button" id="a2" οnclick="myFunction()" value="查找">
<input type="button" id="a4" οnclick="cancel()" value="取消查找">
<input type="button" value="新增/隐藏" id="a3" οnclick="dis()">
</form>
<table id="b1">
<tr>
<th class="col-sm-1">姓名</th>
<th class="col-sm-1">学号</th>
<th class="col-sm-1">学院</th>
<th class="col-sm-1">专业</th>
<th class="col-sm-1">QQ号</th>
<th class="col-sm-1">联系方式</th>
<th class="col-sm-1">性别</th>
<th class="col-sm-1">选择组别</th>
<th class="col-sm-1">操作</th>
<th class="col-sm-1">操作</th>
</tr>//forEach循环中item是要进行迭代的集合,var是迭代参数的名称
//result.rows是返回查询结果集中行的数目
<c:forEach items="${result.rows }" var="l">
<tr>
<td><c:out value="${l.姓名}"/></td>
<td><c:out value="${l.学号}"/></td>
<td><c:out value="${l.学院}"/></td>
<td><c:out value="${l.专业}"/></td>
<td><c:out value="${l.qq号}"/></td>
<td><c:out value="${l.电话号码}"/></td>
<td><c:out value="${l.性别}"/></td>
<td><c:out value="${l.选择组别}"/></td>
<th>//注意这两个地方,因为用的是a标签跳转,所以跳转方式为doGet
<a href="Delete?学号=${l.学号}" οnclick="return window.confirm('确认删除吗?')">删除</a> //删除信息按钮
</th>
<td><a href="Update?序号=${l.id}">修改</a></td> //修改信息按钮
</tr>
</c:forEach>
</table>
<!-- 增加信息 -->
<form action="add" method="post">
<table id="add" style="display:none">
<caption style="font-size:26px;text-align: center;">添加信息</caption>
<tr>
<td>姓名:
<input type="text" id="name" name="username"/>
</td>
</tr>
<tr>
<td>学号:
<input type="text" id="iname" name="xuehao"/>
</td>
</tr>
<tr>
<td>学院:
<input type="text" id="name1" name="xueyuan"/>
</td>
</tr>
<tr>
<td>专业:
<input type="text" id="name2" name="zhuanye"/>
</td>
</tr>
<tr>
<td>qq号:
<input type="text" id="name3" name="qq"/>
</td>
</tr>
<tr>
<td>手机:
<input type="text" id="name4" name="phone"/>
</td>
</tr>
<tr>
<td>性别:
<input type="text" id="name5" name="sex"/>
</td>
</tr>
<tr>
<td>组别:
<input type="text" id="name6" name="hobby"/>
</td>
</tr>
<tr>
<td>
<input type="submit" value="添加此信息" οnclick="add()" class="abc" />
</td>
</tr>
</table>
</form>
<table>
</table>
</div>
</body>
四、管理员的删除功能
删除信息这一步就显得比较简单了,首先有一个delete的方法,然后在Servlet层获取信息,调用delete方法,进行信息的修改与保存。
public boolean deletes(Connection con,String xuehao) throws SQLException{
String sql = "delete from qmx where 学号 = ?";
PreparedStatement ps = con.prepareStatement(sql); //预编译
ps.setString(1, xuehao); //或许学号内容
if(ps.executeUpdate()>0)
return true;
return false;
}
这里的Servlet层用的就是gedoGt方法了
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setCharacterEncoding("utf-8");
request.setCharacterEncoding("utf-8");//PrintWriter 是以流的方式输出html,返回到浏览器上,也就是输出的意思
PrintWriter pw = response.getWriter();
Connection con = null;
String xuehao = request.getParameter("学号");
UserDao user = new UserDao();
try {
con = qmxDao.getConnection();
if(user.deletes(con, xuehao))
request.getRequestDispatcher("/D_qmx/success.jsp").forward(request, response);
else
pw.print(xuehao);
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
五、管理员的修改添加功能
修改功能,这一步呢,实现的就相对比较麻烦。因为刚开始我一直不知道要怎么获取Id,后来看到了可以传入参数,是在跳转时救火的了id,然后传进来,就可以了。
现在呢,根据id获取所有信息,然后跳转到要修改信息的一个页面。
public Users selects(Connection con,int id) throws SQLException{
String sql=("select * from qmx where id = ?");
Users stu = null;
PreparedStatement ps = con.prepareStatement(sql);
ps.setLong(1, id);
ResultSet rs = ps.executeQuery();
while(rs.next()){
stu = new Users();//这里下面获取的就是数据库里面的信息,所以getString里面就是数据库里面的列名
stu.setId(rs.getInt("id"));
stu.setName(rs.getString("姓名"));
stu.setXuehao(rs.getString("学号"));
stu.setXueyuan(rs.getString("学院"));
stu.setZhuanye(rs.getString("专业"));
stu.setQq(rs.getString("qq号"));
stu.setPhone(rs.getString("电话号码"));
stu.setSex(rs.getString("性别"));
stu.setHobby(rs.getString("选择组别"));
}
rs.close();
ps.close();
return stu;
}
Servlet层的doGet方法
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setCharacterEncoding("utf-8");
request.setCharacterEncoding("utf-8");
Connection con = null;
int id = Integer.valueOf(request.getParameter("序号")); //在jsp页面获取传过来的序号
UserDao sImpl = new UserDao();
try {
con = qmxDao.getConnection();
Users user = sImpl.selects(con, id); //这里就获取到了Id
request.setAttribute("user", user);
String forward = "/D_qmx/correct.jsp"; //跳转到修改页面
RequestDispatcher rd = request.getRequestDispatcher(forward);
rd.forward(request, response);
} catch (SQLException | ClassNotFoundException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
在修改页面进行修改信息,这里就是比较简单了,是和添加信息是一样一样的。
public boolean updates(Connection con,Users user) throws SQLException{
String sql = "update qmx set 姓名=?,学号=?,学院=?,专业=?,qq号=?,电话号码=?,性别=?,选择组别=? "
+ "where id = ?";
PreparedStatement ps=con.prepareStatement(sql);
ps.setString(1, user.getName());
ps.setString(2, user.getXuehao());
ps.setString(3, user.getXueyuan());
ps.setString(4, user.getZhuanye());
ps.setString(5, user.getQq());
ps.setString(6, user.getPhone());
ps.setString(7, user.getSex());
ps.setString(8, user.getHobby());
ps.setInt(9, user.getId());
if(ps.executeUpdate()>0)
return true;
else
return false;
}
Servlet层的doPost方法进行信息的获取与保存,与前面的添加信息也类似,首先获取input里面的信息,然后将信息添加到user中,再判断是否执行了SQL语句的更新,最后跳转到另一个页面。由此,管理员的信息修改功能也完成了。
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setCharacterEncoding("utf-8");
request.setCharacterEncoding("utf-8");
Connection con = null;
try {
con = qmxDao.getConnection();
} catch (ClassNotFoundException | SQLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
int id = Integer.valueOf(request.getParameter("id"));
String name = request.getParameter("username");
String xuehao = request.getParameter("xuehao");
String xueyuan = request.getParameter("xueyuan");
String zhuanye = request.getParameter("zhuanye");
String qq = request.getParameter("qq");
String phone = request.getParameter("phone");
String sex = request.getParameter("sex");
String hobby = request.getParameter("hobby");
Users user = new Users();
user.setId(id);
user.setName(new String(name.getBytes("UTF-8")));
user.setXuehao(new String(xuehao.getBytes("UTF-8")));
user.setXueyuan(new String(xueyuan.getBytes("UTF-8")));
user.setZhuanye(new String(zhuanye.getBytes("UTF-8")));
user.setQq(new String(qq.getBytes("UTF-8")));
user.setPhone(new String(phone.getBytes("UTF-8")));
user.setSex(new String(sex.getBytes("UTF-8")));
user.setHobby(new String(hobby.getBytes("UTF-8")));
UserDao dao = new UserDao();
String forward = null;
boolean flag;
try {
flag = dao.updates(con,user);
if(flag){
forward = "/D_qmx/success.jsp";
RequestDispatcher rd = request.getRequestDispatcher(forward);
rd.forward(request, response);
}
else{
forward = "/D_qmx/error.jsp";
RequestDispatcher rd = request.getRequestDispatcher(forward);
rd.forward(request, response);
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
管理员的添加信息功能是和学生报名信息的一样的,只是最后跳转的页面不一样,所以,我就略过啦。。。
六、学生的修改信息功能
学生的修改信息功能我也想了是好久啊,其实修改信息,不就是先获取,然后再进行修改保存嘛,你只要获取到信息,那修改保存不就和添加是一样的,不过是SQL语句不同,Servlet层大致都是一样的,可关键就是怎么获取得到这个信息。刚开始写好了管理员的信息修改,可以根据id来进行修改,可是在学生添加信息后,他如何能够获取id,然后将信息调出,根据id来修改呢,好吧,这个问题我想了很久也没有想到,因为学生页面我不知道如何获取id,然后就根据学号来进行修改,其中学号是不能修改的,为了安全,我在学生修改页面将学号去掉,只保留了其余能修改的信息。
这是这个页面的效果。
这样一来,学生修改信息的方法比管理员修改信息更加简单了。
学生修改信息的service层的stuUpdate方法和管理员的update方法类似(只是SQL语句不同),而在Servlet层,也是与添加信息的那部分一样一样的呢。
但是,后来我才发现,这一部分是有问题的,当你刷新这个部分的时候,会再次提交信息,也就是数据库中会再次保存信息,我怀疑是我数据库没有设置约束的问题,,,这个项目,我自己要完善的还有很多呀。
所以呢,我的寒假答辩总结也由此结束了吧,在做的时候没有好好总结,感觉每一个都好难,现在把每一部分都写出来才发现原来相似之处这么多,是我太懒了。
最后因为我的偷懒,我自己所做部分的分层及一些其他工作并没有完成,所以,我的分层是比较乱的,我只讲一下我所做的部分功能,期待我下一周完整项目的出炉。 |