学习目标
JDBC 概念
JDBC (Java DataBase Connectivity
)
Java数据库连接技术的简称,提供连接各种常用数据库的能力
说白了就是java语言连接数据库
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| 有一个程序员,他要写一套程序,但是他不知道公司用什么数据库
所以,他就得学java连mysql连Oracle,连DB2, 市面上所有的关系型数据库,他都得学习一遍,对吧!
而我们期望使用统一的一套Java代码可以操作所有的关系型数据库 有一个程序员终于忍不住了,写了个JDBC JDBC:定义了操作所有关系型数据库的规则(接口)
这里只是写了接口,但是没有写具体的实现类,那么这个实现类谁写呢
sun公司说了,每一个数据库的厂商你们自己写实现类 所以每个数据库厂商都写了不同的实现类,不同版本的实现类
我们给这个实现类起了个名字,叫做数据库驱动
|
JDBC
本质:其实就是官方(Sun
公司)定义的一套操作所有关系型数据库的规则,及接口.
各个数据库厂商去实现这套接口,提供数据库驱动jar
包.我们可以使用这套接口(JDBC
)编程,真正执行的代码是驱动jar
包中的实现类.
JDBC
快速入门
步骤:
- 导入驱动
jar
包
官网mysql
驱动jar
包下载地址:mysql/mysql-connector-java
- 复制
mysql-connector-java-5.1.37.jar
- 右键–>
Add as library
- 注册驱动
- 获取数据库的连接对象
- 定义
sql
- 获取执行
sql
语句的对象 statement
- 执行
sql
,接收返回结果
- 处理结果
- 释放资源
实例代码
别管能不能看懂,直接我就上一堆代码,然后再解释
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| package cn.itcast.jdbc;
import java.sql.Connection; import java.sql.DriverManager; import java.sql.Statement;
public class JdbcDemo01 {
public static void main(String[] args) throws Exception { Class.forName("com.mysql.jdbc.Driver"); Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/plan","root","");
String sql = "use plan"; Statement stmt = conn.createStatement(); int count = stmt.executeUpdate(sql); System.out.println(count); stmt.clearBatch(); conn.close(); } }
|
详解各个对象
DriverManager
:
驱动管理对象,用于管理JDBC
驱动, 功能如下:
1. 注册驱动
- 注册与给定的驱动程序
static void registerDriver(Driver driver)
- 写代码使用:
Class.forName("com.mysql.jdbc.Driver");
好像这个类中有一个静态代码块,这里面有现成的代码
- 通过查看源码发现:在
com.mysql.jdbc.Driver
类中存在静态代码块1 2 3 4 5 6 7
| static { try { DriverManager.registerDriver(new Driver()); } catch (SQLException var1) { throw new RuntimeException("Can't register driver!"); } }
|
- 补充:
- 在
mysql-connector-java-5.1.37.jar
的5
版本之后
- 有一个文件在
mysql-connector-java-5.1.37.jar/META-INF/services/java.sql.Driver
里面
- 这个文件可以让你省略注册驱动的步骤,好吧!
2. 获取数据库连接:
方法:static Connection getConnection(String url,String user,String password)
参数:
- url
:指定连接的路径
- 语法:jdbc:mysql://ip地址(域名):端口号/数据库名称
- 例子:jdbc:mysql://localhost:3306/plan
- 细节:如果连接的是本机的mysql
服务器,并且mysql服务器默认端口是3306,则url可以简写为:jdbc:mysql///数据库名称
- 例如:Connection conn = DriverManager.getConnection("jdbc:mysql:///plan","root","");
- user
:用户名
- password
:密码
Connection
:数据库连接对象,用于连接数据库并传送数据
1. 获取执行sql
的对象
Statement createStatement
PreparedStatement prepareStatement(String sql)
2. 管理事务:
- 开启事务:
setAutoCommit(boolean autoCommit)
: 调用改方法设置参数为false
,就开启事务啦,哈哈
- 提交事务:
commit()
- 回滚事务:
rollback()
Statement
:执行sql
的对象,负责执行SQL
语句
执行sql
boolean execute(String sql)
:可以执行任意的sql
,可能会返回多个结果!(了解即可)
int executeUpdate(String sql)
:
- 执行
DML(insert,update,delete)
语句,DDL(create,alter,drop)
语句
- 这个
DDL
不经常用,所有在这个地方我们都是用前者的
- 返回值: 执行语句后,所影响的行数,我们可以通过这个影响的行数判断DML语句是否执行成功,要是大于0就成功了呗,反之,则失败.
ResultSet executeQuery(String sql)
: 执行DQL(select)
语句
练习:见附录
ResultSet
:结果集对象,负责保存Statement执行后所产生的查询结果
next()
:
- 游标向下移动一行
- 并且判断当前行是否是最后一行的末尾
- 返回
boolean
,如果有数据返回true,反之亦然!
getXxx(参数)
:获取数据
- Xxx:代表数据类型 如:
int getInt(), String getString()
- 参数:
int
: 代表列的编号, 从1开始 如getString(1)
String
: 代表列名称. 如: getDouble("balance")
- 注意:
使用步骤:
- 游标向下移动一行
- 判断是否有数据
- 获取数据
- 练习:
定义一个方法,查询emp表的数据将其封装为对象,然后装载集合,返回.
- 定义
Emp
类 用于封装Emp
表数据的JavaBean
- 定义方法
public List<Emp> findAll(){}
- 实现方法
select * from emp;
PreparedStatement
: 执行sql
的对象,用于负责执行SQL
语句
1. SQL注入问题:在拼接sql时,有一些特殊关键字参与字符串的拼接.会造成安全性的问题.
- 输入用户名随便,输入密码:
a' or 'a' = 'a
- sql:
select * from user where username = 'victor' and password = 'a' or 'a' = 'a'
2. 解决sql注入问题:使用PreparedStatement对象来解决,他是
3. 预编译sql:参数使用?作为占位符
4. 使用步骤:
- 导入驱动包
- 注册驱动
- 获取数据库对象连接
- 定义sql
- 注意:sql的参数使用?作为占位符.如:
select * from user where username = ? and password = ?;
- 获取执行sql语句的对象PreparedStatement Connection.prepareStatement(String sql)
- 给? 赋值:
- 执行sql,接受返回结果,不需要传递sql语句
- 处理结果
- 释放资源
5. 注意:后期都会使用PreparedStatement来完成增删改查的所有操作
- 可以防止SQL注入
- 效率更高
抽取JDBC工具类 : JdbcUtils.java
- 目的 : 简化书写
- 分析 :
1. 注册驱动
2. 抽取一个方法获取连接对象
需求 : 不想传递参数(麻烦),还得保证工具类的通用性.
解决 : 配置文件 jdbc.properties
1 2 3 4
| url=jdbc:mysql: user=root password= driver=com.mysql.jdbc.Driver
|
- 练习:
- 需求 :
- 通过键盘录入用户名和密码
- 判断用户是否登录成功
select * from user where username = "and password = ""
- 如果这个sql有结果,则查询成功,反之失败
- 步骤 :
创建数据库表 user
1 2 3 4 5
| create table user( id int primary key auto_increment, username varchar(32), password varchar(32) );
|
插入数据
1 2 3 4 5
| insert into user values (null,"victor","123");
insert into user values (null,"ttkr","1907123");
|
JDBC控制事务:
1. 事务: 一个包含多个步骤的业务操作.如果这个业务操作被事务管理,则这多个步骤要么同事成功,要么同时失败.
2. 操作:
3. 使用Connection对象来管理事务
- 开启事务:setAutoCommit(boolean autoCommit) :调用改方法设置参数为false,即开启事务
- 提交事务: commit()
- 回滚事务: rollback()
附录(源代码)
account
表 添加一条记录
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
| package cn.itcast.jdbc;
import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.sql.Statement;
public class JdbcDemo02 { public static void main(String[] args) { Statement stmt = null;
try { String sql = "insert into account values(null,'yupeng',5666)";
Connection conn = DriverManager.getConnection("jdbc:mysql:///plan", "root", ""); stmt = conn.createStatement(); int count = stmt.executeUpdate(sql); System.out.println(count); if (count > 0) { System.out.println("提交成功");
} else { System.out.println("添加失败"); }
} catch (Exception e) { e.printStackTrace(); } finally { if (stmt != null) { try { stmt.close(); } catch (SQLException e) { e.printStackTrace(); } } } } }
|
account
表 删除一条记录
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
| package cn.itcast.jdbc;
import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.sql.Statement;
public class JdbcDemo04 { public static void main(String[] args) { Connection conn = null; Statement stmt = null; try { conn = DriverManager.getConnection("jdbc:mysql:///plan","root",""); String sql = "delete from account where id = 4"; stmt = conn.createStatement(); int count = stmt.executeUpdate(sql); if (count > 0) { System.out.println("运行成功"); } else { System.out.println("失败了!"); }
} catch (Exception e) { e.printStackTrace(); }finally { if (stmt != null) { try { stmt.close(); } catch (SQLException e) { e.printStackTrace(); } } } }
}
|
account
表 修改一条记录
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
| package cn.itcast.jdbc;
import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.sql.Statement;
public class JdbcDemo03 { public static void main(String[] args) { Connection conn = null; Statement stmt = null; try { conn = DriverManager.getConnection("jdbc:mysql:///plan","root",""); String sql = "update account set balance = 6060 where id = 2"; stmt = conn.createStatement(); int count = stmt.executeUpdate(sql); if (count > 0) { System.out.println("运行成功"); } else { System.out.println("失败了!"); }
} catch (Exception e) { e.printStackTrace(); }finally { if (stmt != null) { try { stmt.close(); } catch (SQLException e) { e.printStackTrace(); } } } } }
|
DDl
: 创建一个表
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
| package cn.itcast.jdbc;
import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.sql.Statement;
public class JdbcDemo05 { public static void main(String[] args) { Connection conn = null; Statement stmt = null; try { conn = DriverManager.getConnection("jdbc:mysql:///plan","root",""); String sql = "create table student (id int ,name varchar(20))"; stmt = conn.createStatement(); int count = stmt.executeUpdate(sql); if (count > 0) { System.out.println("运行成功"); } else { System.out.println("失败了!"); }
} catch (Exception e) { e.printStackTrace(); }finally { if (stmt != null) { try { stmt.close(); } catch (SQLException e) { e.printStackTrace(); } } } } }
|
account
表 查询一条记录
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
| package cn.itcast.jdbc;
import java.sql.*;
public class JdbcDemo06 { public static void main(String[] args) { Connection conn = null; Statement stmt = null; ResultSet rs = null; try { conn = DriverManager.getConnection("jdbc:mysql:///plan", "root", ""); String sql = "select * from account"; stmt = conn.createStatement(); rs = stmt.executeQuery(sql); while (rs.next()) { int id = rs.getInt(1); String name = rs.getString("name"); double balance = rs.getDouble(3); System.out.println(id + "---" + name + "---" + balance);
}
} catch (Exception e) { e.printStackTrace(); } finally { if (stmt != null) { try { stmt.close(); } catch (SQLException e) { e.printStackTrace(); } } } } }
|
工具类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
| package cn.itcast.util;
import java.io.FileReader; import java.io.IOException; import java.net.URL; import java.sql.*; import java.util.Properties;
public class JdbcUtils {
private static String url; private static String user; private static String password; private static String driver;
static { try { Properties pro = new Properties();
ClassLoader classLoader = JdbcUtils.class.getClassLoader(); URL res = classLoader.getResource("jdbc.properties"); String path = res.getPath();
pro.load(new FileReader(path)); url = pro.getProperty("url"); user = pro.getProperty("user"); password = pro.getProperty("password"); driver = pro.getProperty("driver"); Class.forName(driver); } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } }
public static Connection getConnection() throws SQLException { return DriverManager.getConnection(url, user, password); }
public static void close(Statement stmt, Connection conn) { if (stmt != null) { try { stmt.close(); } catch (SQLException e) { e.printStackTrace(); } } if (conn != null) { try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } } }
public static void close(ResultSet rs, Statement stmt, Connection conn) { if (rs != null) { try { rs.close(); } catch (SQLException e) { e.printStackTrace(); } } if (stmt != null) { try { stmt.close(); } catch (SQLException e) { e.printStackTrace(); } } if (conn != null) { try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } }
|
查询emp表的数据将其封装为对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172
| package cn.itcast.jdbc;
import cn.itcast.domain.Emp; import cn.itcast.util.JdbcUtils;
import java.sql.*; import java.util.ArrayList; import java.util.Date; import java.util.List;
public class JdbcDemo08 {
public static void main(String[] args) { List<Emp> list = new JdbcDemo08().findAll2(); for (Emp emp : list) { System.out.println(emp); } }
public List<Emp> findAll() { Connection conn = null; Statement stmt = null; ResultSet rs = null; List<Emp> list = null;
try { Class.forName("com.mysql.jdbc.Driver"); conn = DriverManager.getConnection("jdbc:mysql:///plan", "root", ""); String sql = "select * from emp"; stmt = conn.createStatement(); rs = stmt.executeQuery(sql); Emp emp = null; list = new ArrayList<Emp>(); 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 joindate = rs.getDate("joindate"); double bonus = rs.getDouble("bonus"); double salary = rs.getDouble("salary"); int dept_id = rs.getInt("dept_id"); emp = new Emp(); emp.setId(id); emp.setEname(ename); emp.setJob_id(job_id); emp.setMgr(mgr); emp.setJoindate(joindate); emp.setBonus(bonus); emp.setSalary(salary); emp.setDept_id(dept_id);
list.add(emp); }
} catch (Exception e) { e.printStackTrace(); }finally { if (stmt != null) { try { stmt.close(); } catch (SQLException e) { e.printStackTrace(); } }
if (rs != null) { try { rs.close(); } catch (SQLException e) { e.printStackTrace(); } } if (conn != null) { try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } return list; }
public List<Emp> findAll2() { Connection conn = null; Statement stmt = null; ResultSet rs = null; List<Emp> list = null;
try { conn = JdbcUtils.getConnection(); String sql = "select * from emp"; stmt = conn.createStatement(); rs = stmt.executeQuery(sql); Emp emp = null; list = new ArrayList<Emp>(); 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 joindate = rs.getDate("joindate"); double bonus = rs.getDouble("bonus"); double salary = rs.getDouble("salary"); int dept_id = rs.getInt("dept_id"); emp = new Emp(); emp.setId(id); emp.setEname(ename); emp.setJob_id(job_id); emp.setMgr(mgr); emp.setJoindate(joindate); emp.setBonus(bonus); emp.setSalary(salary); emp.setDept_id(dept_id);
list.add(emp); }
} catch (Exception e) { e.printStackTrace(); }finally { JdbcUtils.close(rs,stmt,conn); } return list; } }
|
用户登录案例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
| package cn.itcast.jdbc;
import cn.itcast.util.JdbcUtils; import cn.itcast.util.python;
import java.sql.*;
public class JdbcDemo09 {
public static void main(String[] args) { String username = python.input("请输入用户名:"); String password = python.input("请输入密码:"); boolean flag = new JdbcDemo09().login(username, password); if (flag) { System.out.println("登录成功"); } else { System.out.println("用户名或者密码错误"); } }
public boolean login(String username, String password) { Connection conn = null; PreparedStatement pstmt = null; ResultSet rs = null; try { if (username != null || password != null) { ; } conn = JdbcUtils.getConnection(); String sql = "select * from user where username = ? and password = ?"; System.out.println(sql); pstmt = conn.prepareStatement(sql); rs = pstmt.executeQuery(); return rs.next();
} catch (SQLException e) { e.printStackTrace(); }finally { JdbcUtils.close(rs,pstmt,conn); }
return false; } }
|
转账案例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
| package cn.itcast.jdbc;
import cn.itcast.util.JdbcUtils;
import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException;
public class JdbcDemo10 { public static void main(String[] args) { transfer(); }
public static void transfer() { Connection conn = null; PreparedStatement pstmt1 = null; PreparedStatement pstmt2 = null; try { conn = JdbcUtils.getConnection(); String sql1 = "update account set balance = balance + ? where id = ?"; String sql2 = "update account set balance = balance - ? where id = ?"; pstmt1 = conn.prepareStatement(sql1); pstmt2 = conn.prepareStatement(sql2); pstmt1.setDouble(1,500); pstmt1.setDouble(2,1);
pstmt2.setDouble(1,500); pstmt2.setDouble(2,2);
pstmt1.executeUpdate(); int i = 3/0; pstmt2.executeUpdate();
} catch (Exception e) { try { if (conn != null) { conn.rollback(); } } catch (SQLException ex) { ex.printStackTrace(); } e.printStackTrace(); }finally { JdbcUtils.close(pstmt1,conn); JdbcUtils.close(pstmt2,null);
} } }
|