JDBC快速入门
步骤:
增删改
1. 注册驱动
Class.forName("com.mysql.jdbc.Driver"); // 1.5 以后可以省略
2. 获取数据库连接
String url = "jdbc:mysql://127.0.0.1:3306/db6";
// db6 为数据库名称
String username = "root"; // 数据库名
String password = "1234"; // 连接数据库密码
Connection conn = DriverManager.getConnection(url, username, password);
3. 编写sql语句
String sql = "UPDATE account SET money=1000 WHERE id=1";
4. 获取执行sql语句的对象
Statement stmt = conn.createStatement(); // statement对象执行DML DDL语句(不能查询)
5. 执行sql语句
int result = stmt.executeUpdate(sql); // 返回值为影响的行数
6. 处理结果
System.out.println("影响的行数:" + result);
7. 释放资源
stmt.close();
conn.close();
问题
执行结果控制台可能会出现警告 需要在url后面添加信息 ?useSSL=false
? 拼接符 &连接符
String url = "jdbc:mysql://127.0.0.1:3306/db6?useSSL=false";
事务
conn.setAutoCommit(false);
conn.commit();
conn.rollback();
3. 编写sql语句
String sql1 = "UPDATE account SET money=money+500 WHERE name='李四'";
String sql2 = "UPDATE account SET money=money-500 WHERE name='张三'";
4. 获取执行sql语句的对象
Statement stmt = conn.createStatement();
// 开启事务
try {
// 开启事务
conn.setAutoCommit(false); // 参数为false表示,不提交事务。true表示自动提交事务
//执行第一条sql语句
int result1 = stmt.executeUpdate(sql1);
System.out.println(result1);
System.out.println(2/0); // 模拟异常
//执行第二条sql语句
int result2 = stmt.executeUpdate(sql2);
System.out.println(result2);
// 到达此处,说明都执行成功,则手动提交事务
conn.commit();
} catch() {
// 进入异常,则回滚事务
conn.rollback();
e.printStackTrace();
} finally {
// 最后释放资源
if(stmt != null) {
stmt.close();
}
if(conn!= null) {
conn.close();
}
}
查询语句
3. 编写sql语句
String sql = "SELECT * FROM account";
4. 获取执行对象
Statement stmt = conn.createStatement();
5. 执行sql,得到结果集
ResultSet rs = stmt.executeQuery(sql);
6. 处理结果集
while(rs.next()) {
//根据编号获取
// System.out.println(rs.getInt(1) + "," + rs.getString(2) + "," + rs.getInt(3));
//根据列名获取(推荐)
System.out.println(rs.getInt("id") + "," + rs.getString("name") + "," + rs.getInt("money"));
}
可以封装Account对象,将数据添加到集合中。最后遍历集合
###SQL注入问题
sql注入是通过操作输入来修改事先定义好的SQL语句,用以达到执行代码对服务器进行攻击的方法。
数据库准备
-- 创建test数据库
CREATE DATABASE test;
-- 使用test数据库
USE test;
-- 创建用户表
CREATE TABLE tb_user(
id int PRIMARY KEY AUTO_INCREMENT,
username varchar(20),
password varchar(20)
);
-- 添加2个用户数据
INSERT INTO tb_user VALUES (null,'张三','123'),(null,'李四','123');
-- 查询用户数据
SELECT * FROM tb_user;
public class JDBCDemo01 {
public static void main(String[] args) throws Exception {
// 1.注册驱动
Class.forName("com.mysql.jdbc.Driver");
// 2.获取数据库连接
String url = "jdbc:mysql://127.0.0.1/test?useSSL=false";
String username = "root";
String password = "1234";
Connection conn = DriverManager.getConnection(url, username, password);
String user = "张三";
//String pwd = "123";
String pwd = "hhh' or '1' = '1"; // 密码
// 此类密码与下面的sql语句拼接到一块,修改了原本的sql语句。导致查询出错
// 3.编写sql语句
String sql = "SELECT * FROM tb_user WHERE username='"+user+"' AND password='"+pwd+"'";
System.out.println(sql);
// 4.获取执行sql语句的对象
Statement stmt = conn.createStatement();
// 5.执行sql语句,并接收结果集
ResultSet rs = stmt.executeQuery(sql);
// 6.处理结果集
if(rs.next()) {
System.out.println("登录成功");
}else {
System.out.println("登录失败");
}
// 7.释放资源
rs.close();
stmt.close();
conn.close();
}
}
优化
sql 语句中的参数使用 ? 来充当占位符。
使用 prepareStatement 来获取执行sql的预编译对象
&useServerPrepStmts=true url 之后拼接 代表 预编译
prepareStatement好处:
- 预编译SQL,性能更高
- 防止SQL注入,将敏感字符进行转义
- 如果sql模板一样,则只需要进行一次检查、编译
在这里插入代码片
String sql = "SELECT * FROM tb_user WHERE username=? AND password=?";
// 3.获取执行sql语句的预编译对象,对sql语句进行预编译
PreparedStatement pst = conn.prepareStatement(sql);
//给占位符赋值 占位符从 1 开始
pst.setString(1,user);
pst.setString(2,pwd);
// 4.执行sql语句,并接收结果集
ResultSet rs = pst.executeQuery();
druid 连接池
数据库连接池是个容器,负责分配、管理数据库连接(Connection)。 它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个
1. 导入jar包
druid-1.1.12.jar
2. 编写配置文件
druid.properties
3. 加载配置文件
InputStream is = DruidDemo.class.getClassLoader().getResourceAsStream("druid.properties");
Properties prop = new Properties();
prop.load(is);
is.close();
4. 获取数据库连接池对象
DataSource ds = DruidDataSourceFactory.createDataSource(prop);
// 从连接池中,获取数据库连接对象
Connection conn = ds.getConnection();
5. 编写sql
String sql = "SELECT * FROM account";
6. 获取预编译执行者对象
PreparedStatement pst = conn.prepareStatement(sql);
7. 执行sql
ResultSet rs = pst.executeQuery();
8. 处理结果
while(rs.next()) {
System.out.println(rs.getInt("id") + "," + rs.getString("name") + "," + rs.getInt("money"));
}
9. 释放资源
rs.close();
pst.close();
conn.close(); //注意:不是关闭连接,而是将连接归还连接池中
实现增删查改
数据库
-- 创建db7数据库
CREATE DATABASE db7;
-- 使用db7数据库
USE db7;
-- 创建商品分类表
CREATE TABLE tb_brand(
-- id 主键
id int primary key auto_increment,
brand_name varchar(20), -- 品牌名称
company_name varchar(20), -- 企业名称
ordered int, -- 排序字段
description varchar(100), -- 描述信息
status int -- 状态:0:禁用 1:启用
);
-- 添加数据
INSERT INTO tb_brand VALUES (null,'三只松鼠', '三只松鼠股份有限公司', 5, '好吃不上火', 0),
(null,'华为', '华为技术有限公司', 100, '华为致力于把数字世界带入每个人、每个家庭、每个组织,构建万物互联的智能世界', 1),
(null,'小米', '小米科技有限公司', 50, 'are you ok', 1);
-- 查询分类数据
SELECT * FROM tb_brand;
实现
public class TestBrand {
// 1.查询全部
@Test
public void testSelectAll() throws Exception {
//加载配置文件
InputStream is = DruidDemo.class.getClassLoader().getResourceAsStream("druid.properties");
Properties prop = new Properties();
prop.load(is);
//获取数据库连接对象
DataSource ds = DruidDataSourceFactory.createDataSource(prop);
Connection conn = ds.getConnection();
//编写sql语句
String sql = "SELECT * FROM tb_brand";
//获取预编译执行者对象
PreparedStatement pst = conn.prepareStatement(sql);
//执行sql,并接收结果
ResultSet rs = pst.executeQuery();
//处理结果
ArrayList<Brand> brands = new ArrayList<>();
while(rs.next()) {
//获取数据
Integer id = rs.getInt("id");
String brandName = rs.getString("brand_name");
String companyName = rs.getString("company_name");
Integer ordered = rs.getInt("ordered");
String description = rs.getString("description");
Integer status = rs.getInt("status");
//封装Brand对象
Brand brand = new Brand(id,brandName,companyName,ordered,description,status);
//添加到集合
brands.add(brand);
}
//释放资源
rs.close();
pst.close();
conn.close();
//遍历集合
for (Brand brand : brands) {
System.out.println(brand);
}
}
// 2.添加分类
@Test
public void testAdd() throws Exception {
//模拟页面接收到的参数
String brandName = "香飘飘";
String companyName = "香飘飘";
Integer ordered = 1;
String description = "绕地球一圈";
Integer status = 1;
//加载配置文件
InputStream is = DruidDemo.class.getClassLoader().getResourceAsStream("druid.properties");
Properties prop = new Properties();
prop.load(is);
//获取数据库连接对象
DataSource ds = DruidDataSourceFactory.createDataSource(prop);
Connection conn = ds.getConnection();
//编写sql语句
String sql = "INSERT INTO tb_brand(brand_name,company_name,ordered,description,status) VALUES (?,?,?,?,?)";
//获取预编译执行者对象
PreparedStatement pst = conn.prepareStatement(sql);
//设置参数
pst.setString(1,brandName);
pst.setString(2,companyName);
pst.setInt(3,ordered);
pst.setString(4,description);
pst.setInt(5,status);
//执行sql语句并接收结果
int result = pst.executeUpdate();
System.out.println(result);
//释放资源
pst.close();
conn.close();
}
// 3.修改分类
@Test
public void testUpdate() throws Exception {
//模拟页面接收到的参数
String brandName = "香飘飘";
String companyName = "香飘飘";
Integer ordered = 10;
String description = "绕地球三圈";
Integer status = 1;
Integer id = 8;
//加载配置文件
InputStream is = DruidDemo.class.getClassLoader().getResourceAsStream("druid.properties");
Properties prop = new Properties();
prop.load(is);
//获取数据库连接对象
DataSource ds = DruidDataSourceFactory.createDataSource(prop);
Connection conn = ds.getConnection();
//编写sql语句
String sql = "UPDATE tb_brand SET brand_name=?,company_name=?,ordered=?,description=?,status=? WHERE id=?";
//获取预编译执行者对象
PreparedStatement pst = conn.prepareStatement(sql);
//设置参数
pst.setString(1,brandName);
pst.setString(2,companyName);
pst.setInt(3,ordered);
pst.setString(4,description);
pst.setInt(5,status);
pst.setInt(6,id);
//执行sql语句并接收结果
int result = pst.executeUpdate();
System.out.println(result);
//释放资源
pst.close();
conn.close();
}
// 4.删除分类
@Test
public void testDelete() throws Exception {
//模拟页面接收到的参数
Integer id = 4;
//加载配置文件
InputStream is = DruidDemo.class.getClassLoader().getResourceAsStream("druid.properties");
Properties prop = new Properties();
prop.load(is);
//获取数据库连接对象
DataSource ds = DruidDataSourceFactory.createDataSource(prop);
Connection conn = ds.getConnection();
//编写sql语句
String sql = "DELETE FROM tb_brand WHERE id=?";
//获取预编译执行者对象
PreparedStatement pst = conn.prepareStatement(sql);
//设置参数
pst.setInt(1,id);
//执行sql语句并接收结果
int result = pst.executeUpdate();
System.out.println(result);
//释放资源
pst.close();
conn.close();
}
}