文章目录
1. JDBC
JDBC java数据库连接
Java Database Connectivity
JAVA在JDBC中提供一套通用的接口,用于连接和操作数据库。不同的数据库厂商都提供了一套对应的实现类来操作自家提供的 DBMS。而这套实现类也称为连接该DBMS的驱动(Driver)
使用步骤:
1:加载对应数据库厂商提供的驱动(MAVEN添加依赖即可)
2:基于标准的JDBC操作流程操作该数据库
1.1配置驱动
在maven的pom.xml项目中添加阿里的依赖
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.15</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.21</version>
</dependency>
</dependencies>
1.2 创建一个DBUtil类用于调用驱动
package jdbc;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
/**
* 管理数据库连接
*/
public class DBUtil {
static {
try {
//DBUtil第一次被使用时先加载数据库驱动
Class.forName("com.mysql.cj.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
public static Connection getConnection() throws SQLException {
// return DriverManager.getConnection("jdbc:mysql://localhost:3306/tedu?characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true","root","root");
return DriverManager.getConnection("jdbc:mysql://localhost:3306/birdbootdb?characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true","root","root");
}
}
2. 标准的JDBC操作流程:
1:加载驱动:Class.forName(“不同厂商提供的Driver的实现类”)
不同厂商提供的Driver实现类的名字不同,但是每个数据库是固定的。
DriverManager.getConnection(String url,String username,String password)
- 参数1:数据库路径(JDBC有格式要求,但是不同厂商在规定的格式中又有自身不同的地方)
- 参数2:数据库的用户名
- 参数3:数据库的密码
- 返回值类型:Connection
该方法返回的Connection实例就表示与数据库的一条连接。
Connection是JDBC的一个核心接口,它用于表与数据库的一个连接,里面提供了创建执行对象,关闭连接等操作
2:与数据库建立连接。使用DriverManager.getConnection()
mysql的url固定格式
jdbc:mysql://localhost:3306/birdbootdb?characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true
^^^^^^^^^^
数据库名称
相当于USE birdbooddb
3:通过Connection创建执行对象Statement
Statement用于指定SQL语句
Statement对象是用于执行SQL语句的对象
4:使用Statement执行SQL(CRUD)
如果执行的是DQL语句,则还要接收查询结果集并遍历获取查询结果。
执行SQL语句
boolean execute(sql)
该方法可以执行任意类型的sql语句。
由于执行DML,DQL都有专属的方法,因此execute方法通常仅用来执行DDL语句
该方法返回值为boolean值。当执行的SQL有查询结果集时,返回值为true。
package jdbc;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
public class JDBCDemo1 {
public static void main(String[] args) throws ClassNotFoundException, SQLException {
//步骤1
Class.forName("com.mysql.cj.jdbc.Driver");
//步骤2
Connection conn=DriverManager.getConnection("jdbc:mysql://localhost:3306/birdbootdb?characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true","root","root");
System.out.println("与数据库建立连接!");
//步骤3 Statement对象是用于执行SQL语句的对象
Statement state = conn.createStatement();
// 创建一张表userinfo
// 表字段:id,username,password,nickname,age
String sql = "CREATE TABLE userinfo(" +
" id INT PRIMARY KEY AUTO_INCREMENT," +
" username VARCHAR(30)," +
" password VARCHAR(30)," +
" nickname VARCHAR(30)," +
" age INT(3)" +
")";
System.out.println(sql);
//执行SQL语句
state.execute(sql);
System.out.println("执行完毕!");
conn.close();
}
}
4.1 执行INSERT语句
package jdbc;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
import java.util.Scanner;
/**
* 执行INSERT语句
*/
public class JDBCDemo2 {
public static void main(String[] args) throws Exception {
Class.forName("com.mysql.cj.jdbc.Driver");
Connection conn= DriverManager.getConnection("jdbc:mysql://localhost:3306/birdbootdb?characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true","root","root");
System.out.println("与数据库建立连接!");
Statement state = conn.createStatement();
// String sql = "INSERT INTO userinfo(username,password,nickname,age) " +
// "VALUES ('张三','123456','阿三',16)";
System.out.println("欢迎注册:");
Scanner scanner = new Scanner(System.in);
System.out.println("请输入用户名");
String username = scanner.nextLine();
System.out.println("请输入密码");
String password = scanner.nextLine();
System.out.println("请输入昵称");
String nickname = scanner.nextLine();
System.out.println("请输入年龄");
int age = scanner.nextInt();
String sql = "INSERT INTO userinfo(username,password,nickname,age) " +
"VALUES ('" + username + "','" + password + "','" + nickname + "'," + age + ")";
System.out.println(sql);
/*
int executeUpdate(String sql)
该方法用于执行DML语句(增删改),返回值为执行该条SQL语句后影响了表中多少条记录
*/
int sum = state.executeUpdate(sql);//对于insert而言,应当插入后影响了表中1条记录
if(sum>0){//至少影响了表中一条记录
System.out.println("插入成功!");
}else{
System.out.println("插入失败!");
}
conn.close();
}
}
4.2 执行UPDATE
package jdbc;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
/**
* 执行UPDATE
*/
public class JDBCDemo3 {
public static void main(String[] args) throws Exception {
Class.forName("com.mysql.cj.jdbc.Driver");
Connection conn= DriverManager.getConnection("jdbc:mysql://localhost:3306/birdbootdb?characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true","root","root");
System.out.println("与数据库建立连接!");
Statement state = conn.createStatement();
//将张三的年龄改为56岁
String sql = "UPDATE userinfo " +
"SET age=56 " +
"WHERE username='张三'";
int sum = state.executeUpdate(sql);
System.out.println("修改了表中"+sum+"条记录");
conn.close();
}
}
4.3 执行DELETE
package jdbc;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
/**
* 执行DELETE
*/
public class JDBCDemo4 {
public static void main(String[] args) throws Exception {
Class.forName("com.mysql.cj.jdbc.Driver");
Connection conn= DriverManager.getConnection("jdbc:mysql://localhost:3306/birdbootdb?characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true","root","root");
System.out.println("与数据库建立连接!");
Statement state = conn.createStatement();
String sql = "DELETE FROM userinfo " +
"WHERE username='张三'";
int sum = state.executeUpdate(sql);
System.out.println("删除了表中"+sum+"条记录");
conn.close();
}
}
4.4 执行DQL语句
package jdbc;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
/**
* 执行DQL语句
*/
public class JDBCDemo5 {
public static void main(String[] args) throws Exception {
Class.forName("com.mysql.cj.jdbc.Driver");
Connection conn= DriverManager.getConnection("jdbc:mysql://localhost:3306/tedu?characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true","root","root");
System.out.println("与数据库建立连接!");
Statement state = conn.createStatement();
/*
查看所有老师的id,名字,工资,职称,年龄
*/
String sql = "SELECT id,name,age,salary,title " +
"FROM teacher";
/*
ResultSet executeQuery(String sql)
执行DQL语句,并且返回查询结果集。
ResultSet结果集。该类的每一个实例表示一个查询出来的结果集。
*/
ResultSet rs = state.executeQuery(sql);
/*
ResultSet遍历结果集对应的方法:
1:
boolean next()
该方法会让结果集指针向下移动一条记录,并通过返回值表达是否存在该条记录。
true表达存在,false表达不存在。
注:结果集指针默认在结果集第一条记录之上。
获取字段值的相关方法
int getInt(String name)
根据字段名获取该字段的值(该字段是整数类型)
int getInt(int colIndex)
获取第几个字段的值(colIndex从1开始,1表是第一个字段。)
同理获取其他类型字段值时:
String getString(String name)
String getString(int colIndex)
double getDouble(...)
...
*/
while(rs.next()){
int id = rs.getInt("id");//获取结果集表示的当前记录中"id"字段的整数类型值。
// int id = rs.getInt(1);//获取结果集表示的当前记录中第一个字段的整数类型值。(这里要参考执行DQL时SELECT子句中字段的顺序)
String name = rs.getString("name");//name在teacher表中是VARCHAR类型,在JAVA中用String保存
String title = rs.getString("title");
int age = rs.getInt("age");
int salary = rs.getInt("salary");
System.out.println(id+","+name+","+title+","+age+","+salary);
}
conn.close();
}
}
ame = rs.getString("name");//name在teacher表中是VARCHAR类型,在JAVA中用String保存
String title = rs.getString("title");
int age = rs.getInt("age");
int salary = rs.getInt("salary");
System.out.println(id+","+name+","+title+","+age+","+salary);
}
conn.close();
}
}
5. 通过 PreparedStatement预编译执行SQL
package jdbc;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
/**
* 执行预编译SQL语句
*/
public class JDBCDemo8 {
public static void main(String[] args) throws SQLException {
Connection conn = DBUtil.getConnection();
/*
?仅能表达SQL中需要使用的值。?是不能影响语义的。
*/
String sql = "SELECT id,username,password,nickname,age " +
"FROM userinfo " +
"WHERE username=? AND password=?";
/*
当调用Connection的方法:prepareStatement(String sql)
就会先将预编译SQL发送给数据库,使之生成一个执行计划。
意思:当数据库接收到这条SQL时就会理解该SQL的作用,并生成一个内置的函数用来执行SQL表达的操作
准备后并不会立即执行,因为还缺少数据(预编译SQL中?部分是未知的)
当执行计划生成后,数据库方对于该SQL的语义就定死了。
方法返回的PreparedStatement实例表示的就是数据库端已经生成的执行计划。
我们现在需要做得就是通过PreparedStatement传递"?"对应的值就可以让数据库执行一次该执行计划。
*/
PreparedStatement ps = conn.prepareStatement(sql);
//为预编译SQL对应的"?"指定值时,要根据该"?"应有的数据类型调用对应的set方法。比如:setString(对应VARCHAR类型) setInt(对应INT类型)
ps.setString(1,"范传奇");//参数1表示预编译SQL中第几个"?",第二个参数为该问号对应的值
// ps.setString(2,"123456");
ps.setString(2,"123' OR '1'='1");//数据库仅会将它当作密码的值,不会改变SQL语义。
ResultSet rs = ps.executeQuery();
if(rs.next()){
int id = rs.getInt("id");
String username = rs.getString("username");
String password = rs.getString("password");
String nickname = rs.getString("nickname");
int age = rs.getInt("age");
System.out.println(id+","+username+","+password+","+nickname+","+age);
}else{
System.out.println("查无此人");
}
}
}
5.1 在DML语句中使用预编译SQL
package jdbc;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
/**
* 在DML语句中使用预编译SQL
*/
public class JDBCDemo9 {
public static void main(String[] args) throws SQLException {
Connection conn = DBUtil.getConnection();
//SQL语义:向userinfo表的username,password,nickname,age四个字段插入数据(未知)
String sql = "INSERT INTO userinfo (username,password,nickname,age) " +
"VALUES(?,?,?,?)";
PreparedStatement ps = conn.prepareStatement(sql);
ps.setString(1,"刘国斌");
ps.setString(2,"556677");
ps.setString(3,"国斌");
ps.setInt(4,26);
int sum = ps.executeUpdate();
if(sum>0){
System.out.println("插入成功");
}else{
System.out.println("插入失败");
}
conn.close();
}
}
5.2 预编译SQL在UPDATE中使用
package jdbc;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
/**
* 预编译SQL在UPDATE中使用
*/
public class JDBCDemo10 {
public static void main(String[] args) {
try (
Connection conn = DBUtil.getConnection();
){
String sql = "UPDATE userinfo " +
"SET nickname=?,age=? " +
"WHERE username=?";
PreparedStatement ps = conn.prepareStatement(sql);
ps.setString(1,"苍老师");
ps.setInt(2,66);
ps.setString(3,"刘苍松");
int sum = ps.executeUpdate();
System.out.println("修改了"+sum+"条记录");
} catch (SQLException e) {
e.printStackTrace();
}
}
}