JDBC概述
为什么要使用JDBC?
JDBC:java database connectivity SUN公司提供的一套操作数据库的标准规范。
JDBC与数据库驱动的关系:接口与实现的关系。
JDBC本质:其实是官方(sun公司)定义的一套操作所有关系型数据库的规则,即接口。各个数据库厂商去实现这套接口,提供数据库驱动jar包。我们可以使用这套接口(JDBC)编程,真正执行的代码是驱动jar包中的实现类。
JDBC规范(掌握四个核心对象):
DriverManager:用于注册驱动
Connection: 表示与数据库创建的连接
Statement: 操作数据库sql语句的对象
ResultSet: 结果集或一张虚拟表
开发一个JDBC程序(重要)
实现查询数据库中的数据显示在java的控制台中
1.创建数据库及表,并初始化一些数据
2.创建Java project项目,并添加数据库依赖(*.jar)
3.实现JDBC操作
// 1、注册驱动
// 2、创建连接
// 3、得到执行sql语句的Statement对象
// 4、执行sql语句,并返回结果
// 5、处理结果
// 6、关闭资源
//1、注册驱动
// DriverManager.registerDriver(new Driver()); // 不建议使用
Class.forName(“com.mysql.cj.jdbc.Driver”);
//2、获取连接Connection
Connection conn = DriverManager.getConnection(“jdbc:mysql://localhost:3306/hs_test?serverTimezone=Asia/Shanghai”, “root”, “root”);
//?serverTimezone=GMT%2B8
//3、得到执行sql语句的对象Statement
Statement stmt = conn.createStatement();
//4、执行sql语句,并返回结果
ResultSet rs = stmt.executeQuery(“select id,name,chinese,english,math from student”);
//5、处理结果
while(rs.next()){
System.out.println(rs.getObject(“id”));
System.out.println(rs.getObject(“name”));
System.out.println(rs.getObject(“chinese”));
System.out.println(rs.getObject(“english”));
System.out.println(rs.getObject(“math”));
System.out.println("-----------------");
}
//6、关闭资源
rs.close();
stmt.close();
conn.close();
JDBC增删改查
工具类:
将连接与关闭操作抽成一个工具类
public class DBUtils {
private static String driverClass;
private static String url;
private static String username;
private static String password;
static {
//此对象是用于加载yml文件数据的
ResourceBundle rb = ResourceBundle.getBundle("dbinfo");
driverClass = rb.getString("driverClass");
url = rb.getString("url");
username = rb.getString("username");
password = rb.getString("password");
System.out.println("driverClass======"+driverClass);
System.out.println("url======"+url);
System.out.println("username======"+username);
System.out.println("password======"+password);
try {
Class.forName(driverClass);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
//得到连接的方法
public static Connection getConnection() throws Exception{
return DriverManager.getConnection(url, username, password);
}
//关闭资源的方法
public static void closeAll(ResultSet rs, Statement stmt, Connection conn){
//关闭资源
if(rs!=null){
try {
rs.close();
} catch (Exception e) {
e.printStackTrace();
}
rs = null;
}
if(stmt!=null){
try {
stmt.close();
} catch (Exception e) {
e.printStackTrace();
}
stmt = null;
}
if(conn!=null){
try {
conn.close();
} catch (Exception e) {
e.printStackTrace();
}
conn = null;
}
}
}
新增:
@Test
public void testInsert(){
Connection conn = null;
PreparedStatement stmt = null;
Statement statement = null;
try {
conn = DBUtils.getConnection();
statement = conn.createStatement();
int i = statement.executeUpdate(“INSERT INTO student VALUES(9,“老刘”,85.45,78.32,63.98)”);
/stmt = conn.prepareStatement(“INSERT INTO student VALUES(?,?,?,?,?)”);
stmt.setInt(1, 9);
stmt.setString(2, “老刘”);
stmt.setDouble(3, 85.45);
stmt.setDouble(4, 78.32);
stmt.setDouble(5, 63.98);/
// int i = stmt.executeUpdate();
if(i>0){
System.out.println("success");
}
} catch (Exception e) {
e.printStackTrace();
}finally{
DBUtils.closeAll(null, stmt, conn);
}
}
查询
@Test
public void testSelect (){
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
try {
conn = DBUtils.getConnection();
stmt = conn.createStatement();
rs = stmt.executeQuery("select * from student");
List<Student> list = new ArrayList<Student>();
while(rs.next()){
Student student = new Student();
student.setId(rs.getInt(1));
student.setName(rs.getString(2));
student.setChinese(rs.getDouble(3));
student.setEnglish(rs.getDouble(4));
student.setMath(rs.getDouble(5));
list.add(student);
}
for (Student student : list) {
System.out.println(student);
}
} catch (Exception e) {
e.printStackTrace();
}finally{
DBUtils.closeAll(rs, stmt, conn);
}
}
更新
@Test
public void testUpdate(){
Connection conn = null;
PreparedStatement stmt = null;
try {
conn = DBUtils.getConnection();
stmt = conn.prepareStatement(“UPDATE student SET NAME=? WHERE id=?”);
stmt.setString(1, “jerry123”);
stmt.setInt(2, 8);
int i = stmt.executeUpdate();
if(i>0){
System.out.println("success");
}
} catch (Exception e) {
e.printStackTrace();
}finally{
DBUtils.closeAll(null, stmt, conn);
}
}
删除
@Test
public void testDelete(){
Connection conn = null;
Statement stmt = null;
try {
conn = DBUtils.getConnection();
stmt = conn.createStatement();
int i = stmt.executeUpdate("DELETE FROM student WHERE id=9");
if(i>0){
System.out.println("success");
}
} catch (Exception e) {
e.printStackTrace();
}finally{
DBUtils.closeAll(null, stmt, conn);
}
}
JDBC之Statement与PreparedStatement
一般使用preparedStatement执行sql语句,因为效率高,还可以有效防止sql注入问题。
在JDBC应用中,如果你已经是稍有水平开发者,你就应该始终以PreparedStatement代替Statement.也就是说,在任何时候都不要使用Statement。
PreparedStatement接口继承Statement;作为 Statement 的子类,PreparedStatement 继承了 Statement 的所有功能。
PreparedStatement 实例包含已编译的 SQL 语句,由于 PreparedStatement 对象已预编译过,所以其执行速度要快于 Statement 对象。
JDBC管理事务
在执行SQL语句之前,先执行start transaction,这就开启了一个事务(事务的起点),然后可以去执行多条SQL语句,最后要结束事务,commit表示提交,即事务中的多条SQL语句所作出的影响会持久到数据库中,或者rollback,表示回滚到事务的起点,之前做的所有操作都被撤销了。
开启事务:setAutoCommit(boolean autoCommit) :调用该方法设置参数为false,即开启事务
提交事务:commit()
回滚事务:rollback() 在catch中回滚事务
@Test
public void testTransaction(){
Connection conn = null;
PreparedStatement pstmt1 = null;
PreparedStatement pstmt2 = null;
try {
//1.获取连接
conn = DBUtils.getConnection();
//开启事务
conn.setAutoCommit(false);
//2.定义sql
//2.1 张三 - 500
String sql1 = "update account set balance = balance - ? where id = ?";
//2.2 李四 + 500
String sql2 = "update account set balance = balance + ? where id = ?";
//3.获取执行sql对象
pstmt1 = conn.prepareStatement(sql1);
pstmt2 = conn.prepareStatement(sql2);
//4. 设置参数
pstmt1.setDouble(1,500);
pstmt1.setInt(2,1);
pstmt2.setDouble(1,500);
pstmt2.setInt(2,2);
//5.执行sql
pstmt1.executeUpdate();
// 手动制造异常
// int i = 3/0;
pstmt2.executeUpdate();
//提交事务
conn.commit();
System.out.println("===执行成功===");
} catch (Exception e) {
//事务回滚
try {
if(conn != null) {
conn.rollback();
}
} catch (SQLException e1) {
e1.printStackTrace();
}
e.printStackTrace();
}finally {
DBUtils.closeAll(null, pstmt1, conn);
DBUtils.closeAll(null, pstmt2, conn);
}
}