学习jdbc-爱代码爱编程
JDBC简介
JDBC概念:
·JDBC就是使用Java语言操怍关系型数舵库的一套API·全称: (Java DataBase Connectivity ) Java数据库连接
JDBC本质:
·官方(sun公司)定义的一套操作所有关系型数据库的规则,即接口
·各个数据库厂商去实现这套接口,提供数据库驱动jar包
·我们可以使用这套接口(JDBC)编程,真正执行的代码是驱动jar包中的实现类
JDBC好处:
·各数据库厂商使用相同的接口,Java代码不需要针对不同数据库分别开发
·可随时替换底层数据库,访问数据库的Java代码基本不变
JDBC快速入门
步骤
0.创建工程,导入驱动jar包
mysql-connector-java-5.1.48.jar
1.注册驱动
Class.forName("com.mysql.jdbc.Driver");
2.获取连接
Connection conn = DriverManager.getConnection(url, username, password);
3.定义SQL语句
String sql = “update...";
4.获取执行SQL对象
Statement stmt = conn.createStatement();
5.执行SQL
stmt.executeUpdate(sql);
6.处理返回结果
7.释放资源
package iknow.jdbc;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
public class JDBCDemo {
public static void main(String[] args) throws Exception {
//1.注册驱动
Class.forName("com.mysql.jdbc.Driver");
//2.获取连接
String url = "jdbc:mysql://localhost:3306/db1";
String username = "root";
String password = "1234";
Connection conn = DriverManager.getConnection(url,username,password);
//3.定义sql
String sql = "update account set money = 2000 where id = 1";
//4.获取执行sql的对象 Statement
Statement stmt = conn.createStatement();
//5.执行sql
int count = stmt.executeUpdate(sql);//受影响的行数
//6.处理结果
System.out.println(count);
//7.释放资源
stmt.close();
conn.close();
}
}
JDBC API详解
DriverManager
·DriverManager(驱动管理类)作用:
1.注册驱动
2获取数据库连接
1.注册驱动
Class forNarna("com.mysql jdbc.Driver");
提示:
. MySQL 5之后的驱动包,可以省略注册驱动的步骤
·自动加载jar包中META-INF/servicesf/java.sql.Driver文件中的驱动类
2.获取连接
static Connection getConnection (String url,String user,String password)
·参数
1.url:连接路径
语法: jdbc:mysql://ip地址(域名):端口号/数据库名称?参数键值对1&参数键值对2...
示例: jdbc:mysql://127.0.0.1:3306/db1
细节:
·如果连接的是本机mysql服务器,并且mysql服务默认端口是3306,则ur可以简写为: jdbc:mysql://数据库名称?参数键值对
·配置useSSL=false参数,禁用安全连接方式,解决警告提示
2.user:用户名
3.password:密码
package iknow.jdbc;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
public class JDBCDemo2_DriverManager {
public static void main(String[] args) throws Exception {
//1.注册驱动
// Class.forName("com.mysql.jdbc.Driver");
//2.获取连接
String url = "jdbc:mysql:///db1?useSSL=false";
String username = "root";
String password = "1234";
Connection conn = DriverManager.getConnection(url,username,password);
//3.定义sql
String sql = "update account set money = 2000 where id = 1";
//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
·Connection(数据库连接对象)作用:
1.获取执行SQL的对象
2.管理事务
1.获取执行SQL的对象
·普通执行SQL对象
Stalemert createStatement()
·预综译SQL的执行SQL对象:防止SQL注入
PreparedStatement prapareStatement (sql)
·执行存储过程的对象
callableStatement prepareCall (sql)
2.事务管理
·MySQL事务管理
开启事务:BEGIN;&START TRANSACTION;
提交事务:COMMIT;
回滚事务:ROLLBACK;
MySOL默认自动提交事务
· JDBC事务管理: Connection接口中定义了3个对应的方法
开启事务: setAutcCommit(boolean autoCommit): true为自动提交事务; false为手动提交事务,即为开启事务
提交事务:commit()
可滚事务:rollback()
package iknow.jdbc;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
public class JDBCDemo3_Connection {
public static void main(String[] args) throws Exception {
//1.注册驱动
//Class.forName("com.mysql.jdbc.Driver");
//2.获取连接
String url = "jdbc:mysql:///db1?useSSL=false";
String username = "root";
String password = "1234";
Connection conn = DriverManager.getConnection(url,username,password);
//3.定义sql
String sql1 = "update account set money = 3000 where id = 1";
String sql2 = "update account set money = 3000 where id = 2";
//4.获取执行sql的对象 Statement
Statement stmt = conn.createStatement();
try {
//开启事务
conn.setAutoCommit(false);
//5.执行sql
int count1 = stmt.executeUpdate(sql1);//受影响的行数
//6.处理结果
System.out.println(count1);
//5.执行sql
int count2 = stmt.executeUpdate(sql2);//受影响的行数
//6.处理结果
System.out.println(count2);
//提交事务
conn.commit();
} catch (Exception e) {
//回滚事务
conn.rollback();
e.printStackTrace();
}
//7.释放资源
stmt.close();
conn.close();
}
}
Statement
·Statement作用:
1.执行SQL语句
·执行SQL语句
int executeUpdate(sql):执行DML.DDL语句
返回值:(1) DML语句影响的行数 (2)DDL语句执行后,执行成功也可能返回О
ResultSet executeQueryi(sql):执行DQL语句
返回值:ResultSet结果集对象
package iknow.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语句
* @throws Exception
*/
@Test
public void testDML() throws Exception {
//1.注册驱动
//Class.forName("com.mysql.jdbc.Driver");
//2.获取连接
String url = "jdbc:mysql:///db1?useSSL=false";
String username = "root";
String password = "1234";
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
int count = stmt.executeUpdate(sql);//受影响的行数
//6.处理结果
if (count > 0){
System.out.println("修改成功");
}else {
System.out.println("修改失败");
}
//7.释放资源
stmt.close();
conn.close();
}
/**
* 执行DDL语句
* @throws Exception
*/
@Test
public void testDDL() throws Exception {
//1.注册驱动
Class.forName("com.mysql.jdbc.Driver");
//2.获取连接
String url = "jdbc:mysql:///db1?useSSL=false";
String username = "root";
String password = "1234";
Connection conn = DriverManager.getConnection(url,username,password);
//3.定义sql
String sql = "create database db2";
//4.获取执行sql的对象 Statement
Statement stmt = conn.createStatement();
//5.执行sql
int count = stmt.executeUpdate(sql);//受影响的行数
//6.处理结果
if (count > 0){
System.out.println("修改成功");
}else {
System.out.println("修改失败");
}
//7.释放资源
stmt.close();
conn.close();
}
}
ResultSet
. ResultSet(结果集对象)作用:
1.封装了DQL查询语句的结果
ResultSet stmt.executeQuery(sql):执行DQL语句,返回ResultSet对象
·获取查询结果
boolean next(): (1)将光标从当前位置向前移动一行(2)判断当前行是否为有效行
返回值:
· true:有效行,当前行有数据.
· false:无效行,当前行没有数据
xxx getXxx(参数):获取数据
xxx:数据类型;如: int getInt(参数) ; String getString(参数)
参数:
·int:列的编号,从1开始
·String:列的名称
·使用步骤:
1.游标向下移动一行,并判断该行否有数据: next()
2.获取数据: getXxx(参数)
//循环判断游标是否是最后一行末尾
while(s.next(){
//获取数据
rs.getXxcx(参数);
}
import org.junit.Test;
import pojo.Account;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
public class JDBCDemo5_ResultSet {
/**
* 执行DQL语句
* @throws Exception
*/
@Test
public void testResultSet() throws Exception {
//1.注册驱动
//Class.forName("com.mysql.jdbc.Driver");
//2.获取连接
String url = "jdbc:mysql:///db1?useSSL=false";
String username = "root";
String password = "1234";
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()){
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("---------------------");
}
//7.释放资源
rs.close();
stmt.close();
conn.close();
}
案例ResultSet案例
需求:查询account账户表数据,封装为Account对象中,并且存储到ArrayList集合中
/**
* 查询account
* 1.定义实体类Account
* 2.查询数据,封装到Account对象中
* 3.将Account对象存入ArrayList集合中
*
* @throws Exception
*/
@Test
public void testResultSet2() throws Exception {
//1.注册驱动
//Class.forName("com.mysql.jdbc.Driver");
//2.获取连接
String url = "jdbc:mysql:///db1?useSSL=false";
String username = "root";
String password = "1234";
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);
//创建集合
List<Account> list = new ArrayList<>();
//6.处理结果,遍历rs中的所有数据
//6.1 光标向下移动一行,并且判断当前行是否有数据
while (rs.next()){
Account account = new Account();
//6.2 获取数据 getXxx()
int id = rs.getInt("id");
String name = rs.getString("name");
double money = rs.getDouble("money");
//赋值
account.setId(id);
account.setName(name);
account.setMoney(money);
//存入集合
list.add(account);
}
System.out.println(list);
//7.释放资源
rs.close();
stmt.close();
conn.close();
}
}
PreparedStatement
·PreparedStatement作用:
1.预编译SQL语句并执行:预防SQL注入问题
. SQL注入
. SQL注入是通过操作输入来修改事先定义好的SQL语句,用以达到执行代码对服务器进行攻击的方法。
package iknow.jdbc;
import org.junit.Test;
import pojo.Account;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
public class JDBCDemo6_UserLogin {
/**
*
* @throws Exception
*/
@Test
public void testResultSet2() throws Exception {
//2.获取连接
String url = "jdbc:mysql:///db1?useSSL=false";
String username = "root";
String password = "1234";
Connection conn = DriverManager.getConnection(url,username,password);
//接收用户输入 用户名和密码
String name = "asdgagetggh";
String pwd = "' or '1' = '1";
String sql = "select * from tb_user where username = '"+name+"' and password = '"+pwd+"'";
System.out.println(sql);
//4.获取statement对象
Statement stmt = conn.createStatement();
//5.执行sql
ResultSet rs = stmt.executeQuery(sql);
//创建集合
List<Account> list = new ArrayList<>();
//6.处理结果,遍历rs中的所有数据
//6.1 光标向下移动一行,并且判断当前行是否有数据
while (rs.next()){
Account account = new Account();
//6.2 获取数据 getXxx()
int id = rs.getInt("id");
String name = rs.getString("name");
double money = rs.getDouble("money");
//赋值
account.setId(id);
account.setName(name);
account.setMoney(money);
//存入集合
list.add(account);
}
System.out.println(list);
//7.释放资源
rs.close();
stmt.close();
conn.close();
}
}
PreparedStatement作用:
1.预编译SQL并执行SQL语句
(1)获取PreparedStatement对象
//SQL语句中的参数值,使用?占位符替代
String sql = "select * from user where username = ? and password = ?";
通过Connection对象获取,并传入对应的sql语句
PreparedStatement pstmt = conn.prepareStatement(sql);
(2) 设置参数值
PreparedStatement对象:setXxx(参数1,参数2):给?赋值
Xxx:数据类型;如setlnt(参数1,参数2)
参数:
参数1:?的位置编号,从1开始
参数2:?的值
(3)执行SQL
executeUpdate(); / executeQuery(); ︰不需要再传递sql
package iknow.jdbc;
import org.junit.Test;
import pojo.Account;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
public class JDBCDemo7_PreparedStatement {
/**
*
* @throws Exception
*/
@Test
public void testResultSet2() throws Exception {
//2.获取连接
String url = "jdbc:mysql:///db1?useSSL=false";
String username = "root";
String password = "1234";
Connection conn = DriverManager.getConnection(url,username,password);
//接收用户输入 用户名和密码
String name = "asdgagetggh";
String pwd = "adgaggag";
String sql = "select * from tb_user where username = ? and password = ?";
//4.获取pstmt对象
Statement pstmt = conn.createStatement();
//设置?到值
pstmt.setString(1,name);
pstmt.setString(2,pwd);
//5.执行sql
ResultSet rs = pstmt.executeQuery();
//判断登录是否成功
if (rs.next()){
System.out.println("登录成功~");
}else {
System.out.println("登录失败~");
}
//7.释放资源
rs.close();
stmt.close();
conn.close();
}
}
PreparedStatement原理
· PreparedStatement好处:
1.预编译SQL,性能更高
2.防止SQL注X:将敏感字符进行转义
(1)PreparedStatement 预编译功能开启: useServerPrepStmts=true
(2)配置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原理:
1.在获取PreparedStatement对象时,将sql语句发送给mysql服务器
进行检查,编译(这些步骤很耗时)
2.执行时就不用再进行这些步骤了,速度更快
3.如果sql模板一样,则只需要进行一次检查、编译