JDBC基础
一、JDBC基本概念
1.概念
JDBC是 Java DataBase Connectivity 的缩写,Java语言操作数据库。
JDBC本质是官方(sun公司)定义的一套操作所有关系型数据库的规则,即接口。各个数据库厂商去实现这套接口,提供数据库驱动jar包。我们可以使用这套接口(JDBC)编程,真正执行的代码是驱动jar包中的实现类。
2.快速入门
步骤:
public static void main(String[] args) throws Exception {
//1.导入驱动jar包,一般系统会自动导入
//Class.forName("com.mysql.cj.jdbc.Driver");
//2.获取数据库连接对象
Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/test?serverTimezone=UTC&characterEncoding=utf-8&useSSL=true", "root", "root");
//3.定义sql语句
String sql = "update stu1 set age = 20 where id=1";
//4.获取执行sql的对象
Statement stmt = connection.createStatement();
//5.执行sql语句
long l = stmt.executeLargeUpdate(sql);
//6.处理结果
System.out.println(l);//1 表示影响1行数据
//7.释放资源
stmt.close();
connection.close();
}
3.各个对象的详解
1.Drivermanager:驱动管理对象
-
注册驱动:告诉程序该使用哪一个数据库驱动jar
static void registerDriver(Driver driver):
注册与给定的驱动程序Drivermanager。写代码使用:
Class.forName("com.mysql.jdbc.Driver");
通过查看源码发现在com.mysql.jdbc.Driver类中存在静态代码块:
static { try { DriverManager.registerDriver(new Driver()); } catch (SQLException var1) { throw new RuntimeException("Can't register driver!"); } }
注意:mysql5之后的驱动jar包可以省略注册驱动的步骤。
-
获取数据库连接:
static Connection getConnection(String url,String user,String password):
连接数据库。参数:
-
url:指定连接的路径。
语法:jdbc:mysql://ip地址(域名):端口号/数据库名称…
如果连接的是本机mysql服务器,并且mysql服务器默认端口是3306,则url可以简写为:jdbc:mysql:///数据库名称…
-
user:数据库用户名
-
password:密码
-
2.Connection:数据库连接对象
- 获取执行sql的对象
Statement createStatement()
PreparedStatement preparedStatement(String sql)
- 管理事务
1. 开启事务:setAutoCommit(boolean antoCommit):
调用该方法设置参数false,即开启事务。
2. 提交事务:commit()
3. 回滚事务:rollback()
3.Statement:执行sql的对象
-
执行sql
1.
boolean execute(String sql):
可以执行任意的sql(不常用,作为了解)。2.
int executeUpdate(String sql):
执行(insert、update、delete)语句、DDL(create、alter、drop)语句,返回值为影响的行数,可以通过影响的行数来判断DML语句是否执行成功。 -
练习
1.在表中,添加一条记录。
public class Demo2 {
public static void main(String[] args) {
Connection connection = null;
Statement statement = null;
try {
connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/test?serverTimezone=UTC&characterEncoding=utf-8&useSSL=true", "root", "root");
statement = connection.createStatement();
String sql = "insert into stu1(id,name,age) value(null,'小花',21)";
int i = statement.executeUpdate(sql);
if (i>0){
System.out.println("执行成功~");
}else {
System.out.println("执行失败~");
}
} catch (SQLException e) {
e.printStackTrace();
}finally {
if (statement!=null){
try {
statement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (connection!=null){
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}
2.在表中,修改记录。
public class Demo2 {
public static void main(String[] args) {
Connection connection = null;
Statement statement = null;
try {
connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/test?serverTimezone=UTC&characterEncoding=utf-8&useSSL=true", "root", "root");
statement = connection.createStatement();
String sql = "update stu1 set age = 18 where name = '小花'";
int i = statement.executeUpdate(sql);
if (i>0){
System.out.println("执行成功~");
}else {
System.out.println("执行失败~");
}
} catch (SQLException e) {
e.printStackTrace();
}finally {
if (statement!=null){
try {
statement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (connection!=null){
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}
3.在表中,删除一条记录。
String sql = "delete from stu1 where name='小花'";
//修改sql语句即可,步骤与上面一致
4.ResultSet:结果集对象,封装查询结果
-
常用方法
boolean next():游标向下移一行,判断当前行是否最后一行末尾。
getXxx(参数):获取数据。Xxx:代表数据类型。如:int getInt(),int getString()。
-
使用步骤
- 游标向下移动一行
- 判断是否有数据
- 获取数据
-
代码演示
public static void main(String[] args) { Connection connection = null; Statement statement = null; try { connection = JDBCUtils.getConnection(); statement = connection.createStatement(); //添加一行数据 //String sql = "insert into stu1(id,name,age) value(null,'小花',21)"; //修改数据 //String sql = "update stu1 set age = 18 where name = '小花'"; //查询语句 String sql = "select * from stu1"; ResultSet rs = statement.executeQuery(sql); Stu1 stu = null; ArrayList<Stu1> list = new ArrayList<>(); while(rs.next()){ int id = rs.getInt(1);//查取第1列 String name = rs.getString("name");//查取列名为name int age = rs.getInt(3);//查取第3列 Date birthday = rs.getDate(4);//查取第4列 double math = rs.getDouble(5); double english = rs.getDouble(6); double language = rs.getDouble(7); stu = new Stu1(id,name,age,birthday,math,english,language); list.add(stu);//将stu对象添加到集合中 } //遍历集合 for (Stu1 stu1 :list){ System.out.println(stu1); } } catch (SQLException e) { e.printStackTrace(); }finally { JDBCUtils.close(statement,connection); } }
-
练习
需求:通过键盘输入用户名和密码,判断用户名是否登录成功。
public static void main(String[] args) { Scanner scanner = new Scanner(System.in); System.out.println("请输入您的用户名:"); String user = scanner.next(); System.out.println("请输入您的密码:"); String password = scanner.next(); login(user,password); } private static void login(String user,String password) { Connection connection = null; Statement statement = null; try { connection = JDBCUtils.getConnection(); statement = connection.createStatement(); //查询语句 String sql = "select * from tables where user = '"+user+"' and password = '"+password+"'"; ResultSet rs = statement.executeQuery(sql); if (rs.next()){ System.out.println("登陆成功"); }else { System.out.println("登陆失败~"); } } catch (SQLException e) { e.printStackTrace(); }finally { JDBCUtils.close(statement,connection); } }
以上代码存在sql注入问题:在拼接sql时,有一些sql的特殊关键字参与字符串的拼接,会造成安全问题。
5.PreparedStatement:执行sql对象
PreparedStatement对象就是专门解决sql注入问题的,它使用的是预编译的sql:参数使用?作为占位符,解决了sql注入问题。
后期都会使用PreparedStatement来完成增删改查的所有操作,它比Statement的效率高并且可以防止sql注入。
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入您的用户名:");
String user = scanner.nextLine();
System.out.println("请输入您的密码:");
String password = scanner.nextLine();
login(user,password);
}
private static void login(String user,String password) {
Connection connection = null;
PreparedStatement pstate = null;
ResultSet rs = null;
try {
connection = JDBCUtils.getConnection();
//查询语句
String sql = "select * from tables where user = ? and password = ?";
//传递sql语句
pstate = connection.prepareStatement(sql);
//给占位符赋值
pstate.setString(1,user);//第一个占位符
pstate.setString(2,password);//第二个占位符
//执行sql语句
rs = pstate.executeQuery();
if (rs.next()){
System.out.println("登陆成功");
}else {
System.out.println("登陆失败~");
}
} catch (SQLException e) {
e.printStackTrace();
}finally {
JDBCUtils.close(rs,pstate,connection);
}
}
二、JDBC控制事务
1.事务
一个包含多个步骤的业务操作,如果这个业务操作被事务管理,则这多个步骤要么同时成功,要么同时失败。
2.操作
- 开启事务
- 提交事务
- 回滚事务
3.使用Connection对象来管理事务
- 开启事务:
setAutoCommit(boolean autoCommit):
调用该方法设置参数为false,即开启事务。(在执行sql之前使用) - 提交事务:
commit():
(当所有sql都执行完成提交事务) - 回滚事务:
rollback():
(在catch中回滚事务)