JSP访问数据库
一.数据库
1.创建数据库
CREATE DATABASE javaWeb1 CHARSET = UTF8;;
USE javaWeb;
CREATE TABLE student(
uname CHAR(20),
upwd CHAR(20)
)
idea连接数据库
2.JDBC
通过java代码操作数据库, 使用到了jdbc
<%
//接受用户的注册信息
request.setCharacterEncoding("UTF-8");
String username = request.getParameter("uname");
String userpwd = request.getParameter("upwd");
// 将用户信息写入数据库
Connection con = null;
PreparedStatement pstmt = null;
//加载数据库驱动
Class.forName("com.mysql.jdbc.Driver");
//创建连接
con= DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/javaweb","root","root");
//创建Statement对象-- sql语句
String loginSql="insert into student(uname,upwd) value(?,?)";
//预编译 SQL语句
pstmt = con.prepareStatement(loginSql);
//设置占位符 ? 的值
pstmt.setString(1, username);
pstmt.setString(2, userpwd);
//执行SQL语句
pstmt.executeUpdate();
out.print("<h1>注册成功</h1>");
%>
2.1JDBC概念
2.2JDBC快速入门
<%
//1.注册驱动
Class.forName("com.mysql.jdbc.Driver");
//2.获取连接
String url="jdbc:mysql://127.0.0.1:3306/javaweb";
String username="root";
String password="root";
Connection conn = DriverManager.getConnection(url, username, password);
//3.定义sql
String sql="insert into student(uname,upwd) value('lisi','123')";
//4.获取执行sql的对象 Statement
Statement stmt = conn.createStatement();
//5.执行sql
int count = stmt.executeUpdate(sql);
//6.打印处理结果---控制台输出
System.out.println(count);
//7.释放资源
stmt.close();
conn.close();
%>
2.3JDBC API 详解
① DriverManager - JDBCDemo2_DriverManager
jdbc:mysql — 协议,固定写法
<%
//1.注册驱动
Class.forName("com.mysql.jdbc.Driver");
//可以不写
//2.获取连接:如果连接的是本机mysq 并且端口是默认的 3306 可以简化书写
String url="jdbc:mysql://127.0.0.1:3306/javaweb";
String username="root";
String password="root";
Connection conn = DriverManager.getConnection(url, username, password);
//3.定义sql
String sql="insert into student(uname,upwd) value('lisi','123')";
//4.获取执行sql的对象 Statement
Statement stmt = conn.createStatement();
//5.执行sql
int count = stmt.executeUpdate(sql);
//6.打印处理结果---控制台输出
System.out.println(count);
//7.释放资源
stmt.close();
conn.close();
%>
② Connection-JDBCDemo3_Connection
无法演示 先不讲
<%
//1.注册驱动
Class.forName("com.mysql.jdbc.Driver");
//可以不写
//2.获取连接:如果连接的是本机mysq 并且端口是默认的 3306 可以简化书写
String url="jdbc:mysql://127.0.0.1:3306/javaweb?useSSL=false";
String username="root";
String password="root";
Connection conn = DriverManager.getConnection(url, username, password);
//3.定义sql
String sql1="update student set upwd='abc' where id=1";
String sql2="update student set upwd='def' where id=2";
//4.获取执行sql的对象 Statement
Statement stmt = conn.createStatement();
// 期望: 两条sql语句要不同时成功, 要不同时失败
// 需要事务管理起来,在sql语句执行前, 开启事务
//使用try/catch实现事务回滚 -- Ctrl+Alt+T
try {
//开启事务
conn.setAutoCommit(false);
//5.执行sql
int count1 = stmt.executeUpdate(sql1);
//6.打印处理结果---控制台输出
System.out.println(count1);
// 造一个异常
int i=3/0;
//5.执行sql
int count2 = stmt.executeUpdate(sql2);
//6.打印处理结果---控制台输出
System.out.println(count2);
//提交事务
conn.commit();
} catch (SQLException throwables) {
// 回滚事务
conn.rollback();
throwables.printStackTrace();
}
//执行成功后, 提交事务 -- 在try中提交事务
//7.释放资源
stmt.close();
conn.close();
%>
③ Statement
DDL: 对表和库的增删改查操作
DML: 对数据的增删改操作
DQL: 对数据的查询操作
package cn.tedu.jdbc;
import org.junit.Test;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
public class JDBCDemo4_Statement {
/**
* 执行DML语句:对数据的增删改
*/
@Test
public void testDML() throws ClassNotFoundException, SQLException {
//1.注册驱动
Class.forName("com.mysql.jdbc.Driver");
//2.获取连接:如果连接的是本机mysq 并且端口是默认的 3306 可以简化书写
String url="jdbc:mysql://127.0.0.1:3306/javaweb";
String username="root";
String password="root";
Connection conn = DriverManager.getConnection(url, username, password);
//3.定义sql
String sql="UPDATE account set money=3000 WHERE id=1";
//4.获取执行sql的对象 Statement
Statement stmt = conn.createStatement();
//5.执行sql--返回值执行完DML语句,受影响的行数
int count = stmt.executeUpdate(sql);
//6.判断执行是否成功
if(count>0){
System.out.println("修改成功");
}else{
System.out.println("修改失败");
}
//7.释放资源
stmt.close();
conn.close();
}
/**
* 执行DDL语句: 对库的增删改查操作
*/
@Test
public void testDDL() throws ClassNotFoundException, SQLException {
//1.注册驱动
Class.forName("com.mysql.jdbc.Driver");
//2.获取连接:如果连接的是本机mysq 并且端口是默认的 3306 可以简化书写
String url="jdbc:mysql://127.0.0.1:3306/javaweb";
String username="root";
String password="root";
Connection conn = DriverManager.getConnection(url, username, password);
//3.定义sql
String sql="CREATE DATABASE myTest";
//4.获取执行sql的对象 Statement
Statement stmt = conn.createStatement();
//5.执行sql--返回值执行完DML语句,受影响的行数
int count = stmt.executeUpdate(sql);
//6.判断执行是否成功
if(count>0){
System.out.println("修改成功");
}else{
System.out.println("修改失败");
}
//7.释放资源
stmt.close();
conn.close();
}
}
④ ResultSet
package cn.tedu.jdbc;
import org.junit.Test;
import java.sql.*;
public class JDBCDemo5_ResultSet {
/**
* 执行DQL语句:查询语句
*/
@Test
public void testResultSet() throws ClassNotFoundException, SQLException {
//1.注册驱动
Class.forName("com.mysql.jdbc.Driver");
//2.获取连接:如果连接的是本机mysq 并且端口是默认的 3306 可以简化书写
String url="jdbc:mysql://127.0.0.1:3306/javaweb";
String username="root";
String password="root";
Connection conn = DriverManager.getConnection(url, username, password);
//3.定义sql
String sql="SELECT * FROM account";
//4.获取Statement对象
Statement stmt = conn.createStatement();
//5.执行sql
ResultSet rs=stmt.executeQuery(sql);
//6.处理结果-遍历rs中的所有数据
//6.1 光标向下移动一行, 并且判断当前行是否有数据
while (rs.next()){
//6.2 获取数据 getXXX(参数)
// int id = rs.getInt(1);
// String name = rs.getString(2);
// double money = rs.getDouble(3);
// System.out.println(id);
// System.out.println(name);
// System.out.println(money);
// System.out.println("--------------");
int id = rs.getInt("id");
String name = rs.getString("uname");
double money = rs.getDouble("money");
System.out.println(id);
System.out.println(name);
System.out.println(money);
System.out.println("--------------");
}
//7.释放资源
rs.close();
stmt.close();
conn.close();
}
}
⑤ PrepareStatement
/*实现登录功能*/
public class JDBCDemo6_UserLogin {
@Test
public void testLogin() throws ClassNotFoundException, SQLException {
//1.注册驱动
Class.forName("com.mysql.jdbc.Driver");
//2.获取连接
String url="jdbc:mysql://127.0.0.1:3306/javaweb";
String username="root";
String password="root";
Connection conn = DriverManager.getConnection(url, username, password);
// 接收用户数输入的用户名和密码
String name = "zhangsan";
String pwd = "def";
//String sql="select * from student where uname='xx' and upwd='sss'";
String sql="select * from student where uname='"+name+"' and upwd='"+pwd+"'";
// 获取stmt对象
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(sql);
if (rs.next()){
System.out.println("登录成功");
}else{
System.out.println("登录失败");
}
//7.释放资源
// rs.close();
// stmt.close();
// conn.close();
}
}
// 演示sql注入- 修改用户名和密码
@Test
public void testLogin_Inject() throws ClassNotFoundException, SQLException {
//1.注册驱动
Class.forName("com.mysql.jdbc.Driver");
//2.获取连接
String url="jdbc:mysql://127.0.0.1:3306/javaweb";
String username="root";
String password="root";
Connection conn = DriverManager.getConnection(url, username, password);
// 接收用户数输入的用户名和密码
String name = "wydhfbh";
String pwd = "'or'1'='1"; //特定的字符
String sql="select * from student where uname='"+name+"' and upwd='"+pwd+"'";
System.out.println(sql);
/*
sql注入成功原因:
当前sql语句: select * from student where uname='wydhfbh' and upwd=''or'1'='1'
upwd变成 upwd=''然后 or '1'='1' 恒等式
uname='wydhfbh' and upwd='' 不成立 false
false or true == true
所以 where的条件为 true
所以可以查询出所有的数据
*/
// 获取stmt对象
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(sql);
if (rs.next()){
System.out.println("登录成功");
}else{
System.out.println("登录失败");
}
//7.释放资源
// rs.close();
// stmt.close();
// conn.close();
}
//解决sql注入 -- PreparedStatement对象
public class JDBCDemo7_PreparedStatement {
@Test
public void testPreparedStmt() throws ClassNotFoundException, SQLException {
//1.注册驱动
Class.forName("com.mysql.jdbc.Driver");
//2.获取连接
String url="jdbc:mysql://127.0.0.1:3306/javaweb";
String username="root";
String password="root";
Connection conn = DriverManager.getConnection(url, username, password);
// 接收用户数输入的用户名和密码
String name = "zhangsan";
String pwd = "def";//"''or'1'='1'";
String sql="select * from student where uname=? and upwd=?";
// 设置 ? 的值
PreparedStatement pstmt = conn.prepareStatement(sql);
pstmt.setString(1, name);
pstmt.setString(2, pwd);
//执行sql -- 不传参
ResultSet rs = pstmt.executeQuery();
if (rs.next()){
System.out.println("登录成功");
}else{
System.out.println("登录失败");
}
//7.释放资源
rs.close();
pstmt.close();
conn.close();
}
}
PreparedStatement原理
2.4 数据库连接池
步骤
补充: 事务
将转账操作当做一个整体来看, 这个整理要不同时成功,要不同时失败, 成功的话,张三和李四的钱变成1500和500, 如果失败,他们的钱还是1000和1000,总数不变, 一直是2000
事务的用法: 将转账操作看做是一个事务,
- 开启事务: START TRANSACTION 或者 BEGIN
- 回滚事务: ROLLBACK
- 提交事务: COMMIT
开启事务就是做标记, 告诉数据库是一个临时修改,遇到提交事务才是真正的修改, 如果遇到错误,就回滚事务,回滚到开启事务之前的状态
USE javaweb;
DROP TABLE IF EXISTS account;
CREATE TABLE account(
id int auto_increment PRIMARY KEY ,
uname VARCHAR(10),
money DOUBLE(10,2)
);
INSERT INTO account(uname,money) values('zs',1000),('ls',1000);
# 转账操作
## 查询ls账户的钱
USE javaweb;
## 修改ls账户的钱减500
UPDATE account set money=money-500 WHERE uname='ls';
#12/0;
## 修改zs账户的前加500
UPDATE account set money=money+500 WHERE uname='zs';
# 转账操作
## 查询ls账户的钱
USE javaweb;
BEGIN; #开启事务
## 修改ls账户的钱减500
UPDATE account set money=money-500 WHERE uname='ls';
#出错了
UPDATE account set money=money-500 WHERE name='ls';
## 修改zs账户的前加500
UPDATE account set money=money+500 WHERE uname='zs';
SELECT * FROM account;
COMMIT ; # 提交事务-- 永久性修改数据
ROLLBACK ; # 回滚事务
2.4 JavaBean
JavaBean是一种可重复使用、且跨平台的软件组件。JavaBean可分为两种:一种是有用户界面(UI,User Interface)的JavaBean;还有一种是没有用户界面,主要负责处理事务(如数据运算,操纵数据库)的JavaBean。JSP通常访问的是后一种JavaBean。
JSP与JavaBean搭配使用的优点
使得HTML与Java程序分离,这样便于维护代码。如果把所有的程序代码都写到JSP网页中,会使得代码繁杂,难以维护。
可以降低开发JSP网页人员对Java编程能力的要求。
JSP侧重于生成动态网页,事务处理由JavaBean来完成,这样可以充分利用JavaBean组件的可重用性特点,提高开发网站的效率。
package cn.tedu.javabean;
import java.io.Serializable;
//实现序列化接口
public class XDLUser implements Serializable {
private static final long serialVersionUID = 1L;
private int id;
private String name;
private int age;
private double salary;
// Fn+Alt+Insert - 无参构造 有参构造 get set方法
public XDLUser(int id, String name, int age, double salary) {
this.id = id;
this.name = name;
this.age = age;
this.salary = salary;
}
public XDLUser() {
}
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 double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
}
jsp中使用javaBean --1
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>在代码块中创建javaBean对象应用</title>
</head>
<body>
<%
XDLUser user = new XDLUser(1,"詹姆斯",32,2600);
%>
<%
String name = user.getName();
System.out.println(name);
%>
<%= user.getName()%>
</body>
jsp中使用javaBean --2