简单使用三层架构完成学生管理系统之增加功能
先介绍三层架构有那些三层:第一层就是表示层、第二层就是业务逻辑层、第三层是数据访问层
再介绍三层所要负责的内容,并搭建框架:
1.表示层:需要负责两个地方,一个是前台,另一个是后台
(1)前台:使用JSP增加学生
创建JSP文件,取名为:add.jsp,效果如下:
(2)后台:使用Servlet,再将JSP所增加的数据提交给后台
创建包,包类名为:org.student.servlet,如下:
之后再包中创建Java文件,Java文件名为:servlet.java,专门处理将JSP中提交后台,效果如下:
2.业务逻辑层:将数据访问层进行组装
先创建包类,包名为:org.student.service,效果如下:
然后再创建Java文件,效果如下:
3.数据访问层:采用的是原子性的增删改查,只要是对数据库进行操作,就必须使用JDBC操作mysql数据库
创建包类,包名为:org.student.dao,如果如下:
包创建好以后,再创建Java文件,Java文件名为:studentDao.java,使用数据访问层中原子性的增删改查进行操作,并使用JDBC效果如下:
4.创建学生类:封装mysql数据库中表的字段,但名字可以不设置一样,这里只是为了servlet类方便的使用
(1)这里的所创建的包类名为:
(2) 再创建Java文件。这里的Java文件名为:student.java,这里就是对mysql数据库中表的所有字段进行封装,效果如下:
整体Java文件+所用到的包,还所创建的jsp文件等,展示:
第一步:在表示层中前台(add.jsp)下完成form表单,配置如下:
代码:
<form action="servlet" method="get"> 学号:<input type="text" name="id"><br> 姓名:<input type="text" name="name"/><br> 年龄:<input type="text" name="age"/><br> 地址:<input type="text" name="address"/><br> <input type="submit" value="新增">
效果:
注:(1)form表单中所设置的字段是根据mysql数据库中的字段来的(注:也不一定要把mysql数据库中表下的字段所有取出来,比如说:我只要姓名、年龄这个两个参数,也可以,并没有规定设置规定,反正看自己吧),后面设置的name值可以随便取,(2)在form表单中的action的用途是进行跳转到表示层下的后台中的doGet()方法下
第二步:根据表中的字段,建立实体类进行封装,这里字段名可以取别名来代替(注:在org.student.app包下的student.java中的Java文件里进行添加)
//这是封装类,进行封装mysql数据库中的所有字段,为了servlet类方便使用 package org.student.app; public class student { private int id; private String name; private int age; private String address; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } //构造方法 //无参 public student() { } //有参 public student(int id,String name,int age,String address) { this.id=id; this.name=name; this.age=age; this.address=address; } }
第三步:表示层(servlet.java)中的doGet()方法下进行获取JSP中表单所定义的字段
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //通过servlet来获取JSP中表单所定义的字段 //将字符串类型转化成int类型 int id=Integer.parseInt(request.getParameter("id")); String name=request.getParameter("name"); //将字符串类型转化成int类型 int age=Integer.parseInt(request.getParameter("age")); String address=request.getParameter("address"); //实例化student类 student stu=new student(id,name,age,address); }
第四步:数据访问层(studentDao.java)中使用JDBC来操作数据库的增删改查,注:这里采取原子性的增删改查
(1)先定义查询总,专门处理关于JDBC中的查询功能,这里方法名为“atomicity”
//这是三层中的数据访问层:原子性的增删改查 package org.student.dao; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import org.student.app.student; import com.sun.org.apache.regexp.internal.recompile; public class studentDao { //所要连接的数据库 String url="jdbc:mysql://localhost:3306/user"; String user="root"; String password="123"; //根据学号,查改具体的学生,所以返回值为student,而不是void,以下方法可以理解为查询总 public student atomicity(int id) { //调用学生类 student stu=null; //设置变量,要用的话,直接调用即可 Connection conn=null; PreparedStatement prepareStatement=null; ResultSet execut=null; //使用驱动 try { Class.forName("com.mysql.jdbc.Driver"); conn= DriverManager.getConnection(url,user,password); // sql语句,根据学号查询此人是否存在 String sql="select * from student where id=?"; prepareStatement = conn.prepareStatement(sql); prepareStatement.setInt(1, id); execut = prepareStatement.executeQuery(); //进行判断,有数据则显示,没有数据则返回null if(execut.next()) { //id int nid = execut.getInt("id"); //名称 String name = execut.getString("name"); //年龄 int age = execut.getInt("age"); //地址 String address = execut.getString("address"); //实例化对象 //这里可以说将学生信息封装到所定的stu变量中 stu=new student(nid,name,age,address); } //如果拿到了关于学生的信息,则返回出去 return stu; } catch (ClassNotFoundException e) { e.printStackTrace(); //如果没有拿到学生信息,则返回null; return null; } catch (SQLException e) { e.printStackTrace(); //如果没有拿到学生信息,则返回null; return null; } catch (Exception e) { e.printStackTrace(); //如果没有拿到学生信息,则返回null; return null; } finally { try { //释放资源 //这里的意思是:当execut不等于空时,才执行释放资源。以下都是这个意思 if(execut!=null)execut.close(); if(prepareStatement!=null)prepareStatement.close(); if(conn!=null)conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } }
(2)关于以上的查询功能的作用是拿整体的数据,而这里不取那么多的数据,在原有的数据上创建一个子查询调用查询总的方法,这里我取名为“isExit”,代码2如下:
//这是三层中的数据访问层:原子性的增删改查 package org.student.dao; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import org.student.app.student; import com.sun.org.apache.regexp.internal.recompile; public class studentDao { //所要连接的数据库 String url="jdbc:mysql://localhost:3306/user"; String user="root"; String password="123"; ···· //在使用数据访问层时,想要完成增加功能,就必须使用查询功能,以免发成冲突,所以以下就是定义子查询调用查询总 public boolean isExit(int id) throws Exception { //这是调用查询总方法 //解释以下的写法:下面也是进行判断, 如果拿到了学生信息,则返回true,没有拿到的话,则返回false return atomicity(id)==null? false:true; } ···· }
注:这里我想要的结果是向数据库中增加新的数据。所以需要先完成查询,再次增加。原因是:如果在添加数据时,发现此人已经存在的问题,则会增加失败,所以在添加数据时,先进行查询,如果此人没有存在,才进行添加,接下来完成增加功能
(3)完成增加功能,提醒:只要添加失败,都返回成false
//这是三层中的数据访问层:原子性的增删改查 package org.student.dao; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import org.student.app.student; import com.sun.org.apache.regexp.internal.recompile; public class studentDao { //所要连接的数据库 String url="jdbc:mysql://localhost:3306/user"; String user="root"; String password="123"; public boolean add(student stdent){ try { student stu=null; //使用驱动 Class.forName("com.mysql.jdbc.Driver"); Connection conn= DriverManager.getConnection(url,user,password); //sql语句,增加数据 String sql="insert into student(id,name,age,address) value(?,?,?,?)"; PreparedStatement prepareStatement = conn.prepareStatement(sql); prepareStatement.setInt(1, stdent.getId()); prepareStatement.setString(2,stdent.getName()); prepareStatement.setInt(3, stdent.getAge()); prepareStatement.setString (4, stdent.getAddress()); int cout=prepareStatement.executeUpdate(); //如果是大于0,则返回增加成功 if(cout>0) return true; else return false; } catch (ClassNotFoundException e) { return false; } catch (SQLException e) { return false; } catch (Exception e) { return false; } } }
第五步:在业务逻辑层(StudentService .py)中进行组装所写的数据访问层,接下来继续完成业务逻辑层
//业务逻辑层,逻辑性的增加,想要增加的话,先进行查询,如果此人不存在,再进行增加 package org.student.service; import org.student.app.student; import org.student.dao.studentDao; public class StudentService { studentDao stu=new studentDao(); public boolean add(student student) throws Exception { //判断此人存不存在 //查询此人存不存在,不存在的话,才进行增加 if(!stu.isExit(student.getId())) { stu.add(student);//这里进行增加 return true; }else { System.out.print("已存在"); return false; } } }
第六步:继续完善表示层(servlet.java)下的doGet()方法,这里是进行调用业务逻辑层(StudentServicce.java)
(1)完善的代码如下:
package org.student.servlet; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.student.app.student; import org.student.service.StudentService; public class servlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { ··· //进行调用 StudentService studentService = new StudentService(); try {boolean add = studentService.add(stu); PrintWriter out = response.getWriter(); if(add) { out.println("增加成功"); }else { out.println("增加失败"); } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } ··· }
(2)在运行项目时,直接在路径的后面添加add.jsp(add.jsp是我自己创建的jsp,根据自己的jsp来),因为目前只做了添加功能,所以直接进入添加页面,如果是其它的话,会出现500错误,先看怎么在路径后面添加
整体效果:
之后再依次填写表单中的信息,填写好以后,再点击新增按钮,然后会出现一个乱码,但是所填写好的信息已经存在数据库中效果如下:
查看数据库中所添加的数据,效果如下:
(3)出现了乱码,所以接下来解决乱码
注:在存到数据库中的数据是没有乱码出现,只是在页面中出现乱码,所以接下来需要设置响应式编码
在doGet()方法中进行设置,代码如下:
package org.student.servlet; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.student.app.student; import org.student.service.StudentService; public class servlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //通过servlet来获取JSP中表单所定义的字段 //将字符串类型转化成int类型 int id=Integer.parseInt(request.getParameter("id")); String name=request.getParameter("name"); //将字符串类型转化成int类型 int age=Integer.parseInt(request.getParameter("age")); String address=request.getParameter("address"); //实例化student类 student stu=new student(id,name,age,address); //进行调用 StudentService studentService = new StudentService(); try { //解决乱码,设置响应式编码 response.setContentType("text/html;charset=utf-8"); response.setCharacterEncoding("utf-8"); boolean add = studentService.add(stu); PrintWriter out = response.getWriter(); if(add) { out.println("增加成功"); }else { out.println("增加失败"); } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub doGet(request, response); } }
之后找到Servers文件下的server.xml,点击server.xml,再找到Connector标签,找到以后设置“utf-8”,效果如下:
最终再次运行项目,再添加数据,具体效果如下:
先填写信息
返回结果
查看数据是否存到数据库中