在之前已经写过了jdbc的工具类,不过最近学习了新的方法,所以在这里重新写一遍,为后面的javaEE做铺垫;

首先我们要了解javaEE项目中,文件构成,新建一个javaEE项目,在项目中,有一个web文件夹,在web文件夹下有WEB-INF文件夹,我们的web.xml文件放在这个文件夹下,同时我们要新建两个文件夹,一个是classes文件夹,一个lib文件夹;

classes文件夹:我们做出来的程序,都是先编译成class文件,然后再jvm中运行class文件,所以运行时,并不需要java‘文件,因此要把编译好的class文件放在classes文件夹下,然后直接将web文件夹放在tomcat的webapps文件夹下就可以运行了。

这里写一下怎样将class文件放入classes文件夹:

我们先建四个包:

然后以建一个student表:

我们一这个表为基础,来模拟一次业务;

首先在entity中创建student表的实例化对象类Student:

package com.zs.entity;
/**
* 创建实例化是对象类Student
* 生成get和set方法,
* 空参及带参构造方法
* tostring方法*/
public class Student {
// 1定义成员变量
private int id;
private String sname;
private int age; public Student() {
super();
} public Student(int id, String sname, int age) {
this.id = id;
this.sname = sname;
this.age = age;
} public int getId() {
return id;
} public void setId(int id) {
this.id = id;
} public String getSname() {
return sname;
} public void setSname(String sname) {
this.sname = sname;
} public int getAge() {
return age;
} public void setAge(int age) {
this.age = age;
} @Override
public String toString() {
return "Student{" +
"id=" + id +
", sname='" + sname + '\'' +
", age=" + age +
'}';
}
}

然后我们在util包创建jdbc的工具类:

package com.zs.util;

import com.alibaba.druid.pool.DruidDataSourceFactory;

import javax.sql.DataSource;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.*; /**
* 1.导jar包,需要用到druid-1.0.9.jar,
* mysql-connector-java-5.1.45-bin.jar,
* servlet-api.jar
* 需要用到阿里的连接池,所以需要配置文件,配置文件放在src文件夹下,配置文件的内容之前有介绍
*/ public class DBUtils {
private static DataSource ds;
// 1.创建静态代码块读druid.properites配置文件,创建链接池
static {
Properties p = new Properties();
InputStream in = DBUtils.class.getClassLoader().getResourceAsStream("druid.properties");
try {
p.load(in);
ds = DruidDataSourceFactory.createDataSource(p);
} catch (Exception e) {
e.printStackTrace();
}
} // 2.创建获得连接对象的静态方法
public static Connection getConnection() throws SQLException {
return ds.getConnection();
} // 3.创建增删改的方法,并返回布尔类型,使用可变参数来传递占位符的值
public static boolean executeUpdate(String sql,Object... args){
Connection conn = null;
PreparedStatement ps = null;
try {
conn= getConnection();
ps = conn.prepareStatement(sql);
// 通过for循环来给占位符赋值
for (int i = 0; i < args.length; i++) {
ps.setObject(i+1,args[i]);
}
// 执行sql语句
int i = ps.executeUpdate();
return i>0;
} catch (SQLException e) {
e.printStackTrace();
}finally {
close(conn,ps);
}
return false;
} // 创建查询的方法,并返回list集合
public static List<Map<String, Object>> executeQuery(String sql, Object... args) {
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
conn=getConnection();
ps = conn.prepareStatement(sql);
// 遍历可变数组传递占位符值
for (int i = 0; i < args.length; i++) {
ps.setObject(i+1,args[i]);
}
rs = ps.executeQuery();
List<Map<String,Object>> list=new ArrayList<>();
while (rs.next()) {
Map<String, Object> map = new LinkedHashMap<>();
/**这里可能会有问题,为什么是String,Object类型,因为我们通过rs.next只能获得一行结果,这一行结果,我们如果直接存入集合中的的化就是一个一个的值
* 我们无法识别哪儿个值是那儿一列的,所以用想到用map集合来装结果,key为列名,所以用String,因为一行中有多种数据类型,所以用obj来保存,用linkedHashMap
* 是因为map集合出来的结果是无序的,所以用linkedHashMap是有序的*/
// rs.getMetaData().getColumnCount();方法获得当前结果集的列数
for (int i = 0; i <rs.getMetaData().getColumnCount(); i++) {
// 通过列的索引获得列名,i+1是因为没有第0列,从第一列开始
String key = rs.getMetaData().getColumnLabel(i + 1);
// 通过键名来获得值
Object value = rs.getObject(key);
map.put(key, value);
}
list.add(map);
}
return list;
} catch (SQLException e) {
e.printStackTrace();
}finally {
close(conn,ps,rs);
}
return null;
}
// 创建关闭流的方法
private static void close(Connection conn) {
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
// 重载
private static void close(Connection conn, PreparedStatement ps) {
if (ps != null) {
try {
ps.close();
} catch (SQLException e) {
e.printStackTrace();
}finally {
close(conn);
}
}
}
// 重载
private static void close(Connection conn, PreparedStatement ps, ResultSet rs) {
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}finally {
close(conn,ps);
}
}
}
}

然后我们写dao层的类:

package com.zs.dao;

import com.zs.entity.Student;

import java.util.List;
import java.util.Map; /**我们首先在dao层下面创建接口,因为我们需要一个多态的特征,所以在接口中写抽象方法,方便后期的修改和维护
* 为什么要用多态,为了程序解耦,接触程序的耦合性,在创建后期修改时,如果我们要修改某一个方法,那就看可能会导致其他的方法不能运行,
* 程序之间的联系就是耦合性,就像藕断丝连,越是复杂的程序,之间的联系就越多,而多态就是为了解耦*/
public interface IStudentDAO {
/**
* 在这里我们传递的参数为Student 对象
* 为什么要用student对象?
* 因为在实际开发中,我们的表中的数据可能有很多列,我们不能把所有的列都当参数来传递,那样太麻烦了,而且不方便后期的修改和维护和,
* 比如说,我们突然要删除一列,那么我们就要找到所有于该方法有关的方法,删除参数列表中相应的参数,这样太麻烦了,传递对象,我们通过get方法来获得参数*/
boolean add(Student s);
boolean upd(Student s);
boolean del(int id);
List<Map<String,Object>> getStudentById(int id);
List<Map<String,Object>> getAllStudent(); }
package com.zs.dao.impl;
/**
* 在创建完接口后,我们在dao层的下面新建一个impl文件夹,用来存放接口的实现类*/
import com.zs.dao.IStudentDAO;
import com.zs.entity.Student;
import com.zs.util.DBUtils; import java.util.List;
import java.util.Map; public class StudentImpl implements IStudentDAO {
@Override
public boolean add(Student s) {
String sql="insert into student(sname,age) value (?,?)";
// 通过get方法来传递占位符的值
return DBUtils.executeUpdate(sql, s.getSname(), s.getAge());
} @Override
public boolean upd(Student s) {
String sql = "update student set sname=? ,age=? where id=?";
return DBUtils.executeUpdate(sql, s.getSname(), s.getAge(), s.getId());
} @Override
public boolean del(int id) {
String sql = "delete from student where id=?";
return DBUtils.executeUpdate(sql, id);
} @Override
public List<Map<String, Object>> getStudentById(int id) {
String sql = "select * from student where id=?";
return DBUtils.executeQuery(sql, id);
} @Override
public List<Map<String, Object>> getAllStudent() {
String sql = "select * from student";
return DBUtils.executeQuery(sql);
}
}

然后我们在servlet包中建测试类来测试工具类:

package com.zs.servlet;

import com.zs.dao.IStudentDAO;
import com.zs.dao.impl.StudentImpl;
import com.zs.entity.Student;
import com.zs.util.DBUtils;
import org.junit.Test; import java.util.List;
import java.util.Map; public class StudentServlet {
IStudentDAO is=new StudentImpl();
@Test
public void add(){
Student stu = new Student(1, "张三", 20);
// 这里这个 1 可能会有疑问,可以看一下dao层,我们插入语句中并没有用导id;写1是为了使用带参构造
boolean b = is.add(stu);
if (b) {
System.out.println("插入成功");
} else {
System.out.println("插入失败");
}
}
@Test
public void upd(){
Student stu = new Student(1, "张三", 20);
boolean b = is.upd(stu);
if (b) {
System.out.println("修改成功");
} else {
System.out.println("修改失败");
}
}
@Test
public void del(){
boolean b = is.del(1);
if (b) {
System.out.println("删除成功");
} else {
System.out.println("删除失败");
}
}
@Test
public void sel(){
List<Map<String, Object>> list = is.getStudentById(2);
if (list.size() > 0) {
System.out.println(list);
} else {
System.out.println("该学生不存在");
}
}
@Test
public void selAll(){
List<Map<String, Object>> list = is.getAllStudent();
System.out.println(list);
}
}

上面完成后,我们下面写一个页面,完成简单的表单验证,点击提交后,数据提交到后台,然后后台调用dao层,数据对比:

首先创建一个login表:

然后我们在dao层中创建ilogin接口:

package com.zs.dao;

public interface ILoginDAO {
boolean login(String username, String password);
}

然后在impl文件夹中创建实现类:

package com.zs.dao.impl;

import com.zs.dao.ILoginDAO;
import com.zs.util.DBUtils; import java.util.List;
import java.util.Map; public class LoginImpl implements ILoginDAO { @Override
public boolean login(String username, String password) {
String sql = "select * from login where sname=? and pwd=?";
List<Map<String, Object>> list = DBUtils.executeQuery(sql, username, password);
return list.size()>0;
}
}

然后我们写一个简单的html页面,html页面放在web文件夹下;

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登录界面</title>
</head>
<body>
<form action="/zs/login" method="post">
<input type="text" name="username" placeholder="请输入用户名"><br>
<input type="password" name="password" placeholder="请输入密码"><br>
<input type="submit" value="登录">
</form>
</body>
</html>

下面写登陆的后台Servlet:

package com.zs.servlet;

import com.zs.dao.ILoginDAO;
import com.zs.dao.impl.LoginImpl; import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException; @WebServlet(name = "LoginServlet")
public class LoginServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 将请求的数据转为utf-8的格式,没有这句话的话,会出现登录中文用户名失败
request.setCharacterEncoding("utf-8");
String username = request.getParameter("username");
String password = request.getParameter("password");
ILoginDAO lo=new LoginImpl();
boolean b = lo.login(username, password);
if (b) {
System.out.println("登录成功");
// 成功跳转页面方法与下面一样,这里没有写可以跳转的页面
} else {
System.out.println("登陆失败");
// 失败返回登录页面
response.sendRedirect("Login.html");
}
} protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request,response);
}
}

配置tomcat的方法再之前写过,然后直接启动tomcat就好了

jdbc工具类的封装,以及表单验证数据提交后台的更多相关文章

  1. jQuery封装的表单验证,模仿网易或者腾讯登录的风格

    模仿网易邮箱做了一个登录表单验证,不太好,请指教 上代码 <form action="" name="" id="form1"> ...

  2. spring+thymeleaf实现表单验证数据双向绑定

    前言 这个教程介绍了Thymeleaf与Spring框架的集成,特别是SpringMvc框架. 注意Thymeleaf支持同Spring框架的3.和4.版本的集成,但是这两个版本的支持是封装在thym ...

  3. Vue Element-ui 框架:路由设置 限制文件类型 表单验证 回车提交 注意事项 监听事件

    1.验证上传文件的类型: (1)验证图片类型 <template> <el-upload class="avatar-uploader" action=" ...

  4. js基础-表单验证和提交

    基础知识: 原始提交如下: <form action="/login" method="post" id="form1"> &l ...

  5. ng表单验证,提交以后才显示错误

    只在提交表单后显示错误信息 有时候不想在用户正在输入的时候显示错误信息. 当前错误信息会在用户输入表单时立即显示. 由于Angular很棒的数据绑定特性,这是可以发生的. 因为所有的事务都可以在一瞬间 ...

  6. JDBC工具类—如何封装JDBC

    “获得数据库连接”操作,将在以后的增删改查所有功能中都存在,可以封装工具类JDBCUtils.提供获取连接对象的方法,从而达到代码的重复利用. 该工具类提供方法:public static Conne ...

  7. SpringMVC之ajax与表单 Post 数据提交差异小结

    最近在写一个富文本框的后台数据服务的时候遇到一些关于 ajax 提交与 表单提交的比较特殊的案例,这里拿来跟大家分享,希望能让大家有所启发. 1. 首先是常见表单提交在SpringMVC的控制器中的代 ...

  8. 【Codebase】JQuery获取表单部分数据提交方法

    JQuery使用ajax提交整个表单最简便的方法就是$('#form').serialize();但如果仅想保存表单中的部分数据,比如仅更新选中的条目,那么获取数据就比较麻烦了. 解决方法:新建一个表 ...

  9. layui 自定义表单验证 以及提交表单

    订购数量</span> <span style="color: red">*</span>: <input type="text ...

随机推荐

  1. React文档(十八)最佳性能

    在内部,React使用好几种聪明的技巧去最小化更新UI所需要的DOM操作.对于很多应用来说,使用React会使得构建用户界面非常之快而且不需要做太多专门的性能优化.虽然如此,还是有一些方法可以让你为R ...

  2. VSCode 启动 Vue 项目 npm install 报错

    1.  报错后,查看了版本. 查看node版本:node -v 查看npm版本:npm -v 查看Augular版本:ng --version 2.  感觉 Augular CLI版本太低,使用以下方 ...

  3. swig模板引擎汇总

    1. Express中使用swig模板引擎 2.Swig 使用指南 3.jade to html online

  4. VMware下Debian开发环境部署之常见问题记录

    本文讲介绍windows作为宿主机,linux虚拟机作为编译环境的开发环境搭建中最常用到的三个问题,详细描述了解决过程. 目录: 1.网路配置: 2.分辨率设置: 3.共享网盘设置: 1.网络设置,V ...

  5. 我的第一个Angular2应用

    1需要具备的基本前端基础:HTML.CSS.JavaScript.为了实现对项目包的管理,推荐使用npm NPM是随同NodeJS一起安装的包管理工具,能解决NodeJS代码部署上的很多问题:官网先下 ...

  6. websocket session共享

    单机运行 用户a通过服务器进入房间room,用户b也通过房间进入room,用户之间是通过session来通话的,所以session直接存储在集合中就可以了. 因为session存储在一台服务器的集合中 ...

  7. Python中类的__init__继承

    Python中类的__init__继承 概念: 定义父类 In [10]: class Person: ....: def __init__(self,name,age,sex): ....: sel ...

  8. 'weinre' 不是内部或外部命令,也不是可运行的程序 或批处理文件。 解决方案

    使用 npm install -g weinre 全局安装 weinre,weinre 安装目录是:C:\Users\Administrator\AppData\Roaming\npm 需要配置环境变 ...

  9. Oracle数据库字段数据拆分成多行(REGEXP_SUBSTR函数)

    做多选功能时为了简便,会在某个字段中存储多个值,保存时虽然省事,但后续的查询统计时还需要拆分数据才行,因此这时需要将字段内的值分成多行以便后续使用. 下面这个例子实现了字段内数据的拆分: --创建测试 ...

  10. 较为复杂的实现Parcelable的子类--推荐Android中使用

    2017-08-14 21:23:34 一个较为复杂的Parcelable实现类 public class CommentShareBean implements Parcelable { /** * ...