JDBC炼气篇-1
-
- 介绍
-
- 简介
- 主要步骤
- 详解各个对象
-
- DriverManager
- Connection
- Statement
- ResultSet
- PreparedStatement
- 代码实现
-
- 增加一条记录(insert)
- 修改一条记录(update)
- 删除一条记录(delete)
- 执行DDL语句(了解)
- 执行查询
- JDBC工具类
- 配置文件
- 将表中数据 封装对象 装载集合 返回
- 打怪篇
介绍 这篇博客是一只菜汪学习JDBC的第一步。
这篇博客更多地是Statement和不用JDBCUtils的写法。
欲知后事如何请看下集:(/▽\)
简介
JDBC本质:官方定义的一套操作所有关系型数据库的规则,即 接口 。各个数据库厂商去实现这套接口,提供数据库驱动jar包。我们可以使用这套接口(JDBC)编程,真正执行的代码是驱动jar包中的 实现类 。
主要步骤
- 导入驱动jar包 例如:mysql-connector-java-5.1.37-bin.jar
- 注册驱动
- 获取数据库连接对象 Connection
- 获取执行sql语句的对象 Statement
- 定义sql
- 执行sql,接受返回结果
- 处理结果
- 释放资源
类名 | 作用 |
---|---|
DriverManager | 驱动管理对象 |
Connection | 数据库连接对象 |
Statement | 执行sql的对象 |
ResultSet | 结果集对象,封装查询结果 |
PreparedStatement | 执行sql的对象 |
功能:
- 注册驱动,告诉程序该使用哪一个数据库驱动jar包
通过查看源码发现:在com.mysql.jdbc.Driver类中存在静态代码块 static { try { java.sql.DriverManager.registerDriver(new Driver()); } catch (SQLException E) { throw new RuntimeException("Can't register driver!"); } }
注意: mysql5 之后的驱动jar包可以省略注册驱动的步骤。
- 获取数据库连接
方法:static Connection getConnection(String url, String user, String password) 参数: * url:指定连接的路径 * 语法:jdbc:mysql://ip地址(域名):端口号/数据库名称 * 例子:jdbc:mysql://localhost:3306/db3 * 细节:如果连接的是本机mysql服务器,并且mysql服务默认端口是3306,则url可以简写为:jdbc:mysql:///数据库名称 * user:用户名 * password:密码
功能:
- 获取执行sql的对象
Statement createStatement()
PreparedStatement prepareStatement(String sql)
- 管理事务:
- 开启事务:
setAutoCommit(boolean autoCommit)
:调用该方法设置参数为false,即开启事务。 - 提交事务:
commit()
- 回滚事务:
rollback()
- 开启事务:
功能:
- 执行sql
-
boolean execute(String sql)
:可以执行任意的 sql
-
int executeUpdate(String sql)
:执行DML(insert、update、delete)语句、DDL(create,alter、drop)语句
返回值:影响的行数,可以通过这个影响的行数判断DML语句是否执行成功 返回值 >0 的则执行成功,反之,则失败。
-
ResultSet executeQuery(String sql)
:执行DQL(select)语句
-
方法:
-
boolean next()
: 游标向下移动一行,判断当前行是否是最后一行末尾(是否有数据),如果是,则返回false,如果不是则返回true
-
getXxx(参数)
:获取数据
? Xxx:代表数据类型,如: int getInt() , String getString()
? 参数:
? 1. int : 代表列的编号,从1开始。如: getString(1)
? 2. String:代表列名称。 如: getDouble(“balance”)
- 游标向下移动一行
- 判断是否有数据
- 获取数据
while(rs.next()){
//获取数据
int id = rs.getInt(1);
String name = rs.getString("name");
double balance = rs.getDouble(3);
System.out.println(id + "---" + name + "---" + balance);
}
PreparedStatement
功能:
- 解决 sql 注入问题:在拼接sql时,有一些sql的特殊关键字参与字符串的拼接。会造成安全性问题
- 输入用户随便,输入密码:
a' or 'a' = 'a
- sql:
select * from user where username = 'fhdsjkf' and password = 'a' or 'a' = 'a'
- 输入用户随便,输入密码:
- 解决sql注入问题:使用PreparedStatement对象来解决
- 预编译的SQL:参数使用 ? 作为占位符
- 注意:后期都会使用PreparedStatement来完成增删改查的所有操作
- 可以防止SQL注入
- 效率更高
- 但是在需要拼接字符串形成sql语句的时候,需要用到Statement语句
- 可以防止SQL注入
- 此处使用的是Statement类实现,但是在实际中很少用到Statement(),用到更多的是PreparedStatement()
- 此处未使用JDBCUtil工具类,所以代码冗杂
- 更多精彩请见下篇博客【JDBC筑基篇-1】
public class JDBCDemo2 {
public static void main(String[] args) {
Statement stmt = null;
Connection conn = null;
try {
//1. 注册驱动
Class.forName("com.mysql.jdbc.Driver");
//2.获取Connection对象
conn = DriverManager.getConnection("jdbc:mysql:///db3", "root", "root");
//3.获取执行sql的对象 Statement
stmt = conn.createStatement();
//4. 定义sql
String sql = "insert into account values(null,'王五',3000)";
//5.执行sql
int count = stmt.executeUpdate(sql);
//影响的行数
//6.处理结果
System.out.println(count);
if(count > 0){
System.out.println("添加成功!");
}else{
System.out.println("添加失败!");
}} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}finally {
//stmt.close();
//7. 释放资源 避免空指针异常
if(stmt != null){
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}if(conn != null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}
修改一条记录(update)
public class JDBCDemo3 {
public static void main(String[] args) {
Connection conn = null;
Statement stmt = null;
try {
//1. 注册驱动
Class.forName("com.mysql.jdbc.Driver");
//2.获取连接对象
conn = DriverManager.getConnection("jdbc:mysql:///db3", "root", "root");
//3.获取执行sql对象
stmt = conn.createStatement();
//4.定义sql
String sql= "update account set balance = 1500 where id = 3";
//5.执行sql
int count = stmt.executeUpdate(sql);
//6.处理结果
System.out.println(count);
if(count > 0){
System.out.println("修改成功!");
}else{
System.out.println("修改失败");
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
} finally {
//7.释放资源
if(stmt != null){
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(conn != null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}
删除一条记录(delete)
public class JDBCDemo4 {
public static void main(String[] args) {
Connection conn = null;
Statement stmt = null;
try {
//1. 注册驱动
Class.forName("com.mysql.jdbc.Driver");
//2.获取连接对象
conn = DriverManager.getConnection("jdbc:mysql:///db3", "root", "root");
//3.获取执行sql对象
stmt = conn.createStatement();
//4.定义sql
String sql= "delete from account where id = 3";
//5.执行sql
int count = stmt.executeUpdate(sql);
//6.处理结果
System.out.println(count);
if(count > 0){
System.out.println("删除成功!");
}else{
System.out.println("删除失败");
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
} finally {
//7.释放资源
if(stmt != null){
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(conn != null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}
执行DDL语句(了解)
public class JDBCDemo5 {
public static void main(String[] args) {
Connection conn = null;
Statement stmt = null;
try {
//1. 注册驱动
Class.forName("com.mysql.jdbc.Driver");
//2.获取连接对象
conn = DriverManager.getConnection("jdbc:mysql:///db3", "root", "root");
//3.定义sql
String sql= "create table student (id int , name varchar(20))";
//4.获取执行sql对象
stmt = conn.createStatement();
//5.执行sql
int count = stmt.executeUpdate(sql);
//6.处理结果
System.out.println(count);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
} finally {
//7.释放资源
if(stmt != null){
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(conn != null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}
执行查询
public class JDBCDemo6 {
public static void main(String[] args) {
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
try {
//1. 注册驱动
Class.forName("com.mysql.jdbc.Driver");
//2.获取连接对象
conn = DriverManager.getConnection("jdbc:mysql:///db3", "root", "root");
//3.定义sql
String sql= "select * from account";
//4.获取执行sql对象
stmt = conn.createStatement();
//5.执行sql
rs = stmt.executeQuery(sql);
//6.处理结果
//循环判断游标是否是最后一行末尾
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 (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
} finally {
//7.释放资源
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();
}
}
}
}
}
JDBC工具类
// JDBC工具类
public class JDBCUtils {
private static String url;
private static String user;
private static String password;
private static String driver;
// 文件的读取,只需要读取一次即可拿到这些值。使用静态代码块
static{
//读取资源文件,获取值。
try {
//1. 创建Properties集合类。
Properties pro = new Properties();
//获取src路径下的文件的方式--->ClassLoader 类加载器
ClassLoader classLoader = JDBCUtils.class.getClassLoader();
URL res= classLoader.getResource("jdbc.properties");
String path = res.getPath();
//2. 加载文件
// pro.load(new FileReader("D:\\IdeaProjects\\itcast\\day04_jdbc\\src\\jdbc.properties"));
pro.load(new FileReader(path));
//3. 获取数据,赋值
url = pro.getProperty("url");
user = pro.getProperty("user");
password = pro.getProperty("password");
driver = pro.getProperty("driver");
//4. 注册驱动
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();
}
}
}
}
配置文件
url=jdbc:mysql:///db3
user=root
password=root
driver=com.mysql.jdbc.Driver
注:配置文件中不要书写空格
将表中数据 封装对象 装载集合 返回
public class JDBCDemo8 {
// 测试方法
public static void main(String[] args) {
List list = new JDBCDemo8().findAll2();
System.out.println(list);
System.out.println(list.size());
}
// 查询所有emp对象的方法
public List findAll(){
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
List list = null;
try {
//1.注册驱动
Class.forName("com.mysql.jdbc.Driver");
//2.获取连接
conn = DriverManager.getConnection("jdbc:mysql:///db3", "root", "root");
//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 joindate = rs.getDate("joindate");
double salary = rs.getDouble("salary");
double bonus = rs.getDouble("bonus");
int dept_id = rs.getInt("dept_id");
// 创建emp对象,并赋值
emp = new Emp();
emp.setId(id);
emp.setEname(ename);
emp.setJob_id(job_id);
emp.setMgr(mgr);
emp.setJoindate(joindate);
emp.setSalary(salary);
emp.setBonus(bonus);
emp.setDept_id(dept_id);
//装载集合
list.add(emp);
}} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}finally {
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();
}
}
}
return list;
}//演示JDBC工具类
public List findAll2(){
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
List list = null;
try {
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 joindate = rs.getDate("joindate");
double salary = rs.getDouble("salary");
double bonus = rs.getDouble("bonus");
int dept_id = rs.getInt("dept_id");
// 创建emp对象,并赋值
emp = new Emp();
emp.setId(id);
emp.setEname(ename);
emp.setJob_id(job_id);
emp.setMgr(mgr);
emp.setJoindate(joindate);
emp.setSalary(salary);
emp.setBonus(bonus);
emp.setDept_id(dept_id);
//装载集合
list.add(emp);
}
} catch (SQLException e) {
e.printStackTrace();
}finally {
JDBCUtils.close(rs,stmt,conn);
}
return list;
}
}
打怪篇 已定义如下代码,自己看着办完成增删改查。(定义Course对象)
import java.util.List;
// 课程要求:Dao接口
public interface ICourseDao {
public int insert(Course course) throws Exception;
public int delete(int id) throws Exception;
public int update(Course course) throws Exception;
public List select() throws Exception;
}
解答:
import java.sql.*;
// 定义JDBC工具类
public class JDU {
public static Connection getConnection() {
Connection conn = null;
String url = "jdbc:mysql://localhost:3306/java09";
String name = "root";
String password = "333";
try {
// 注册驱动
Class.forName("com.mysql.cj.jdbc.Driver");
// 获取连接
conn = DriverManager.getConnection(url, name, password);
} catch (SQLException | ClassNotFoundException e) {
e.printStackTrace();
}
return conn;
}// 关闭数据库资源
public static void close(PreparedStatement pst, Connection conn) throws Exception {
if (pst != null) {
pst.close();
}
if (conn != null) {
conn.close();
}
}// 关闭数据库资源 —— 方法重载
public static void close(ResultSet rs, PreparedStatement pst, Connection conn) throws Exception {
if (rs != null) {
rs.close();
}
if (pst != null) {
pst.close();
}
if (conn != null) {
conn.close();
}
}
}
// 定义Course课程类
public class Course {
private int id;
private String name;
private int credit;
// 构造方法
public Course() {
}public Course(String name, int credit) {
this.name = name;
this.credit = credit;
}// 为属性提供访问接口
public int getId() {
return id;
}public void setId(int id) {
this.id = id;
}public String getName() {
return name;
}public void setName(String name) {
this.name = name;
}public double getCredit() {
return credit;
}public void setCredit(int credit) {
this.credit = credit;
}
}
// 接口Dao的实现类 【!!!】
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;
class ICourseDaoImpl implements ICourseDao {
// 定义sql语句
private static final String SQL_INSERT = "insert into course (name,credit) values(?,?)";
private static final String SQL_DELETE = "delete from course where id=?";
private static final String SQL_UPDATE = "update course set name=?,credit=? where id=?";
public int insert(Course course) throws Exception {
return update(SQL_INSERT, new Object[]{course.getName(), course.getCredit(),});
}public int delete(int i) throws Exception {
return update(SQL_DELETE, new Object[]{i});
}public int update(Course course) throws Exception {
int flag = update(SQL_UPDATE, new Object[]{course.getName(), course.getCredit(), course.getId()});
return flag;
}
//定义update方法,传入对数据库进行修改的操作
public int update (String sql, Object[]param) throws Exception {
int flag = 0;
Connection conn = null;
PreparedStatement pst = null;
try {
conn = JDU.getConnection();
pst = conn.prepareStatement(sql);
if (param != null && param.length > 0) {
for (int i = 1;
i < param.length + 1;
i++) {
pst.setObject(i, param[i - 1]);
}
}
flag = pst.executeUpdate();
} finally {
JDU.close(pst, conn);
}
return flag;
}//定义select方法,进行数据库查询的操作,将查询的结果放在对象Course的集合List中
public List select() throws Exception {
List cl = null;
Connection conn = null;
PreparedStatement pstm = null;
ResultSet rs = null;
try {
conn = JDU.getConnection();
pstm = conn.prepareStatement("select * from course");
rs = pstm.executeQuery();
cl = new ArrayList();
while (rs.next()) {
Course c = new Course();
c.setId(rs.getInt("id"));
c.setName(rs.getString("name"));
c.setCredit(rs.getInt("credit"));
cl.add(c);
}
return cl;
} finally {
JDU.close(rs, pstm, conn);
}
}
}
// 测试类
import java.sql.SQLException;
import java.util.List;
// 编写测试程序
public class Test {
public static void main(String[] args) {
ICourseDaoImpl dao=new ICourseDaoImpl();
// 接口的实现类
Course c=null;
List l = null;
// 准备集合 存放Course对象try {
// 插入
c = new Course("最讨厌的高数", 2);
// 插入学科名字为“最讨厌的高数” 学分为2分
dao.insert(c);
// 将课程插入数据库
// 查询
l = dao.select();
System.out.println("数据库中的信息如下:");
for (Course i : l) { // 循环,打印所有课程的信息
System.out.println("【"+i.getId() + "】---" + i.getName() +"---" + i.getCredit());
if(i.getName().equals("最讨厌的高数")) c.setId(i.getId());
}
// 修改
c.setName("辣鸡高数");
dao.update(c);
// 执行更新操作
System.out.println(c.getId());
dao.delete(57);
// 删除第57号学科信息
l = dao.select();
System.out.println("修改过后的学科信息:");
for (Course i : l) { // 循环遍历 打出所有学科信息
System.out.println("【"+i.getId() + "】---" + i.getName() + "---" + i.getCredit());
}
} catch (SQLException e1) {
e1.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}}
}
【永远学不会的Java|JDBC炼气篇-1】数据库定义:
文章图片
(这是一个程序中间出错测试了65遍程序终于成功的菜汪……这个id是自动递增的你敢信T^T)
推荐阅读
- springboot|从零开始搭建springboot项目骨架
- idea|IDEA 配置可视化数据库视图
- java开发|Idea连接mysql时区错误问题永久解决
- 技术分享|使用 SpringBoot + Redis + Vue3 + ArcoPro 开发管理系统
- 中间件|基于SpringBoot+MyBatis+Vue的音乐网站
- java|推荐一个 Spring Boot + MyBatis + Vue 音乐网站
- java|基于 SpringBoot + Vue 的前后端分离的考试系统
- 后端|MySQL 灵魂 16 问,你能撑到第几问()
- 后端|万字总结(分布式系统的38个知识点)