javaweb基础学习
一、JDBC
1.1 JDBC的简介
概念:
- JDBC就是使用Java语言操作关系型数据库的一套API
- 全称:(Java DataBase Connectivity)Java 数据库连接
本质:
- 官方 (sun公司)定义的一套操作所有关系型数据库的规则,即接口
- 各个数据库厂商去实现这套接口,提供数据库驱动jar包
- 我们可以使用这套接口(DBC)编程,真正执行的代码是驱动jar包中的实现类
JDBC的好处:
- 各数据库厂商使用相同的接口,Java代码不需要针对不同数据库分别开发
- 可随时替换底层数据库,访问数据库的Java代码基本不变
1.2 jdbc入门
步骤:
- 注册驱动
Class.forName("com.mysql.jdbc.Driver");
- 获取连接
String password = "1234";
String username = "root";
String url = "jdbc:mysql//127.0.0.1/dbc1";
Connection conn = DriverManager.getConnection(url,username,password);
- 定义sql
String sql = "update account set money = 2000 where id = 1";
- 获取到执行sql的对象Statement
Statement sta = conn.createStatement();
- 执行sql(其返回值为sql影响的行数)
int count = sta.executeUpdate(sql);
- 数据处理
System.out.println(count);
- 释放空间
sta.close();
conn.close()
1.3 API详解
1.3.1 DriverManager
DriverManagerg区动管理类)作用
- 注册驱动
- 取数据库连接
提示 MySQL 5之后的驱动包,可以省略注册驱动的步骤自动加载jar包中META-INF/services/java.sql.Driver文件中的驱动类
获取连接
参数:
-
url:连接的路径
-
username:用户名
-
password :密码
1.3.2 Connection
Connection(数据库连接对象)作用
- 获取执行 SQL的对象
普通执行SQL对象
StatementcreateStatement()
预编译SQL的执行SQL对象: 防止SQL注入
PreparedStatement prepareStatement (sql)
执行存储过程的对象
CallableStatement prepareCall (sql)
- 管理事务
-
mysql事务管理
-
JDBC管理事务
package com.Smulll.jdbc;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
public class JDBCdemo3_Connet {
public static void main(String[] args) throws Exception {
//1.注册驱动
Class.forName("com.mysql.jdbc.Driver");
//2.获取连接
String url = "jdbc:mysql://127.0.0.1:3306/test1?useSSL=false";
String username = "root";
String password = "123456";
Connection conn = DriverManager.getConnection(url, username, password);
//3.定义sql
String sql1 = "insert into dept values (null,'1')";
String sql2 = "insert into dept values (null,'2')";
//4. 获取执行SQL的对象 Statement
Statement stmt = conn.createStatement();
//使用try-catch块来抛出异常
try {
//开启手动管理事务
conn.setAutoCommit(false);
//5. 执行sql
int count1 = stmt.executeUpdate(sql1);//受影响的行数
//6. 受处理的结果
System.out.println(count1);
int count2 = stmt.executeUpdate(sql2);//受影响的行数
// 6. 受处理的结果
System.out.println(count2);
//提交事务
conn.commit();
} catch (Exception e) {
//如果出现异常回滚事务
conn.rollback();
}
//7.释放资源
stmt.close();
conn.close();
}
}
1.3.3 Statement
Statement作用
执行SQL语句
executeUpdate(sql):
执行DML、DDL语句int返回值:
(1) DML语句影响的行数
(2) DDL语句执行后,执行成功也可能返回0
executeQuery(sql):
执行DQL 语句ResultSet返回值:
1.3.4 ResultSet
ResultSet(结果集对象)作用
- 封装了DQL查询语句的结果
ResultSet stmt.executeQuery(sal): 执行DQL 语句,返回 ResultSet 对象
获取查询结果:
boolean next():
(1)将光标从当前位置向前移动一行
(2)判断当前行是否为有效行返回值:
true
: 有效行,当前行有数据
false
: 无效行,当前行没有数据
- 使用步骤:
- 游标向下移动一行,并判断该行否有数据: next0
- 获取数据:getXxx(参数)
//循环判断游标是否是最后一行末尾
while(rs.next()){
//1获取数据
rs.getXxx(参数);
}
小练习
遍历accounts里面的所有数据,并且封装程Accout对象,然后用Arraylist进行保存
package itheima;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
public class dom1 {
public static void main(String[] args) throws Exception {
//1. 注册驱动
Class.forName("com.mysql.jdbc.Driver");
//2. 创建连接
String url = "jdbc:mysql://127.0.0.1:3306/itheima?useSSL=false";
String user = "root";
String password = "123456";
Connection connn = DriverManager.getConnection(url, user, password);
//3. 编写sql语句
String sql = "select * from accounts;";
//4. 创建执行sql的sta
Statement sta = connn.createStatement();
// 5. 执行sql
ResultSet resultSet = sta.executeQuery(sql);
//6. 数据处理
ArrayList<Account> list = new ArrayList<>();
while (resultSet.next()){
int id = resultSet.getInt("id");
String name = resultSet.getString("name");
int money = resultSet.getInt("money");
Account account = new Account(id,name,money);
list.add(account);
}
System.out.println(list);
//7. 清理缓存
sta.close();
connn.close();
}
}
1.3.5 PreparedStatement
PreparedStatement作用:
预编译SQL语句并执行:预防SQL注入问题
SQL注入
SQL注入是通过操作输入来修改事先定义好的SQL语句,用以达到执行代码对服务器进行攻击的方法
package itheima;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
public class dom1 {
public static void main(String[] args) throws Exception {
//1. 注册驱动
Class.forName("com.mysql.jdbc.Driver");
//2. 创建连接
String url = "jdbc:mysql://127.0.0.1:3306/itheima?useSSL=false";
String user = "root";
String password = "123456";
Connection connn = DriverManager.getConnection(url, user, password);
//3. 编写sql语句
String name = "zhangsan";
String pwd = "123";
String sql ="select * from tb_user where name = '"+name+"' and password = "+pwd+" ";
//4. 创建执行sql的sta
Statement sta = connn.createStatement();
// 5. 执行sql
ResultSet resultSet = sta.executeQuery(sql);
//6. 数据处理
if (resultSet.next()){
System.out.println("登陆成功");
}else{
System.out.println("登陆失败");
}
//7. 清理缓存
sta.close();
connn.close();
}
}
== 使用步骤==
获取PreparedStatement 对象
//SQL语句中的参数值,使用?占位符替代
String sql = "select * from user where username = ? and password = ?";
//通过Connection对象获取,并传入对应的sql语句
PreparedStatement pstmt = conn.prepareStatement(sql);
设置参数值
PreparedStatement对象:setXxx(参数1,参数2):给?赋值
Xxx:数据类型; 如setInt(参数1,参数2)
参数:
参数1:?的位置编号,从1开始
参数2:?的值
执行SQL
// executeQuery(); :不需要再传递sql
executeUpdate();
修改后的登录判断
package itheima;
import java.sql.*;
import java.util.ArrayList;
public class dom1 {
public static void main(String[] args) throws Exception {
//1. 注册驱动
Class.forName("com.mysql.jdbc.Driver");
//2. 创建连接
String url = "jdbc:mysql://127.0.0.1:3306/itheima?useSSL=false";
String user = "root";
String password = "123456";
Connection conn = DriverManager.getConnection(url, user, password);
//3. 编写sql语句
String name = "zhangsan";
String pwd = "123";
String sql ="select * from tb_user where name = ? and password = ? ";
//4. 创建执行sql的sta
PreparedStatement psta = conn.prepareStatement(sql);
psta.setString(1,name);
psta.setString(2,pwd);
// 5. 执行sql
ResultSet res = psta.executeQuery();
//6. 数据处理
if (res.next()){
System.out.println("登陆成功");
}else{
System.out.println("登陆失败");
}
//7. 清理缓存
psta.close();
conn.close();
}
}
1.7 、PreparedStatement-原理
PreparedStatement好处:
- 预编译SQL,性能更高
- 防止SQL注入: 将敏感字符进行转义
- PreparedStatement预编译功能开启:
useServerPrepStmts=true
配置MySQL执行日志(重启mysql服务后生效)
log-output=FILE
general-log=1
general_log_file="D:\mysql.log"
slow-query-log=1
slow_query_log_file="D:\mysql_slow.log"
long_query_time=2
PreparedStatement原理:
- 在获取PreparedStatement对象时,将sql语句发送给mysql服务器进行检查,编译(这些步骤很耗时)
- 执行时就不用再进行这些步骤了,速度更快
- 如果sql模板一样,则只需要进行一次检查、编译
1.8 数据库连接池
1.8.1 数据库连接池简介
基本介绍
- 数据库连接池是个容器,负责分配、管理数据库连接(Connection)
- 它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个
- 释放空闲时间超过最大空闲时间的数据库连接来避免因为没有释放数据库连接而引起的数据库连接遗漏
好处
- 资源重用
- 提升系统响应速度
- 避免数据库连接遗漏
package itheima.DOM1;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import javax.sql.DataSource;
import java.io.FileInputStream;
import java.sql.Connection;
import java.util.Properties;
public class dom2 {
public static void main(String[] args) throws Exception {
//1. 导入jar包
//2. 定义配置文件
//3. 加载配置文件
Properties prop = new Properties();
prop.load(new FileInputStream("E:\\Java文件夹\\dome-jdbc\\jdbc\\src\\itheima\\DOM1\\druid.properties"));
//4. 获取到连接池对象
DataSource dataSource = DruidDataSourceFactory.createDataSource(prop);
//5.获取到数据库连接 connection
Connection connection = dataSource.getConnection();
System.out.println(connection);
}
}
1.9 综合小练习
查询
package itheima.proj;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import javax.sql.DataSource;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Properties;
import java.util.ResourceBundle;
public class Brand {
//查询数据
public static void main(String[] args) throws Exception {
// 1. 获取连接对象
Properties properties = new Properties();
properties.load(new FileInputStream("E:\\Java文件夹\\dome-jdbc\\jdbc\\src\\itheima\\DOM1\\druid.properties"));
//2. 获取连接池对象
DataSource dataSource = DruidDataSourceFactory.createDataSource(properties);
//3. 获取到 connection对象
Connection conn = dataSource.getConnection();
//4. 定义sql
String sql = "select * from tb_brand";
// 5. 创建pstate
PreparedStatement pstate = conn.prepareStatement(sql);
//6.执行sql
ResultSet res = pstate.executeQuery ();
//7.获取到所有的数据
List list = new ArrayList<brand>();
while (rs.next()) {
//获取到结果
int id = rs.getInt("id");
String brandName = rs.getString("brand_name");
String companyName = rs.getString("company_name");
int ordered = rs.getInt("ordered");
String description = rs.getString("description");
int status = rs.getInt("status");
//创建一个brand对象
brand brand = new brand(id,brandName,companyName,ordered,description,status);
list.add(brand);
}
System.out.println(list);
//8. 清理资源
pstate.close();
conn.close();
}
}
添加
package itheima.proj;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import javax.sql.DataSource;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Properties;
import java.util.ResourceBundle;
public class Brand {
//查询数据
public static void main(String[] args) throws Exception {
// 1. 获取连接对象
Properties properties = new Properties();
properties.load(new FileInputStream("E:\\Java文件夹\\dome-jdbc\\jdbc\\src\\itheima\\DOM1\\druid.properties"));
//2. 获取连接池对象
DataSource dataSource = DruidDataSourceFactory.createDataSource(properties);
//3. 获取到 connection对象
Connection conn = dataSource.getConnection();
//4. 定义sql
String sql = "insert into tb_brand (brand_name, company_name, ordered, description, status) values (?,?,?,?,?)";
String brandName = "农夫山泉";
String companyName = "哇哈哈有限公司";
int ordered = 1;
String description = "我们不生产水,我们只是大自然的搬运工";
int status = 1;
// 5. 创建pstate
PreparedStatement pstate = conn.prepareStatement(sql);
pstate.setString(1,brandName);
pstate.setString(2,companyName);
pstate.setInt(3,ordered);
pstate.setString(4,description);
pstate.setInt(5,status);
//6.执行sql
int res = pstate.executeUpdate();
//7.获取到所有的数据
if (res > 0){
System.out.println("加入成功");
}else{
System.out.println("加入失败");
}
//8. 清理资源
pstate.close();
conn.close();
}
}
修改
package itheima.proj;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import javax.sql.DataSource;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Properties;
import java.util.ResourceBundle;
public class Brand {
//查询数据
public static void main(String[] args) throws Exception {
// 1. 获取连接对象
Properties properties = new Properties();
properties.load(new FileInputStream("E:\\Java文件夹\\dome-jdbc\\jdbc\\src\\itheima\\DOM1\\druid.properties"));
//2. 获取连接池对象
DataSource dataSource = DruidDataSourceFactory.createDataSource(properties);
//3. 获取到 connection对象
Connection conn = dataSource.getConnection();
//4. 定义sql
String sql = "update tb_brand set brand_name = ? ,company_name = ?,ordered = ? , description = ? ,status = ? where id = ?";
String brandName = "农夫山贼";
String companyName = "哇哈哈哈哈哈有限公司";
int ordered = 1;
String description = "我们不生产水,我们只是大自然的搬运工";
int status = 1;
// 5. 创建pstate
PreparedStatement pstate = conn.prepareStatement(sql);
pstate.setString(1,brandName);
pstate.setString(2,companyName);
pstate.setInt(3,ordered);
pstate.setString(4,description);
pstate.setInt(5,status);
pstate.setInt(6,4);
//6.执行sql
int res = pstate.executeUpdate();
//7.获取到所有的数据
if (res > 0){
System.out.println("修改成功");
}else{
System.out.println("修改失败");
}
//8. 清理资源
pstate.close();
conn.close();
}
}
删除
package itheima.proj;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import javax.sql.DataSource;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Properties;
import java.util.ResourceBundle;
public class Brand {
//查询数据
public static void main(String[] args) throws Exception {
// 1. 获取连接对象
Properties properties = new Properties();
properties.load(new FileInputStream("E:\\Java文件夹\\dome-jdbc\\jdbc\\src\\itheima\\DOM1\\druid.properties"));
//2. 获取连接池对象
DataSource dataSource = DruidDataSourceFactory.createDataSource(properties);
//3. 获取到 connection对象
Connection conn = dataSource.getConnection();
//4. 定义sql
String sql = "delete from tb_brand where id = ?";
// 5. 创建pstate
PreparedStatement pstate = conn.prepareStatement(sql);
pstate.setInt(1,4);
//6.执行sql
int res = pstate.executeUpdate();
//7.获取到所有的数据
if (res > 0){
System.out.println("修改成功");
}else{
System.out.println("修改失败");
}
//8. 清理资源
pstate.close();
conn.close();
}
}