一、基本概念

1、概念

  • Java Database Connectivity:Java数据库连接

2、本质

  • SUN公司提供的操作所有关系型数据库的规则,是一套接口
  • 各厂商实现此接口,提供相应的驱动jar包供我们使用‘’
    • jar包内是编译好的字节码文件
    • src目录对应开源的源码文件
  • 真正执行的是jar包中的实现类

3、快速入门

  • 导入jar包到libs目录下,右键add as libarary
  • 执行过程
    • 注册驱动
    • 驱动管理类DriverManager获取连接对象
    • 定义sql并获取sql执行对象Statement/预编译sql对象PreparedStatement
    • 执行sql接收返回结果(通过结果集对象ResultSet)并进行处理
    • 释放资源,避免内存泄露
package cn.itcast.jdbc;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
/**
* JDBC快速入门
*/
public class JdbcDemo1 {
public static void main(String[] args) throws Exception{
//1.导入驱动jar包mysql-connector-java-5.1.37-bin.jar
//创建libs文件夹便于管理
//复制后右键,add as library
//2.注册驱动
Class.forName("com.mysql.jdbc.Driver");
//3.获取数据库的连接对象
Connection conn= DriverManager.getConnection("jdbc:mysql://localhost:3306/db3","root","root");
//4.定义一个SQL语句
String sql="update account set balance = 500 where id=1";//sql语句后不用加分号
//5.获取SQL的执行对象
Statement stmt = conn.createStatement();
//6.执行SQL
int count = stmt.executeUpdate(sql);
//7.处理结果,打印
System.out.println(count);
//8.释放资源
stmt.close();
conn.close();
}
}

二、各个对象详解

1、DriverManager--注册驱动、获取连接

  • 注册驱动:Class.forName("com.mysql.jdbc.Driver");

    • 作用同DriverManager.registerDriver(Driver driver)---Dirver类的静态代码块中包含
    • MySQL5后可以省略
  • 获取连接:
    • Connection conn= DriverManager.getConnection("jdbc:mysql://localhost:3306/db3","root","root");
    • URL本地3306端口可以简写为:jdbc:mysql///数据名

2、Connection--获取执行对象、事务管理

  • 获取执行对象:

    • Statement stmt = conn.createStatement();
    • PreparedStatement pstmt = conn.prepareStatement(String sql);
  • 管理事务:
    • 概念:多步操作,要么同时成功要么同时失败
    • 开启事务:conn.setAutoCommit(false)    
    • 提交事务:conn.commit()
    • 回滚事务:conn.rollback();

3、Statement--SQL执行

  • boolean execute(sql):任意语句
  • int executeUpdate(sql) :DDL/DML,DDL只会返回0
  • ResultSet executeQuery(String sql):DQL

4、ResultSet--结果集对象,封装查询结果

  • 通过游标rs.next()向下移动一行取结果rs.getInt(1)/getDouble("学号");

5、JDBCUtils--抽取工具类

  • 之前:每次都要注册驱动、获取连接
  • 现在:编写方法,并通过配置文件获取连接
package cn.itcast.utils;
import java.io.FileReader;
import java.io.IOException;
import java.net.URL;
import java.sql.*;
import java.util.Properties; /**
* JDBC工具类
* 一个获取连接的方法
* 一个释放资源的方法
*/
public class JDBCUtils {
private static String url;
private static String user;
private static String password;
private static String driver;
/**
* 文件的读取,只需要读取一次就可以拿到这些值
* 方案:通过静态代码块
*/
static{
//读取配置资源文件,获取值
//BufeeredReader。。。麻烦
try {
//1.创建Properties集合类
Properties prop=new Properties();
//2.加载文件,代码提示
//prop.load(new FileReader("src/jdbc.properties"));
//找不到资源文件,最笨的方法---可以写绝对路径D:\IdeaProjects\liujinhui\day04_jdbc_20201220\src\jdbc.properties
//另外:获取src路径下的文件--->ClassLoader 类加载器:可以 加载字节码文件进内存,同时可以获取src下的资源文件
ClassLoader classLoader = JDBCUtils.class.getClassLoader();
//传的是以src相对的文件路径
//返回统一资源定位符,即文件的绝对路径
URL res= classLoader.getResource("jdbc.properties");
String path = res.getPath();
System.out.println(path);
prop.load(new FileReader(path));
//3.获取数据,赋值
url=prop.getProperty("url");
user=prop.getProperty("user");
password=prop.getProperty("password");
driver=prop.getProperty("driver");
//4.注册驱动
Class.forName(driver);
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
//Arrays等都是静态,方便类直接调用
/**
* 获取连接的工具方法
* @return 连接对象
*/
//String url,String root,String password有参数仍然很麻烦
//通过私有变量、配置文件及静态代码块解决
public static Connection getConnection() throws SQLException{
return DriverManager.getConnection(url,user,password);
}
/**
* 释放资源
* @param stmt
* @param conn
*/
public static void close(Statement stmt,Connection conn){
if (stmt!=null){
try {
stmt.close();
//conn.close();多个语句要放到多个try..catch中
} catch (SQLException e) {
e.printStackTrace();
}
}
if (conn!=null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
/**
* 释放资源
* @param rs
* @param stmt
* @param conn
*/
public static void close(ResultSet rs, Statement stmt, Connection conn){
if (stmt!=null){
try {
stmt.close();
//conn.close();多个语句要放到多个try..catch中
} catch (SQLException e) {
e.printStackTrace();
}
}
if (conn!=null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (rs!=null){
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
  • 测试
public class JDBCDemo8 {
public static void main(String[] args) {
//想调用非静态方法,则需要创建对象
List<Emp> list = new JDBCDemo8().findAll2();
System.out.println(list);
}
/**
* 演示JDBC工具类
* @return
*/
public List<Emp> findAll2(){
Connection conn=null;
Statement stmt=null;
ResultSet rs=null;
List<Emp> list=null;
try {
//1.注册驱动
//Class.forName("com.mysql.jdbc.Driver");//最好写,写上可以向下兼容
//2.获取连接
//conn = DriverManager.getConnection("jdbc:mysql:///db3", "root", "root");
conn=JDBCUtils.getConnection();
//3.定义sql
String sql="select * from emp";
//4.获取执行sql的对象
stmt = conn.createStatement();
//5.执行sql
rs = stmt.executeQuery(sql);
//6.遍历结果集,封装对象,装载集合
Emp emp=null;
list = new ArrayList<>();
while(rs.next()){
//获取数据
int id = rs.getInt("id");
String ename = rs.getString("ename");
int job_id = rs.getInt("job_id");
int mgr = rs.getInt("mgr");
//怎么把光标放上就能显示概述?
//Date是sql包下的类,继承了util的date,子类继承父类
Date joindate = rs.getDate("joindate");
double salary = rs.getDouble("salary");
double bonus = rs.getDouble("bonus");
int dept_id = rs.getInt("dept_id");
//封装对象,对象引用复用
emp=new Emp();
emp.setId(id);
emp.setBonus(bonus);
emp.setDept_id(dept_id);
emp.setEname(ename);
emp.setJoindate(joindate);
emp.setMgr(mgr);
emp.setSalary(salary);
list.add(emp);
}
}catch (SQLException e) {
e.printStackTrace();
}finally {
JDBCUtils.close(rs,stmt,conn);
}
return list;
}
}  

6、PreparedStatement:预编译SQL执行对象

  • 之前问题:SQL注入问题
  • 预编译的SQL,使用?作为占位符
  • 好处:解决SQL注入,效率更高
package cn.itcast.jdbc;

import cn.itcast.utils.JDBCUtils;

import java.sql.*;
import java.util.Scanner; /**
* 使用PrepareStatement实现登录操作
* 练习:
通过键盘录入用户名和密码
判断用户名是否登录成功
*/
public class JDBCDemo10 {
public static void main(String[] args) {
//1.键盘录入,接收用户名和密码
Scanner sc=new Scanner(System.in);
System.out.println("请输入用户名:");
String username = sc.nextLine();
System.out.println("请输入密码:");
String password = sc.nextLine();
//2.调用方法
//静态调用非静态需要声明对象
boolean flag = new JDBCDemo10().login(username, password);
//3.判断结果,输出不同语句
if (flag){
//登录成功
System.out.println("登录成功");
}else{
System.out.println("用户名或密码错误");
} //2.调用方法 //3.判断结果,输出不同语句
}
/**
* 登录方法
*/
public boolean login(String username ,String password){
if (username==null||password==null){
return false;
}
Connection conn=null;
PreparedStatement pstmt=null;
ResultSet rs=null;
try {
//连接数据库判断是否登录成功
//1.获取连接,更改数据库只需要修改配置文件,可扩展性强
conn = JDBCUtils.getConnection();
//2.定义 sql
String sql="select * from user where username= ? and password= ?";
//System.out.println(sql);
//3.获取执行SQL的对象
pstmt = conn.prepareStatement(sql);
//给 ?赋值
pstmt.setString(1,username);
pstmt.setString(2,password);
//4.执行查询
rs =pstmt.executeQuery();
//5.判断
/*if (rs.next()){
return true;
}else{
return false;
}*/
//直接返回
return rs.next();
} catch (SQLException e) {
e.printStackTrace();
}finally {
JDBCUtils.close(rs,pstmt,conn);
}
return false;
}
}

三、使用JDBC控制事务

1、注意

  • 在执行sql之前开启事务setAutoCommit()
  • 在当所有sql执行完提交事务
  • catch中回滚事务

2、使用(转账操作等)

package cn.itcast.jdbc;

import cn.itcast.utils.JDBCUtils;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException; /**
* 事务操作
*/
public class JDBCDemo11 { public static void main(String[] args) {
Connection conn=null;
PreparedStatement pstmt1=null;
PreparedStatement pstmt2=null;
try {
//1.获取连接
conn = JDBCUtils.getConnection();
//开启事务
conn.setAutoCommit(false);
//2,定义SQL
//2.1 张三-500
//String sql1="update account set balance=balance-500 where id=1";
//2.2 李四+500
//String sql2="update account set balance=balance+500 where id=2";
//通用写法
String sql1="update account set balance=balance-? where id=?";
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();
//使用大异常
} catch (Exception e) {
try { //事务回滚,前提不为null
if (conn!=null){
conn.rollback();
}
} catch (SQLException e1) {
e1.printStackTrace();
}
e.printStackTrace();
}finally {
JDBCUtils.close(pstmt1,conn);
JDBCUtils.close(pstmt2,null);
} }
}

【Java EE】Day05 JDBC概念、对象、控制事务的更多相关文章

  1. Java EE JSP内置对象及表达式语言

    一.JSP内置对象 JSP根据Servlet API规范提供了一些内置对象,开发者不用事先声明就可使用标准变量来访问这些对象. JSP提供了9种内置对象: (一).request 简述: JSP编程中 ...

  2. Java EE (9) -- JDBC & JTA

    Connection接口中定义了5中隔离级别常量 Connection.TRANSACTION_NONE  --  不支持事务 Connection.TRANSACTION_READ_UNCOMMIT ...

  3. Java EE.JSP.内置对象

    JSP根据Servlet API 规范提供了某些内置对象,开发者不用事先声明就可以使用标准的变量来访问这些对象.JSP提供了九中内置对象:request.response.out.session.ap ...

  4. JAVA企业级开发-jdbc事务,数据库连接池(10)

    一.   JDBC事务 事务: 问题1.什么是事务 问题2.java中(jdbc)如何控制事务 1. 事务—重点 指的的逻辑上的一组(一组sql,insert update ,delete)操作,组成 ...

  5. 【Java EE 学习 52】【Spring学习第四天】【Spring与JDBC】【JdbcTemplate创建的三种方式】【Spring事务管理】【事务中使用dbutils则回滚失败!!!??】

    一.JDBC编程特点 静态代码+动态变量=JDBC编程. 静态代码:比如所有的数据库连接池 都实现了DataSource接口,都实现了Connection接口. 动态变量:用户名.密码.连接的数据库. ...

  6. Java数据库连接--JDBC调用存储过程,事务管理和高级应用

    相关链接:Jdbc调用存储过程 一.JDBC常用的API深入详解及存储过程的调用 1.存储过程的介绍 我们常用的操作数据库语言SQL语句在执行的时候要先进行编译,然后执行,而存储过程是在大型数据库系统 ...

  7. spring事务:事务控制方式,使用AOP控制事务,七种事务传播行为,声明事务,模板对象,模板对象原理分析

    知识点梳理 课堂讲义 1)事务回顾 1.1)什么是事务-视频01 事务可以看做是一次大的活动,它由不同的小活动组成,这些活动要么全部成功,要么全部失败. 1.2)事务的作用 事务特征(ACID) 原子 ...

  8. JDBC(三)----JDBC控制事务

    ##  JDBC控制事务 1.事务:一个包含多个步骤的业务操作.如果这个业务员操作被事务管理,则这多个步骤要么同时成功,要么同时失败. 2.操作: 1.开启事务 2.提交事务 3.回滚事务 3.使用C ...

  9. ActiveX数据对象之事务控制在VB和DELPHI中的应用

            本文发表在中国人民解放军"信息工程大学"学报 2001年第3期.        ActiveX数据对象之事务控制在VB和DELPHI中的应用             ...

  10. (未使用AOP)使用ThreadLocal对象把Connection和当前线程绑定, 从而使一个线程中只有一个能控制事务的对象

    每个连接都有自己的独立事务,会造成数据的不一致 这组操作应该要么一起操作成功,要么一起操作失败, 应该使用同一个连接,只有一个能控制事务的对象 需要使用ThreadLocal对象把Connection ...

随机推荐

  1. ProxySQL 密码管理

    ProxySQL是一个协议感知的proxy.由于ProxySQL基于流量进行路由,当一个客户端连接ProxySQL时,它还无法识别它的目标主机组,因此ProxySQL需要对该客户端进行认证.基于此,需 ...

  2. 使用logstash读取MySQL数据传输到es,并且@timestamp字段采用MySQL中的字段时间--建议采用这个

    MySQL中数据样式 ES中数据样式 input { jdbc { jdbc_connection_string => "jdbc:mysql://192.168.0.145:3306 ...

  3. 使用Docker Compose部署SpringCloud项目docker-compose.yml文件示例

    注意各组件之间的依赖关系 microservice-discovery-eureka: image: reg.itmuch.com/microservice-discovery-eureka port ...

  4. 老杜MySql——34道作业题

    老杜MySql链接:https://www.bilibili.com/video/BV1Vy4y1z7EX?p=132 本次随笔主要来源于老杜MySql讲解视频后面的作业题,加上个人的一些理解,以及整 ...

  5. 【linux】 第1回 linux运维基础

    目录 1. 运维的本质 2. 电脑与服务器 2.1 电脑的种类 2.2 服务器种类 2.3 服务器品牌 2.4 服务器尺寸 2.5 服务器内部组成 3. 磁盘阵列 4. 系统简介 5. 虚拟化 6. ...

  6. 手写自定义springboot-starter,感受框架的魅力和原理

    一.前言 Springboot的自动配置原理,面试中经常问到,一直看也记不住,不如手写一个starter,加深一下记忆. 看了之后发现大部分的starter都是这个原理,实践才会记忆深刻. 核心思想: ...

  7. 参考Dubbo3官方文档做的学习笔记

    文章目录 概念与架构 2.1 服务发现 Dubbo3官方文档: https://dubbo.apache.org 服务:是 Dubbo 中的核心概念,一个服务代表一组 RPC 方法的集合,服务是面向用 ...

  8. 靶机: easy_cloudantivirus

    靶机: easy_cloudantivirus 准备 下载靶机(Target):https://www.vulnhub.com/entry/boredhackerblog-cloud-av,453/ ...

  9. 禁忌搜索算法TSA 旅行商问题TSP python

    import math import random import numpy as np import matplotlib.pyplot as plt from mpl_toolkits.mplot ...

  10. adb 安装与使用

    什么是adb adb 是有个通用命令行工具 他允许您与模拟器实例或者链接的Android设备进行通信,他可为各种设备操作提供便利,比如安装和调试应用 启动adb 服务在命令行中输入adb start- ...