MariaDB学习(四)-数据库连接池DBCP、注册、登录、将WebServer改成数据库版本
-
Data Base Connection Pool: 数据库连接池
-
作用: 因为频繁开关连接会浪费服务器资源,使用数据库连接池可以将连接重用,避免频繁开关连接,从而提高执行效率.
-
如何使用数据库连接池
-
在pom.xml文件中添加数据库连接池相关的依赖
<!-- 数据库连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.21</version>
</dependency> -
注册功能
-
创建用户表
use newdb3;
create table user(id int primary key auto_increment,username varchar(50),password varchar(50))charset=utf8;
-
相关代码:
Scanner sc = new Scanner(System.in);
System.out.println("请输入用户名");
String username = sc.nextLine();
System.out.println("请输入密码");
String password = sc.nextLine();
//获取连接
try (Connection conn = DBUtils.getConn()){
//创建执行SQL语句的对象
Statement s = conn.createStatement();
//查询是否存在
ResultSet rs = s.executeQuery("select id from user where username='"+username+"'");
//判断是否有查询到数据
if (rs.next()){
System.out.println("用户名已存在!");
return;
}
//准备插入数据的SQL
String sql = "insert into user values(null,'"+username+"','"+password+"')";
System.out.println(sql);
//执行SQL语句
s.executeUpdate(sql);
System.out.println("执行完成!");
登录功能
select count(*) from user where username='tom' and password='123456';
-
相关代码:
Scanner sc = new Scanner(System.in);
System.out.println("请输入用户名");
String username = sc.nextLine();
System.out.println("请输入密码");
String password = sc.nextLine();
//获取连接
try (Connection conn = DBUtils.getConn()){
Statement s = conn.createStatement();
//准备查询的SQL语句 把用户名和密码拼接进去
String sql = "select count(*) from user where username='username+"' and password='"+password+"'";
System.out.println(sql);
ResultSet rs = s.executeQuery(sql);
//不管用户输入什么,都会有结果,所以不用判断是否有下一条数据,直接移动游标
rs.next();
//取出查询到的数量
int count = rs.getInt(1);
if (count>0){
System.out.println("登录成功!");
}else{
System.out.println("用户名或密码错误!");
}
} catch (SQLException throwables) {
throwables.printStackTrace();
} -
以上写法存在SQL注入漏洞
-
什么事SQL注入?
往SQL语句中添加值的地方,添加进去了SQL语句,导致原有SQL语句的业务逻辑发生改变,这种行为称为SQL注入
-
通过PreparedStatement 预编译的执行SQL语句的对象解决SQL注入问题
-
相关代码:
// **********************解决SQL注入问题***************************
//用? 把变量的位置占上
String sql = "select count(*) from user where username=? and password=?";
//创建执行SQL语句的对象
//预编译: 由原来执行时编译 提前到创建时编译,编译SQL语句时将SQL语句的
//业务逻辑锁死, 编译后不会被用户输入的内容所影响
PreparedStatement ps = conn.prepareStatement(sql);
//替换SQL语句中的?
ps.setString(1,username);
ps.setString(2,password);
//执行查询
ResultSet rs = ps.executeQuery();
批量操作
-
-
Statement相关代码:
//批量操作 三次合并成一次数据传输
s.addBatch(sql1);//添加到批量操作
s.addBatch(sql2);
s.addBatch(sql3);
s.executeBatch();//执行批量操作 -
PreparedStatement相关代码:
String sql = "insert into user values(null,?,?)";
//因为SQL语句中有变量所以使用预编译的对象
PreparedStatement ps = conn.prepareStatement(sql);
for (int i = 1; i <= 100; i++) {
ps.setString(1,"name"+i);
ps.setString(2,"pw"+i);
//添加到批量操作
ps.addBatch();
if (i%20==0){//每隔20次执行一次 避免内存溢出
ps.executeBatch();
}
}
//执行批量操作
ps.executeBatch();
System.out.println("执行完成!");
将WebServer改成数据库版本
-
建库建表
create database wsdb charset=utf8;
use wsdb;
create table user(id int primary key auto_increment,username varchar(50),password varchar(50),nick varchar(50),age int);
-
在之前的WebServer工程中添加com.webserver.utils把今天工程中用到的DBUtils复制到这里
-
在pom.xml中添加数据库和连接池相关的两个依赖,刷新maven
-
修改DBUtils工具类中的newdb3为wsdb
-
修改注册功能:
-
将原注册的第二步和第三步注释掉,添加以下代码
//把上面得到的参数保存到user表里面
//获取连接
try (Connection conn = DBUtils.getConn()){
String sql = "insert into user values(null,?,?,?,?)";
PreparedStatement ps = conn.prepareStatement(sql);
ps.setString(1,username);
ps.setString(2,password);
ps.setString(3,nickname);
ps.setInt(4,age);
ps.executeUpdate();//执行
//给客户端返回注册成功
File file = new File(
"./webapps/myweb/reg_success.html");
response.setEntity(file);
} catch (SQLException throwables) {
throwables.printStackTrace();
}
-
-
修改登录功能:
-
修改登录代码
//获取连接
try(Connection conn = DBUtils.getConnection();){
//准备登录查询的SQL
String sql = "select count(*) from user where username=? and password=?";
PreparedStatement ps = conn.prepareStatement(sql);
ps.setString(1,username);
ps.setString(2,password);
ResultSet rs = ps.executeQuery();//执行查询
rs.next();//移动游标
//取出查询到的数量
int count = rs.getInt(1);
if(count>0){//登陆成功
response.setEntity(new File("./webapps/myweb/login_success.html"));
}else{
response.setEntity(new File("./webapps/myweb/login_fail.html"));
}
} catch (SQLException e) {
e.printStackTrace();
}
System.out.println("处理登录完毕!");UserController代码:
package com.webserver.controller;
import com.webserver.core.annotation.Controller;
import com.webserver.core.annotation.RequestMapping;
import com.webserver.http.HttpRequest;
import com.webserver.http.HttpResponse;
import com.webserver.utils.DBUtils;
import com.webserver.vo.User;
import java.io.*;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
/**
* 处理与用户业务相关的操作
*/
-