[TOC]

0x00 前言基础

什么是JDBC驱动?
答:数据库连接JAVA Database Connectivity java

为什么会出现JDBC?
SUN公司提供的一种数据库访问规则、规范, 由于数据库种类较多,并且java语言使用比较广泛,sun公司就提供了一种规范,让其他的数据库提供商去实现底层的访问规则。 我们的java程序只要使用sun公司提供的jdbc驱动即可。


驱动下载和使用

描述:在利用JAVA的JDBC连接到MySQL或者其它数据库的时候,需要加载其jar包到工程的lib库中;

方式1:JDBC驱动包

MySQL8.x的JDBC驱动包下载页面: https://dev.mysql.com/downloads/connector/j/8.0.html

WeiyiGeek.官网下载JDBC

MySQL JDBC API:https://dev.mysql.com/doc/connector-j/8.0/en/connector-j-reference-implementation-notes.html

JAVA连接数据库的JDBC驱动关于MySQL5.x和MySQL8.X版本:
描述:MySQL 8.0 开始数据库相比常用的 5.X 版本发生了比较大的变化,我们在采用JDBC连接数据库的过程中也相应的发生变化比如驱动包版本,驱动名称等等;
直接下载地址:https://dev.mysql.com/downloads/file/?id=477058

  • 1.MySQL 版本和 mysql-connector-java 版本对应关系如下:
    | Connector/J version | Driver Type | JDBC version | MySQL Server version | Status |
    | ——————- | ———– | —————— | ——————– | —————————————– |
    | 5.1 | 4 | 3.0, 4.0, 4.1, 4.2 | 5.6, 5.7, 8.0* | General availability |
    | 8.0 | 4 | 4.2 | 5.6, 5.7, 8.0 | General availability. Recommended version |

  • 2.将 com.mysql.jdbc.Driver 更换为 com.mysql.cj.jdbc.Driver;

  • 3.MySQL 8.0 以上版本不需要建立 SSL 连接的,需要显式关闭useSSL=false,由于 MySQL 5.7 之前版本安全性做的并不够好,比如安装时生成的root空密码账号、存在任何用户都能连接上的 test 库等,导致数据库存在较大的安全隐患,所以MySQL从5.7版本开始加强安全性问题的修复到了 MySQL 8.0 以上版本已经不需要使用 SSL 进行连接加密了,但是任然保留这个接口;

  • 4.设置 CST 时区: serverTimezone=UTC,否则会启动报错

    Caused by: com.mysql.cj.exceptions.InvalidConnectionAttributeException: The server time zone value '�й���׼ʱ��' is unrecognized or represents more than one time zone. You must configure either the server or JDBC driver (via the serverTimezone configuration property) to use a more specifc time zone value if you want to utilize time zone support.

MySQL8.X的JDBC驱动连接案例:

Class.forName("com.mysql.cj.jdbc.Driver");
conn=DriverManager.getConnection("jdbc:mysql://localhost:3306/test_demo?useSSL=false&serverTimezone=UTC","root","password");


方式2:maven依赖下载

采用maven搜索网站:https://mvnrepository.com/ ,搜寻可用的配置;

<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.16</version>
</dependency>


工程加载Lib

新建立一个Eclipse工程并且创建一个lib目录,将下载的jar包复制到其中;右键点击jar包选择 Build Path -> Add to Bulid Path;

WeiyiGeek.Build Path


0x01 基础使用

描述:JDBC基本步骤流程:

  • 1.注册驱动
  • 2.建立链接
  • 3.创建statement
  • 4.构建并执行SQL
  • 5.获取结果集ResultSet
  • 6.遍历结果集
  • 7.释放资源


基础实例:

package com.weiyi.Jdbc;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import com.mysql.cj.jdbc.result.ResultSetMetaData;

public class Demo1 {
4@SuppressWarnings("unused")
4public static void main(String[] args) throws SQLException {
44
44//JDB连接标准文档
44Connection conn = null;
44Statement st = null;
44ResultSet rs = null;
44try {
444//Step 1.驱动注册(实际上不建议采用此类方法加载驱动-他会注册两次)
444DriverManager.registerDriver(new com.mysql.cj.jdbc.Driver());
444
444//Step 2.构建连接字符串和建立链接
444String urlFormat = "jdbc:mysql://%s:%d/%s?useUnicode=true&characterEncoding=UTF-8";
444String connectionUrl = String.format(urlFormat, "113.xx.xx.xxx", 3306, "Demo");
444conn = DriverManager.getConnection(connectionUrl, "root", "WeiyiGeek");
444
444//Step 3.创建statement
444st = conn.createStatement();
444
44
444//Step 4.构建SQL语句以及执行语句
444String sql = "SELECT ID AS '序号',LastName AS '名称' FROM Persons WHERE ID <> 102";
444rs = st.executeQuery(sql);
444
444//Step 5.遍历数据库
444while(rs.next()){
4444//System.out.println("ID: " + rs.getInt("ID") + " , LastName = " + rs.getString("LastName")); //注意此处使用别名的时候(不能采用字段名进行获取数据库返回的值);
4444System.out.println("ID: " + rs.getInt("序号") + " , LastName = " + rs.getString("名称"));
444}
444
444//Step 6.获取元数据metadate
444ResultSetMetaData rsmd = (ResultSetMetaData) rs.getMetaData();
444int numCols = rsmd.getColumnCount(); //获取列元素数据量
444int count = 1;
444while(count <= numCols) {
4444System.out.printf("第 %d 列: 列名: %s , AS别名: %s , 类型:%s \n",count, rsmd.getColumnName(count), rsmd.getColumnLabel(count), rsmd.getColumnType(count));
4444count++;
444}
44
44} catch (SQLException sqlEx) {
444// TODO: handle exception
444sqlEx.printStackTrace();
44} finally {
444//Step 7.释放资源(非常重要) - 从后往前
444System.out.println("Start-释放资源中");
444//结果集对象
444try {
4444if(rs != null)
44444rs.close();
444} catch (SQLException e) {
4444e.printStackTrace();
444} finally {
4444rs = null;
444}
444
444//statement对象
444try {
4444if(st != null)
44444st.close();
444} catch (SQLException e) {
4444e.printStackTrace();
444} finally {
4444st = null;
444}
444
444//数据库连接对象
444try {
4444if(conn != null)
44444conn.close();
444} catch (SQLException e) {
4444e.printStackTrace();
444} finally {
4444conn = null;
444}
444System.out.println("Successful-资源释放完成!");

444//当然您也可以采用自己封装后的JDBC工具类(非常注意释放的顺序)
444//JDBCUtil.release(conn,st,rs);
44}
4}
}

执行结果:

ID: 100 , LastName = WeiyiGeek
ID: 101 , LastName = Admin
ID: 103 , LastName = Weiyi
ID: 104 , LastName = Young
ID: 105 , LastName = bb204949-3283-11ea-b468-0242ac120002
第 1 列: 列名: ID , AS别名: 序号 , 类型:4
第 2 列: 列名: LastName , AS别名: 名称 , 类型:12
Start-释放资源中
Successful-资源释放完成!


自定义工具包类

补充:JDBC连接MySQL工具包类

  • 1.释放资源的工具类
  • 2.驱动防二次注册,因为Driver类里面有静态代码块,一上来就执行了所以等同于我们注册了两次驱动;
  • 3.构JDBC工具类的构造方法设置连接信息
//该包下的类可以通过静态类 类.方法()进行调用
//该包下的类可以通过静态类 类.方法()进行调用
package com.weiyi.Jdbc;

import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

public class JDBCUtil {
4static String connUrl = "jdbc:mysql://%s:%d/%s?useUnicode=true&characterEncoding=UTF-8";
4static String connIp = "13.62.17.23";
4static int connPort = 9301;
4static String conndatabase = "Demo";
4static String driverClass = null; //使用的时候添加
4static String url = null;
4static String user = null;
4static String pass = null;
4
4//静态代码块,加载类的时候执行
4static {
44try {
444//Step1.创建一个属性配置对象
444Properties prop = new Properties();
44
444//Step2.打开配置文件
444//InputStream ins = new FileInputStream("jdbc.properties");
444InputStream ins = Demo3.class.getClassLoader().getResourceAsStream("jdbc.properties");

444//Step3.导入输入流
444prop.load(ins);
44
444//Step4.属性读取
444driverClass = prop.getProperty("jdbc.driverClassName");
444url = String.format(prop.getProperty("jdbc.url"),connIp,connPort,conndatabase);
444user = prop.getProperty("jdbc.username");
444pass = prop.getProperty("jdbc.password");
44} catch (Exception e) {
444// TODO Auto-generated catch block
444e.printStackTrace();
44} finally {
444System.out.println("Properties配置已经加载!");
44}
4}
4
4public JDBCUtil() {
44super();
44// TODO Auto-generated constructor stub
4}
4public JDBCUtil(String ip,int port,String database) {
44connIp = ip;
44connPort = port;
44conndatabase = database;
4}

4//注册工具方法
4/**
* 驱动注册和建立链接
* @param user
* @param password
* @return Connection
* @throws SQLException
*/
4public static Connection getConn() throws SQLException {
44Connection conn = null;
44System.out.println("连接字符串:" + url);
44try {
444//防止驱动二次注册自动注册驱动与建立连接
444conn = DriverManager.getConnection(url, user, pass);
44} catch (SQLException e) {
444e.printStackTrace();
44}
44return conn;
4}
4
4
4/**
* 释放工具类
* @param conn
* @param st
* @param rs
*/
4
4// 注意点:导包需要查看是哪一个包的返回值
4public static void release(Connection conn, Statement st, ResultSet rs) {
44//注意点:关闭的顺序
44closeRs(rs);
44closeSt(st);
44closeConn(conn);
44System.out.println("END-资源释放完成!");
4}

4//私有静态方法-释放查询结果集
4private static void closeRs(ResultSet rs) {
44try {
444if(rs != null)
4444rs.close();
44} catch (SQLException e) {
444e.printStackTrace();
44} finally {
444rs = null;
44}
4}
4
4//私有静态方法-释放statement对象
4private static void closeSt(Statement st) {
44try {
444if(st != null)
4444st.close();
44} catch (SQLException e) {
444e.printStackTrace();
44} finally {
444st = null;
44}
4}
4
4//私有静态方法-
4private static void closeConn(Connection conn) {
44try {
444if(conn != null)
4444conn.close();
44} catch (SQLException e) {
444e.printStackTrace();
44} finally {
444conn = null;
44}
4}
}

注意事项:

  • 注:在实际使用中我们可以不用Class.forName()加载驱动了,在DriverManager.getConenect()方法中,在JDBC4.0版本后会在导入的数据库驱动包的Meta-INF中services里的java.sql.Driver驱动名称;
  • 注:在需要连接多个数据库的时候,为了区分最好是写上驱动名称当然不写也是可以的;

WeiyiGeek.Class.forName


配置文件导入

描述:我们采用properties配置文件进行导入jdbc的驱动名称以及连接字符串和账号密码等等;

比如:在工程src目录下声明一个config.properties文件(如果是使用框架的时候一般会存放在WEB-INF里面):

driverClass=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/student??useUnicode=true&characterEncoding=UTF-8
name=root
password=root

补充说明:

//使用类加载器去读取src底下的资源文件后面在servlet  
//对应文件位于src目录底下在编译打包后存在在bin目录同层中,使用getClassLoader()在加载字节码文件时候顺便也加载了我们制定的资源文件
//InputStream is = JDBCUtil.class.getClassLoader().getResourceAsStream("jdbc.properties");

MySQL数据库的CRUD表述:

  • 1.Create
  • 2.Retrieve 读取
  • 3.Update
  • 4.Delete

MySQL的JDBC库执行SQL方法分类:

  • executeQuery(String sql)
  • executeUpdate(String sql) : 主要针对于DML的语句如insert,update,delete语句,并且返回影响的行数;

基础实例:

package com.weiyi.Jdbc;

import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Properties;

import com.mysql.cj.jdbc.result.ResultSetMetaData;

import javafx.scene.control.SplitPane.Divider;

public class Demo3 {
4/**
* JDBC 连接参数采用 Properties配置文件进行导入
* @param args
*/
4 //使用静态代码块读取属性(当类加载的时候执行)
4static String driverClass = null;
4static String url = null;
4static String user = null;
4static String pass = null;
4
4static {
44try {
444//Step1.创建一个属性配置对象
444Properties prop = new Properties();
44
444//Step2.打开配置文件
444//InputStream ins = new FileInputStream("jdbc.properties"); //在根目录中可以采用这种方式
444InputStream ins = Demo3.class.getClassLoader().getResourceAsStream("jdbc.properties");

444//Step3.导入输入流
444prop.load(ins);
44
444//Step4.属性读取
444driverClass = prop.getProperty("jdbc.driverClassName");
444url = prop.getProperty("jdbc.url");
444user = prop.getProperty("jdbc.username");
444pass = prop.getProperty("jdbc.password");
44} catch (Exception e) {
444// TODO Auto-generated catch block
444e.printStackTrace();
44} finally {
444System.out.println("- #ProPerties配置文件读取完成!");
44}
44
4}
4
4public static void main(String[] args) {
44//JDB连接标准文档
44Connection conn = null;
44Statement st = null;
44ResultSet rs = null;
44
44try {
444//1.驱动注册
444Class.forName(driverClass); //实际上这句话都可以免了在JDBC4.0之后他会自动在jdbc的数据库驱动jar包中元数据进行查看
444//2.建立连接
444conn = DriverManager.getConnection(url, user, pass);
444//3.建立statement对象
444st = conn.createStatement();
444//4.构建SQL语句并且执行
444rs = st.executeQuery("SELECT * FROM Persons WHERE (ID = 100)"); //Retrieve
444//5.获取数据
444ResultSetMetaData rsmd = (ResultSetMetaData) rs.getMetaData(); //获取源数据
444int len = rsmd.getColumnCount(); //字段梳理
444int count = 1;
444while(count <= len) {
4444System.out.print(rsmd.getColumnName(count) + " | ");
4444count++;
444}
444System.out.println("");
444while (rs.next()) {
4444System.out.println(rs.getInt("ID") + "| " + rs.getString("LastName"));
444}
444
444//6.数据库的CRUD;
444String sql = "INSERT INTO Persons VALUE (NULL,'Weiyi')"; //主要Primary Key 插入主键的时候可以用null代替
444int result = st.executeUpdate(sql); //该方法主要执行 INSERT, UPDATE or DELETE 等语句,返回影响的行数
444//如果返回值大于0则表明操作成功,否则失败;
444if(result > 0) {
4444System.out.println("插入成功 : "+ sql);
444}else {
4444System.out.println("插入失败");
444}
444
444// U :
444String sqlUpdate = "UPDATE Persons SET LastName = 'Whoami' WHERE ID = 100";
444result = st.executeUpdate(sqlUpdate);
444if(result > 0) {
4444System.out.println("更新成功 : " + sqlUpdate);
444}else {
4444System.out.println("更新失败");
444}
4444
444// D:
444String sqlDelete = "DELETE FROM Persons WHERE LastName = 'Weiyi'";
444result = st.executeUpdate(sqlDelete);
444if( result > 0) {
4444System.out.println("删除成功 : " + sqlDelete);
444}else {
4444System.out.println("删除失败");
444}
44444
44} catch (SQLException e) {
444// TODO: handle exception
44} finally {
444//End.释放资源
444JDBCUtil.release(conn, st, rs);
44}
4}
}

执行结果:

- #ProPerties配置文件读取完成!
查询成功 : SELECT * FROM Persons WHERE (ID = 100)
ID | LastName |
100| Whoami
插入成功 : INSERT INTO Persons VALUE (NULL,'Weiyi')
更新成功 : UPDATE Persons SET LastName = 'Whoami' WHERE ID = 100
删除成功 : DELETE FROM Persons WHERE LastName = 'Weiyi'
读取完成
END-资源释放完成!


junit 单元测试

描述:在写代码的时候我们常常需要对所写的代码进行测试,如果直接在别人开发code的包下测试是比较混乱,建议将里面的方法进行抽取到测试包里,然后采用junit框架进行测试;

操作步骤:

  • 1.创建一个测试包依赖包org.junit.Test,定义一个类Testxxx然后在里面定义需要测试的方法,它还可建立多个方法进行测试;
  • 2.添加junit框架的支持及引入jar包:工程右键 - build path - add Library - Junit - Junit4;
  • 3.在需要测试的方法上面加入注解标记 @Test
  • 4.光标选择所需要测试的方法名称然后右键执行单元测试或者是打开outline视图,然后选择方法右键采用junit执行;

WeiyiGeek.junit

基础实例:

package com.weiyi.Test;

import java.util.Date;
import org.junit.Test;

/**
* 使用junit进行单元测试
* @author WeiyiGeek
*/
public class MainTest {
4
4//单元测试需要测试的方法
4@Test
4public void testPrint() {
44Date date = new Date();
44System.out.println("当前时间:" + date.toGMTString());
4}
}

WeiyiGeek.jUnit单元测试


Dao 开发模式

描述:Data Access Object 数据访问对象.即使用包类对象实现一个功能;

模式建立流程;

  • 1.建立一个dao的接口,里面声明数据库访问规则;
  • 2.新建一个dao的实现类,具体实现早前定义的规则;
  • 3.建立一个调用dao接口中的方法进行展示实现类的运行结果;
-- (1) 建立一个测试的表
CREATE TABLE user_log (
id INT NOT NULL PRIMARY KEY AUTO_INCREMENT COMMENT '序号',
userLogin VARCHAR(255) NOT NULL COMMENT '登陆名称',
4userPass VARCHAR(255) NOT NULL COMMENT '登陆密码',
loginTime DATETIME NOT NULL DEFAULT NOW() COMMENT '登陆时间'
);

-- (2) 数据插入
INSERT INTO user_log(id,userLogin) VALUES (NULL,'WeiyiGeek');

WeiyiGeek.

基础示例:

// 1.接口
package com.weiyi.dao;
public interface userDao {
4/**
* Dao模型-接口定义操作数据库的方法
*/
4void findAll();
}


// 2.实现接口
package com.weiyi.dao.impl;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import com.weiyi.Jdbc.JDBCUtil;
import com.weiyi.dao.userDao;
public class userDaoImpl implements userDao{
4//JDBC连接标准文档
4Connection conn = null;
4Statement st = null;
4ResultSet rs = null;
4
4@Override
4public void findAll() {
44try {
444//1.驱动加载和建立链接
444conn = JDBCUtil.getConn();
444//2.建立流对象statement
444st = conn.createStatement();
444//3.构建执行SQL语句 (这里的SQL语句是拼接的容易导致安全问题)
444rs = st.executeQuery("SELECT * FROM user_log");
444while(rs.next()){
4444System.out.println(rs.getInt("id") + " " + rs.getString("userLogin") + " " + rs.getDate("loginTime"));
444}
44} catch (Exception e) {
444// TODO Auto-generated catch block
444e.printStackTrace();
44} finally {
444JDBCUtil.release(conn, st, rs);
44}
4}
}


// 3.调用接口
package com.weiyi.Jdbc;
import com.weiyi.dao.userDao;
import com.weiyi.dao.impl.userDaoImpl;
/**
* 调用 dao 模型 实现的接口方法
* @author WeiyiGeek
*/
public class Demo4 {
4//注意:这里测试也可以采用Junit单元测试
4public static void main(String[] args) {
44//Step1.父类指向子类实现的接口
44userDao dao = new userDaoImpl();
44//Step2.直接调用其方法不用管具体的实现
44dao.findAll();
4}
}

运行结果:

Properties配置已经加载!
连接字符串:jdbc:mysql://11.62.17.20:3001/Demo?useUnicode=true&characterEncoding=UTF-8
1 WeiyiGeek 2020-01-14
END-资源释放完成!


0x02 JDBC安全开发

描述:做过渗透测试的人员和经验丰富的开发人员一定是知道对于数据库读取、插入数据的业务常常容易被SQL Inject,所以为了解决这一个安全问题常常采用占位绑定进行防止SQL注入,类似于PHP的PDO扩展类库中的PDO预处理语句;

注意:Statement 对象的安全问题;

  • 1.Statement对象执行SQL语句其实是将SQL语句先拼接再执行;
  • 2.比如下面的实例进行拼接了SQL语句,先拼接SQL语句然后再一起执行;但是如果变量中带有数据库的关键字,那么在进行查询的时候将会被认为是数据库查询的关键字,从而引发安全问题;
    -- 在Statement对象中存在的安全问题
    String sql = "SELECT * FROM user_log WHERE userLogin = '" + user + "' AND userPass = md5('" + pass + "')";

    -- 但是如果请求传入的参数是下面这样的边会出现问题
    http:\/\/127.0.0.1/login.jsp?user=Admin&pass=123456') or '1=1' or md5('123456

    -- 安全问题:最原始的万能登陆密码(现在基本不存在这样的漏洞)
    SELECT * FROM user_log WHERE userLogin='WeiyiGeek' AND userPass = MD5('123456') OR '1=1'

WeiyiGeek.Statement安全


解决办法 :

  • (1) PrepareStatement 该对象就是替换前面的statement对象, 相比较以前的statement, 预先处理给定的sql语句对其执行语法检查。
  • (2) 在sql语句里面使用 ? 占位符来替代后续要传递进来的变量; 后面进来的变量值,将会被看成是字符串,不会产生任何的关键字。
String sql = "insert into t_user values(null , ? , ?)";
ps = conn.prepareStatement(sql);
//给占位符赋值 从左到右数过来,1 代表第一个问号, 永远你是1开始。
ps.setString(1, userName);


基础实例:

// dao 模型接口
package com.weiyi.dao;
public interface userDao {
4/** Dao模型-接口定义操作数据库的方法*/
4void psLogin(String user,String pass,int x);
4void psInsert(String user,String pass);
4void psUpdate(String user,int id);
4void psDelete(String user,String pass);
}


// dao 模型接口具体实现
package com.weiyi.dao.impl;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import com.weiyi.Jdbc.JDBCUtil;
import com.weiyi.dao.userDao;

public class userDaoImpl implements userDao{
4//JDBC连接标准文档
4Connection conn = null;
4Statement st = null;
4ResultSet rs = null;
4

4/*** 创建PreparedStatement预处理对象 */
4@Override
4public void psLogin(String user,String pass, int x) {
44try {
444//1.载入数据库驱动建立链接
444conn = JDBCUtil.getConn();
444//2.构建SQL语句以及预处理SQL语句
444String sql = "SELECT * FROM user_log WHERE userLogin = ? AND userPass = md5(?) AND id = ?"; //? 占位符合后面会将绑定的参数进行格式化后传入
444PreparedStatement ps = conn.prepareStatement(sql); //关键点1:对我们的SQL语句进行预处理如果SQL语法错误的将不能通过解析
444ps.setString(1, user); //关键点2:进行传入参数的位置开始绑定从,1代表第一个问号,2同理;
444ps.setString(2, pass); //关键点3:注意传入的类型是可以根据需要来设置的;
444ps.setInt(3, x);
444//3.执行预处理好的的对象
444rs = ps.executeQuery();
444if(rs.next()) {
4444System.out.println("登陆成功!");
4444System.out.println("欢迎您" + rs.getString("userLogin") + "管理员, 注册时间: " + rs.getTimestamp("loginTime"));
444} else {
4444System.out.println("登陆失败");
444}
44} catch (Exception e) {
444// TODO: handle exception
444e.printStackTrace();
44} finally {
444JDBCUtil.release(conn, st, rs);
44}
4}
4
4
4@Override
4public void psInsert(String user, String pass) {
44PreparedStatement ps = null;
44try {
444conn = JDBCUtil.getConn();
444String sql = "INSERT INTO user_log(userLogin,userPass) VALUES (?,md5(?))";
444ps = conn.prepareStatement(sql);
444ps.setString(1, user);
444ps.setString(2, pass);
444int result = ps.executeUpdate();
444if(result > 0) {
4444System.out.println("成功添加" + user + "用户!");
444}else {
4444System.out.println("用户注册失败!");
444}
44} catch (SQLException e) {
444// TODO Auto-generated catch block
444e.printStackTrace();
44} finally {
444JDBCUtil.release(conn, ps);
44}
4}

4@Override
4public void psUpdate(String user, int id) {
44PreparedStatement ps = null;
44try {
444conn = JDBCUtil.getConn();
444String sql = "UPDATE user_log SET userLogin = ? WHERE id = ?";
444ps = conn.prepareStatement(sql);
444ps.setString(1, user);
444ps.setInt(2, id);
444int result = ps.executeUpdate();
444if(result>0) {
4444System.out.println("更新用户ID = " + id + ", 为 " + user+"用户成功!");
444}else {
4444System.out.println("更新失败");
444}
44} catch (SQLException e) {
444// TODO: handle exception
444e.printStackTrace();
44} finally {
444JDBCUtil.release(conn, ps);
44}
4}

4@Override
4public void psDelete(String user, String pass) {
44PreparedStatement ps = null;
44try {
444conn = JDBCUtil.getConn();
444String sql = "DELETE FROM user_log WHERE userLogin = ? AND userPass = md5(?)";
444ps = conn.prepareStatement(sql);
444ps.setString(1, user);
444ps.setString(2, pass);
444int result = ps.executeUpdate();
444if(result > 0){
4444System.out.println("用户 " + user +" 删除成功!");
444}else {
4444System.out.println("删除失败");
444}
444
44} catch (SQLException e) {
444// TODO Auto-generated catch block
444e.printStackTrace();
44} finally {
444JDBCUtil.release(conn, ps);
44}
4}
}

执行结果:

Properties配置已经加载!
连接字符串:jdbc:mysql://127.0.0.1:3301/Demo?useUnicode=true&characterEncoding=UTF-8
登陆成功!
欢迎您WeiyiGeek管理员, 注册时间: 2020-01-14 12:42:20.0
更新用户ID = 2, 为 Admin用户成功!
用户 Admin 删除成功!
END-资源释放完成!

JavaEE 架构

  • 客户层 (Web 浏览器 、Applet)
  • Web (Severlet、 Jsp)
  • 业务逻辑 (EJB)
  • 数据持久层 (数据库 MySQL , Oracle)