// 这个可以不用写,mysql驱动里面配置了
// 会自动加载jar包中META-INF/services/java.sql.Driver文件中的驱动类
Class.forName("com.mysql.cj.jdbc.Driver");
在com.mysql.cj.jdbc.Driver
这个类中,有个静态代码块,是用来注册驱动的,源码如下:
package com.mysql.cj.jdbc;
public class Driver extends NonRegisteringDriver implements java.sql.Driver {
public Driver() throws SQLException {
}
static {
try {
DriverManager.registerDriver(new Driver());
} catch (SQLException var1) {
throw new RuntimeException("Can't register driver!");
}
}
}
//String url = "jdbc:mysql://127.0.0.1:3306/db1";
// 如果是本机的mysql并且端口是默认的3306,可以简化书写
String url = "jdbc:mysql:///db1";
String url = "jdbc:mysql:///db1";
String username = "root";
String password = "root1234";
// 2. 获取连接
Connection conn = DriverManager.getConnection(url, username, password);
数据库连接对象
Statement statement = conn.createStatement();
PreparedStatement prepareStatement = conn.prepareStatement(sql);
// true:设置成自动提交事务
// false:设置成手动提交事务
// 开启事务
setAutoCommit(false)
commit()
rollback()
drop table if exists account;
create table if not exists account
(
id int primary key auto_increment,
name varchar(10),
money double(10, 2)
);
insert into account(name, money)
values ('张三', 1000),
('李四', 1000);
// 如果是本机的mysql并且端口是默认的3306,可以简化书写
String url = "jdbc:mysql:///db1";
String username = "root";
String password = "root1234";
// 1. 注册驱动
// 这个可以不用写,mysql驱动里面配置了
// 会自动加载jar包中META-INF/services/java.sql.Driver文件中的驱动类
// Class.forName(className);
// 2. 获取连接
Connection conn = DriverManager.getConnection(url, username, password);
// 3. 定义sql语句
String sql1 = "update account set money = 111 where id = 1";
String sql2 = "update account set money = 111 where id = 2";
// 4. 获取执行sql的对象 statement
Statement statement = conn.createStatement();
/**
* ========事务管理=================
*/
try {
// 开启事务
conn.setAutoCommit(false);
// 5. 执行sql语句
int count1 = statement.executeUpdate(sql1);
System.out.println("count: " + count1);
// 模拟失败
int i = 1 / 0;
int count2 = statement.executeUpdate(sql2);
System.out.println("count: " + count2);
// 提交事务
conn.commit();
} catch (Exception e) {
// 回滚事务
conn.rollback();
e.printStackTrace();
}
// 6. 处理结果
// 7. 释放资源
statement.close();
conn.close();
作用就是执行sql语句
int executeUpdate(String sql)
:执行DML、DDL语句
ResultSet executeQuery(String sql)
:执行DQL语句
executeUpdate 执行DML语句
@Test
public void testDML() throws Exception {
//String url = "jdbc:mysql://127.0.0.1:3306/db1";
// 如果是本机的mysql并且端口是默认的3306,可以简化书写
String url = "jdbc:mysql:///db1";
String username = "root";
String password = "root1234";
String className = "com.mysql.cj.jdbc.Driver";
// 1. 注册驱动
// 这个可以不用写,mysql驱动里面配置了
// 会自动加载jar包中META-INF/services/java.sql.Driver文件中的驱动类
// Class.forName(className);
// 2. 获取连接
Connection conn = DriverManager.getConnection(url, username, password);
// 3. 定义sql语句
String sql = "insert into account(name, money) values ('张三丰', '2000');";
// 4. 获取执行sql的对象 statement
Statement statement = conn.createStatement();
// 5. 执行sql语句
int count = statement.executeUpdate(sql);
// 6. 处理结果 count 为 1
System.out.println("count: " + count);
// 7. 释放资源
statement.close();
conn.close();
}
executeUpdate 执行DDL语句
@Test
public void testDDL() throws Exception {
//String url = "jdbc:mysql://127.0.0.1:3306/db1";
// 如果是本机的mysql并且端口是默认的3306,可以简化书写
String url = "jdbc:mysql:///db1";
String username = "root";
String password = "root1234";
String className = "com.mysql.cj.jdbc.Driver";
// 1. 注册驱动
// 这个可以不用写,mysql驱动里面配置了
// 会自动加载jar包中META-INF/services/java.sql.Driver文件中的驱动类
// Class.forName(className);
// 2. 获取连接
Connection conn = DriverManager.getConnection(url, username, password);
// 3. 定义sql语句
String sql = "create table if not exists tb_test_ddl\n" +
"(\n" +
" id int primary key auto_increment,\n" +
" username varchar(20) not null unique,\n" +
" password varchar(20) not null default 123456\n" +
");";
// 4. 获取执行sql的对象 statement
Statement statement = conn.createStatement();
// 5. 执行sql语句
int count = statement.executeUpdate(sql);
// 6. 处理结果 count 为 0
System.out.println("count: " + count);
// 7. 释放资源
statement.close();
conn.close();
}
executeQuery 执行DQL语句
这里使用的是sql注入的例子
模拟数据
create table if not exists tb_user
(
id int primary key auto_increment,
username varchar(20),
password varchar(20)
);
insert into tb_user(username, password)
VALUES ('zhangsan', '123'),
('lisi', '123');
java 代码
@Test
public void testSqlInject() throws Exception {
String url = "jdbc:mysql:///db1";
String username = "root";
String password = "root1234";
Connection conn = DriverManager.getConnection(url, username, password);
String name = "asdafa";
String pwd = "' or '1' = '1";
// 3. 定义sql语句
String sql = "select * from tb_user where username='" + name + "' and password='" + pwd + "'";
// select * from tb_user where username='asdafa' and password='' or '1' = '1'
// 上面的语句相当于 select * from tb_user
System.out.println(sql);
Statement statement = conn.createStatement();
// 通过执行上面的sql语句,是查询所有的user数据
ResultSet rs = statement.executeQuery(sql);
if (rs.next()) {
System.out.println("登陆成功");
} else {
System.out.println("登陆失败");
}
// 释放资源
rs.close();
statement.close();
conn.close();
}
ResultSet 里面是封装了DQL查询语句的结果
boolean next()
xxx getXxx(param)
获取数据
int getInt(param)
和 String getString(param)
columnIndex
:列的序号,是从1开始columnLabel
:列的名称@Test
public void testResultSet() throws Exception {
String url = "jdbc:mysql:///db1";
String username = "root";
String password = "root1234";
Connection conn = DriverManager.getConnection(url, username, password);
// 3. 定义sql语句
String sql = "select * from account";
Statement statement = conn.createStatement();
ResultSet rs = statement.executeQuery(sql);
while (rs.next()) {
// 根据列的序号获取
// int id = rs.getInt(1);
// String name = rs.getString(2);
// double money = rs.getDouble(3);
// 根据列的名称获取
int id = rs.getInt("id");
String name = rs.getString("name");
double money = rs.getDouble("money");
System.out.println(id + " , " + name + " , " + money);
}
// 释放资源
rs.close();
statement.close();
conn.close();
}
预编译sql并执行sql语句
好处
原理
PreparedStatement
对象时,将sql语句发送给了mysql服务器进行检查,编译(这些步骤比较耗时)获取PreparedStatement
对象
// sql语句里面的参数值使用?占位符替代
String sql = "select * from tb_user where username= ? and password = ?";
// 通过Connection对象传入对应的sql语句获取
PreparedStatement prepareStatement = conn.prepareStatement(sql);
设置参数值 setXxx(p1,p2):给sql语句中?赋值
执行sql
executeQuery()
/ executeUpdate()
在这里就不需要传递sql语句了@Test
public void testPreparedStatement() throws Exception {
// useServerPrepStmts=true 开启预编译功能
String url = "jdbc:mysql:///db1?useServerPrepStmts=true";
String username = "root";
String password = "root1234";
Connection conn = DriverManager.getConnection(url, username, password);
String name = "zhangsan";
// String pwd = "' or '1' = '1";
String pwd = "123";
// 定义sql语句
String sql = "select * from tb_user where username= ? and password = ?";
// 获取 PreparedStatement 对象
PreparedStatement prepareStatement = conn.prepareStatement(sql);
// 给 ?设置值
prepareStatement.setString(1, name);
prepareStatement.setString(2, pwd);
// 执行sql
ResultSet rs = prepareStatement.executeQuery();
if (rs.next()) {
System.out.println("登陆成功");
} else {
System.out.println("登陆失败");
}
// 再次设置数据,并执行,在这里,就不需要进行检查编译了,
prepareStatement.setString(1, "aaa");
prepareStatement.setString(2, "pwd");
rs = prepareStatement.executeQuery();
if (rs.next()) {
System.out.println("登陆成功");
} else {
System.out.println("登陆失败");
}
rs.close();
prepareStatement.close();
conn.close();
}
这里用到了junit单元测试,需要在pom.xml
中导入junit
<dependencies>
<dependency>
<groupId>com.mysqlgroupId>
<artifactId>mysql-connector-jartifactId>
<version>8.0.33version>
dependency>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<version>RELEASEversion>
<scope>compilescope>
dependency>
dependencies>
1. 黑马程序员JavaWeb基础教程