Java学习路线-43:JDBC数据库开发入门

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL DuckDB 分析主实例,集群系列 8核16GB
云数据库 RDS PostgreSQL,高可用系列 2核4GB
简介: Java学习路线-43:JDBC数据库开发入门

5-JDBC数据库开发入门

课时1-2 1.什么是JDBC

JDBC 数据库访问规范


应用程序 <-> JDBC <-> MySQL驱动 <-> MySQL
                 <-> Oracle驱动 <-> Oracle

导入jar包

加载驱动 Class.forName(‘类名’)

给出url、username、password

使用DriverManager类得到Connection类


maven导入依赖


<dependencies>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.18</version>
    </dependency>
</dependencies>

连接示例


import java.sql.Connection;
import java.sql.DriverManager;
class Demo {
    // MySQL >= 8.0 配置参数
    private static final String JDBC_DRIVER = "com.mysql.cj.jdbc.Driver";
    private static final String DB_URL = "jdbc:mysql://localhost:3306/data";
    private static final String USER = "root";
    private static final String PASSWORD = "123456";
    public static void main(String[] args) throws Exception {
        // 注册 JDBC 驱动
        Class.forName(JDBC_DRIVER);
        // 等效于
        // com.mysql.cj.jdbc.Driver driver = new com.mysql.cj.jdbc.Driver();
        // DriverManager.registerDriver(driver);
        // 打开链接
        Connection conn = DriverManager.getConnection(DB_URL, USER, PASSWORD);
        // 关闭链接
        conn.close();
    }
}

所有的java.sql.Driver实现类,都提供了static代码块,

块内代码把自己注册到DriverManager中


jdbc4.0之后 每个驱动jar包中,在META-INF/services目录下提供了一个java.sql.Driver文件

内容就是该接口的实现类名称


课时3 3.JDBC完成增、删、改、查

1、增、删、改


// 发送DML, DDL
int Statement.executeUpdate(String sql);

代码示例


// 注册 JDBC 驱动
Class.forName(JDBC_DRIVER);
// 打开链接
Connection conn = DriverManager.getConnection(DB_URL, USER, PASSWORD);
Statement statement = conn.createStatement();
// 增删改
// String sql = "insert into student(sname) values('陆小凤')";
// String sql = "update student set sname='花无缺' where sid=4";
String sql = "delete from student where sid=4";
int ret = statement.executeUpdate(sql);
System.out.println(ret);
// 关闭链接
conn.close();

2、查询


ResultSet executeQuery(String querySql);
boolean ResultSet.next();
// 获取列数据
ResultSet.getString()
ResultSet.getObject()
ResultSet.getInt()
ResultSet.getDouble()

行光标


beforeFirst <- 默认光标位置
first
last
AfterLast
// 打开链接
Connection conn = DriverManager.getConnection(DB_URL, USER, PASSWORD);
Statement statement = conn.createStatement();
// 查询
String sql = "select * from student";
ResultSet ret = statement.executeQuery(sql);
while (ret.next()){
    // 通过列序号获取
    int uid = ret.getInt(1);
    // 通过列名称获取
    String name = ret.getString("sname");
    System.out.println(uid + ", " + name);
}
// 关闭资源
ret.close();
statement.close();
conn.close();
课时4 4.JDBC之代码规范化
// 定义
try{
    // 实例化
}
finally{
    // 关闭资源
}

课时5 5.结果集光标与元数据

JBDC主要的类


DriverManager
Connection conn = DriverManager.getConnection(DB_URL, USER, PASSWORD);
Statement statement = conn.createStatement(); 
    int executeUpdate(String sql)    // 执行增、删、改
    ResultSet executeQuery(String sql)  // 执行查询
    boolean execute(String sql)         // 执行增、删、改、查

ResultSet滚动结果集

一个二维表格,内部维护了一个行光标(游标)


next() // 最常用
beforeFirst()
afterLast()
first()
last()
getRow()
absolute()
relative()
isBeforeFirst()
isAfterLast()
isFirst()
isLast()

元数据


// 元数据 
ResultSetMetaData ResultSet.getMetaData()
// 获取结果集列数
int ResultSetMetaData.getColumnCount()
// 获取指定列的列名
String ResultSetMetaData.getColumnName(int colIndex)

课时6 6.结果集的特性(是否可滚动、是否敏感、是否可更新)

确定结果集特性

1、是否可滚动

2、是否敏感

3、是否可更新


// 不滚动, 不敏感,不可更新
Statement createStatement()
// 滚动支持
Statement createStatement(int resultSetType, int resultSetConcurrency)        
resultSetType:
ResultSet.TYPE_FORWARD_ONLY  // 不滚动
ResultSet.TYPE_SCROLL_INSENSITIVE // 滚动,不随数据库变化而变化
ResultSet.TYPE_SCROLL_SENSITIVE // 滚动,不随数据库变化而变化
resultSetConcurrency // 是否通过修改结果集二反向影响数据库
ResultSet.CONCUR_READ_ONLY // 结果集只读 
ResultSet.CONCUR_UPDATABLE // 结果集可更新

课时7 7.PreparedStatement的用法

PreparedStatement是Statement子接口

1、防止SQL注入攻击

2、提高代码可读性,可维护性

3、提高效率


// 打开链接
Connection conn = DriverManager.getConnection(DB_URL, USER, PASSWORD);
// 使用预处理查询, 使用?占位
String sql = "select * from student where sid = ?";
PreparedStatement statement = conn.prepareStatement(sql);
// 为参数赋值
statement.setInt(1, 1);
// 获取数据
ResultSet ret = statement.executeQuery();
while (ret.next()){
    String name = ret.getString("sname");
    System.out.println(name);
}
// 关闭资源
ret.close();
statement.close();
conn.close();

课时8 8.预处理的原理

服务器工作:

(1)校验:sql语句的语法

(2)编译:为一个与函数相似的东西

(3)执行:调用函数


PreparedStatement

(1)先将sql发给数据库,数据库先进行校验

(2)执行的时候只发送参数


课时9 9.mysql的预编译功能默认是关闭的

prepare myfun from 'select * from student where sid = ?'
set @uid=1
execute myfun using @uid

设置连接参数:

useServerPrepStmts=true

cachePrepStmts=true


DB_URL = "jdbc:mysql://localhost:3306/data?useServerPrepStmts=true&cachePrepStmts=true";

课时10 10.JdbcUtils1.0小工具

JdbcUtils.java


package util;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties;
public class JdbcUtils {
    // 配置文件路径
    private static String dbconfig = "dbconfig.properties";
    private static Properties prop = null;
    // 静态代码块只执行一次
    static {
        // 初始化数据库配置参数
        try {
            InputStream in = JdbcUtils.class.getClassLoader().getResourceAsStream(dbconfig);
            prop = new Properties();
            prop.load(in);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        // 加载驱动
        try{
            Class.forName(prop.getProperty("driver"));
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        }
    }
    public static Connection getConnection() throws SQLException {
        return DriverManager.getConnection(
                prop.getProperty("url"),
                prop.getProperty("username"),
                prop.getProperty("password")
        );
    }
    public static void main(String[] args) throws SQLException {
        Connection conn = getConnection();
        System.out.println(conn);
    }
}

dbconfig.properties


driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/data
username=root
password=123456

课时11 11.面向接口编程

DAO模式

data access object

写一个类,把访问数据库的代码封装起来

DAO在数据库与业务逻辑(service)之间

实体域,即操作的对象


DAO模式步骤

(1)提供一个DAO接口

(2)提供一个DAO接口的实现类

(3)在编写一个DAO工厂,Service通过工厂来获取DAO实现


daoconfig.properties


UserDaoClassName=UserDaoImpl

UserDao.java


public interface UserDao {
}

UserDaoImpl.java

public class UserDaoImpl implements UserDao{
}

DaoFactory.java


import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
public class DaoFactory {
    // 配置文件路径
    private static String dbconfig = "daoconfig.properties";
    private static Properties prop = null;
    // 静态代码块只执行一次
    static {
        // 初始化数据库配置参数
        try {
            InputStream in = DaoFactory.class.getClassLoader().getResourceAsStream(dbconfig);
            prop = new Properties();
            prop.load(in);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
    /**
     * 返回一个UserDao的具体实现类
     */
    public static UserDao getUserDao() {
        String daoClassName = prop.getProperty("UserDaoClassName");
        // 通过反射创建实现类的对象
        try {
            Class Clazz = Class.forName(daoClassName);
            return (UserDao) Clazz.newInstance();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

课时12 12.修改案例,其中dao层为jdbc

User.java


public class User {
    private String username;
    private int age;
    public String getUsername() {
        return username;
    }
    public int getAge() {
        return age;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public void setAge(int age) {
        this.age = age;
    }
    @Override
    public String toString() {
        return "User{" +
                "username='" + username + '\'' +
                ", age=" + age +
                '}';
    }
}

daoconfig.properties


UserDaoClassName=UserDaoImpl

UserDao.java


public interface UserDao {
    public void addUser(User user);
    public User getUserByUsername(String username);
}

UserDaoImpl.java

import util.JdbcUtils;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
/**
 * create table user(
 * id int primary key auto_increment,
 * username varchar(50),
 * age int
 * )
 */
public class UserDaoImpl implements UserDao {
    /**
     * ORM 对象关系映射
     * @param user
     */
    @Override
    public void addUser(User user) {
        Connection conn = null;
        PreparedStatement statement = null;
        try {
            // 得到连接
            conn = JdbcUtils.getConnection();
            String sql = "insert into user(username, age) values(?, ?)";
            // 准备模板
            statement = conn.prepareStatement(sql);
            // 赋值
            statement.setString(1, user.getUsername());
            statement.setInt(2, user.getAge());
            // 执行
            statement.executeUpdate();
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            try {
                if (statement != null) {
                    statement.close();
                }
                if (conn != null) {
                    conn.close();
                }
            } catch (SQLException e) {
            }
        }
    }
    @Override
    public User getUserByUsername(String username) {
        Connection conn = null;
        PreparedStatement statement = null;
        try {
            // 得到连接
            conn = JdbcUtils.getConnection();
            String sql = "select * from user where username = ? limit 1";
            // 准备模板
            statement = conn.prepareStatement(sql);
            // 赋值
            statement.setString(1, username);
            // 执行
            ResultSet resultSet = statement.executeQuery();
            if(resultSet.next()){
                User user = new User();
                user.setUsername(resultSet.getString("username"));
                user.setAge(resultSet.getInt("age"));
                return user;
            }
            else{
                return null;
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            try {
                if (statement != null) {
                    statement.close();
                }
                if (conn != null) {
                    conn.close();
                }
            } catch (SQLException e) {
            }
        }
    }
}

DaoFactory.java


import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
public class DaoFactory {
    // 配置文件路径
    private static String dbconfig = "daoconfig.properties";
    private static Properties prop = null;
    // 静态代码块只执行一次
    static {
        // 初始化数据库配置参数
        try {
            InputStream in = DaoFactory.class.getClassLoader().getResourceAsStream(dbconfig);
            prop = new Properties();
            prop.load(in);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
    /**
     * 返回一个UserDao的具体实现类
     */
    public static UserDao getUserDao() {
        String daoClassName = prop.getProperty("UserDaoClassName");
        // 通过反射创建实现类的对象
        try {
            Class Clazz = Class.forName(daoClassName);
            return (UserDao) Clazz.newInstance();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

Service.java


// 添加测试
UserDao userDao = DaoFactory.getUserDao();
User user = new User();
user.setUsername("小明");
user.setAge(23);
userDao.addUser(user);
// 查询测试
User user1 = userDao.getUserByUsername("小明");
System.out.println(user1);

课时13 13.util包下的Date与sql包下的时间类型之间的转换

Data -> java.sql.Data

Time -> java.sql.Time

Timestamp -> java.sql.Timestamp


领域对象中所有属性不能出现java.sql包内容

继承关系


java.util.Date
    -java.sql.Date

父类转子类:util.Data -> sql.Date、Time、Timestamp


java.util.Date UtilDate = new java.util.Date();
long longDate = UtilDate.getTime();
java.sql.Date sqlData = new java.sql.Date(longDate);

子类转父类:sql.Date、Time、Timestamp -> util.Data


java.util.Date UtilDate = new java.sql.Date(System.currentTimeMillis());

课时14 14.大数据

可以将文件存入MySQL

my.ini配置

max_allowed_packet=10485760


课时15 15.批处理

批处理只针对更新(增,删,改)

一次向服务器发送多条sql语句

开启批处理参数

rewriteBatchedStatements=true


dbconfig.properties


driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/data?rewriteBatchedStatements=true
username=root
password=123456

import util.JdbcUtils;


import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
class Demo {
    public static void main(String[] args) throws SQLException {
        Connection conn = JdbcUtils.getConnection();
        String sql = "insert into user(username)values(?)";
        PreparedStatement statement = conn.prepareStatement(sql);
        for(int i=0; i<10000; i++){
            statement.setString(1, "name" + i);
            statement.addBatch(); // 装箱
        }
        long start = System.currentTimeMillis();
        statement.executeBatch(); // 提交数据
        long end = System.currentTimeMillis();
        System.out.println(end - start); // 107
    }
}
相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。 &nbsp; 相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情:&nbsp;https://www.aliyun.com/product/rds/mysql&nbsp;
相关文章
|
2月前
|
SQL 关系型数据库 数据库
Python SQLAlchemy模块:从入门到实战的数据库操作指南
免费提供Python+PyCharm编程环境,结合SQLAlchemy ORM框架详解数据库开发。涵盖连接配置、模型定义、CRUD操作、事务控制及Alembic迁移工具,以电商订单系统为例,深入讲解高并发场景下的性能优化与最佳实践,助你高效构建数据驱动应用。
312 7
|
3月前
|
IDE Java 关系型数据库
Java 初学者学习路线(含代码示例)
本教程为Java初学者设计,涵盖基础语法、面向对象、集合、异常处理、文件操作、多线程、JDBC、Servlet及MyBatis等内容,每阶段配核心代码示例,强调动手实践,助你循序渐进掌握Java编程。
427 3
|
3月前
|
SQL Java 数据库
2025 年 Java 从零基础小白到编程高手的详细学习路线攻略
2025年Java学习路线涵盖基础语法、面向对象、数据库、JavaWeb、Spring全家桶、分布式、云原生与高并发技术,结合实战项目与源码分析,助力零基础学员系统掌握Java开发技能,从入门到精通,全面提升竞争力,顺利进阶编程高手。
616 1
|
2月前
|
安全 前端开发 Java
《深入理解Spring》:现代Java开发的核心框架
Spring自2003年诞生以来,已成为Java企业级开发的基石,凭借IoC、AOP、声明式编程等核心特性,极大简化了开发复杂度。本系列将深入解析Spring框架核心原理及Spring Boot、Cloud、Security等生态组件,助力开发者构建高效、可扩展的应用体系。(238字)
|
3月前
|
SQL 算法 Java
零基础到精通的史上最强 Java 学习路线图推荐
史上最全Java学习路线图,涵盖基础语法、面向对象、数据结构与算法、多线程、JVM、Spring框架、数据库及项目实战,助你从零基础到精通Java开发,附完整代码与工具推荐。
246 3
零基础到精通的史上最强 Java 学习路线图推荐
|
3月前
|
消息中间件 人工智能 Java
抖音微信爆款小游戏大全:免费休闲/竞技/益智/PHP+Java全筏开源开发
本文基于2025年最新行业数据,深入解析抖音/微信爆款小游戏的开发逻辑,重点讲解PHP+Java双引擎架构实战,涵盖技术选型、架构设计、性能优化与开源生态,提供完整开源工具链,助力开发者从理论到落地打造高留存、高并发的小游戏产品。
|
3月前
|
NoSQL Java 关系型数据库
超全 Java 学习路线,帮你系统掌握编程的超详细 Java 学习路线
本文为超全Java学习路线,涵盖基础语法、面向对象编程、数据结构与算法、多线程、JVM原理、主流框架(如Spring Boot)、数据库(MySQL、Redis)及项目实战等内容,助力从零基础到企业级开发高手的进阶之路。
301 1
|
3月前
|
存储 Java 关系型数据库
Java 项目实战基于面向对象思想的汽车租赁系统开发实例 汽车租赁系统 Java 面向对象项目实战
本文介绍基于Java面向对象编程的汽车租赁系统技术方案与应用实例,涵盖系统功能需求分析、类设计、数据库设计及具体代码实现,帮助开发者掌握Java在实际项目中的应用。
127 0
|
3月前
|
SQL 算法 Java
适合自学的史上最强 Java 学习路线图分享
本路线图系统讲解Java从入门到进阶的学习路径,涵盖基础语法、面向对象编程、数据结构与算法、多线程、JVM原理、主流框架如Spring、数据库操作及项目实战,助你全面掌握Java开发技能,适合零基础及进阶学习。
897 0
|
3月前
|
Java API 数据库
2025 年最新 Java 实操学习路线,从入门到高级应用详细指南
2025年Java最新实操学习路线,涵盖从环境搭建到微服务、容器化部署的全流程实战内容,助你掌握Java 21核心特性、Spring Boot 3.2开发、云原生与微服务架构,提升企业级项目开发能力,适合从入门到高级应用的学习需求。
641 0

热门文章

最新文章