我的编程空间,编程开发者的网络收藏夹
学习永远不晚

JDBC

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

JDBC

JDBC

JDBC

一、概念

JDBC (Java Database Connectivity )指使用Java连接数据库,对数据库实现CRUD操作。

二、核心思想

Java定义一套操作数据库的规范(接口),各数据库厂商去实现该接口,保证程序员在使用上的统一。

三、驱动和接口

API(类和接口):在java.sql包中

  • DriverManager类:获得数据库连接
  • Connection接口:连接的接口
  • Statement接口以及其子接口PreparedStatment接口:操作数据库语句
  • ResultSet接口:查询时返回的结果集
  • SQLException类:数据库操作过程中的异常处理

驱动:

  • ODBC:桥接,使用系统去连接数据库,能够通用的连接大部分数据库,但是性能不好,而且功能不完整。
  • JDBC:数据库厂商提供的直连驱动包。
    • mysql-connector-java-5.1.40.jar:连接MySQL5的驱动
    • mysql-connector-java-8.0.20.jar:连接MySQL8的驱动
四、基本操作

操作步骤:

  • 0、将驱动包导入

  • 加载驱动

  • 获得连接

  • 通过连接获得SQL的执行对象

  • 通过执行对象执行SQL

  • 处理执行结果

  • 释放资源

public class JobsDAO {    public static void main(String[] args) {        // 1、加载驱动        try {            Class.forName("com.mysql.jdbc.Driver");        } catch (ClassNotFoundException e) {            e.printStackTrace();        }        final String url = "jdbc:mysql://localhost:3306/companydb?useUnicode=true&characterEncoding=utf8";        final String username = "root";        final String password = "root";        try (                // 2、获得连接                final Connection connection = DriverManager.getConnection(url, username, password);                // 3、获取执行sql对象                final Statement statement = connection.createStatement()        ){            System.out.println(connection);//            final String sql = "INSERT INTO t_jobs VALUES ('2', 'BBB', 2000, 10000);";//            // 4、执行SQL语句(更新操作,增删改),返回影响的行数//            final int count = statement.executeUpdate(sql);//            // 5、处理结果//            if (count > 0){//                System.out.println("执行成功");//            }else{//                System.out.println("执行失败");//            }            final String sql = "SELECT COUNT(1) FROM t_jobs";            // 4、执行SQL语句(查询操作),返回一个多行多列的结果集            final ResultSet resultSet = statement.executeQuery(sql);            // 5、处理结果            // 循环每一行            while (resultSet.next()){                // 获取当前行每一列的值                // 可以通过列的序号来获取,也可以通过列名来获取,推荐使用名称,COUNT(1)这种名称不太好使用的,推荐使用别名                final long count = resultSet.getLong(1);                System.out.println(count);            }        }catch (SQLException e){            e.printStackTrace();        }    }}
五、ResultSet使用

用来封装查询结果集。

注意:ResultSet是仅向前操作的对象,通过next方法向前操作,不能回退。

当移动到当前行时,使用getXxx()方法来获得某个列的值,方法的参数为列名或者序号(从1开始)。

public class JobsDAO {    public static void main(String[] args) {        // 1、加载驱动        try {            Class.forName("com.mysql.jdbc.Driver");        } catch (ClassNotFoundException e) {            e.printStackTrace();        }        final String url = "jdbc:mysql://localhost:3306/companydb?useUnicode=true&characterEncoding=utf8";        final String username = "root";        final String password = "root";        try (                // 2、获得连接                final Connection connection = DriverManager.getConnection(url, username, password);                // 3、获取执行sql对象                final Statement statement = connection.createStatement()        ){            System.out.println(connection);            final String sql = "SELECT COUNT(1) FROM t_jobs";            // 4、执行SQL语句(查询操作),返回一个多行多列的结果集            final ResultSet resultSet = statement.executeQuery(sql);            // 5、处理结果            // 循环每一行            while (resultSet.next()){                // 获取当前行每一列的值                // 可以通过列的序号来获取,也可以通过列名来获取,推荐使用名称,COUNT(1)这种名称不太好使用的,推荐使用别名                final long count = resultSet.getLong(1);                System.out.println(count);            }        }catch (SQLException e){            e.printStackTrace();        }    }}
六、SQL注入

利用拼接SQL字符串中的单引号,来注入关键字来实现非法操作。

例如:一个简单登录操作如下:

System.out.println(connection);String u = "zhangsan";String p = "123456";final String sql = "SELECT COUNT(1) FROM stu WHERE username = '"+u+"' AND pwd = '"+p+"'";// 4、执行SQL语句(查询操作),返回一个多行多列的结果集final ResultSet resultSet = statement.executeQuery(sql);// 5、处理结果// 循环每一行while (resultSet.next()){    // 获取当前行每一列的值    // 可以通过列的序号来获取,也可以通过列名来获取,推荐使用名称,COUNT(1)这种名称不太好使用的,推荐使用别名    final long count = resultSet.getLong(1);    System.out.println(count > 0);}

上面的代码执行看似没有问题,但是当用户将密码输入sdadsd' OR '1' = '1,无论用户名是什么,都会显示登录成功。就是简单的SQL注入攻击。

七、PreparedStatement

PreparedStatement接口是Statement接口的子接口。

特点:

  • 预编译语句,效率高
  • 安全,避免SQL注入
  • 动态填充内容,可以重复使用
// ?表示占位符final String sql = "INSERT INTO stu(name, username, pwd) VALUES (?, ?, ?);";try (    // 2、获得连接    final Connection connection = DriverManager.getConnection(url, username, password);    // 3、获取执行sql对象    final PreparedStatement preparedStatement = connection.prepareStatement(sql)){    for (int i = 0; i < 5; i++) {        // 设置参数        preparedStatement.setString(1, "AAA" + i);        preparedStatement.setString(2, "BBBB" + i);        preparedStatement.setString(3, "CCCC" + i);        // 4、执行SQL语句(更新操作,增删改),返回影响的行数        final int count = preparedStatement.executeUpdate();        // 5、处理结果        if (count > 0){            System.out.println("执行成功");        }else{            System.out.println("执行失败");        }    }}catch (SQLException e){    e.printStackTrace();}
八、封装工具类

封装连接类:

public class DBConnection {    static {        try {            Class.forName("com.mysql.jdbc.Driver");        } catch (ClassNotFoundException e) {            e.printStackTrace();        }    }    public static Connection getConnection() throws SQLException {        return DriverManager.getConnection("jdbc:mysql://localhost:3306/companydb?useUnicode=true&characterEncoding=utf8",                "root", "root");    }}

上面的内容,无法热修改,因为需要修改源代码,所以对于可能在上线后还需要修改的参数,应该使用配置文件。如下处理:

dbconfig.properties

jdbc.driver=com.mysql.jdbc.Driverjdbc.url=jdbc:mysql://localhost:3306/companydb?useUnicode=true&characterEncoding=utf-8jdbc.user=rootjdbc.password=root
    private final static Properties PROPERTIES = new Properties();    static {        try {            // 读取并加载配置文件            final InputStream inputStream = DBConnection1.class.getResourceAsStream("/dbconfig.properites");            PROPERTIES.load(inputStream);            Class.forName(PROPERTIES.getProperty("jdbc.driver"));        } catch (Exception e) {            e.printStackTrace();        }    }    public static Connection getConnection() throws SQLException {        return DriverManager.getConnection(PROPERTIES.getProperty("jdbc.url"),                PROPERTIES.getProperty("jdbc.user"), PROPERTIES.getProperty("jdbc.password"));    }}
九、封装DAO层

ORM:Object Relational Mapping对象关系映射。

是指将实体类的对象与数据库中的一行记录相对应。

DAO:Data Access Object数据访问对象,即数据库操作类的对象。

@Data@AllArgsConstructor@NoArgsConstructorpublic class Student {    private int id;    private String name;    private String username;    private String pwd;}
public interface StudentDAO {        boolean save(Student student);        boolean delete(int id);        boolean update(Student student);        Student findById(int id);        List<Student> findAll();}
public interface Constants {    String SQL_STUDENT_SAVE = "INSERT INTO stu(name, username, pwd) VALUES (?,?,?)";    String SQL_STUDENT_UPDATE = "UPDATE stu SET name = ?, username = ?, pwd = ? WHERE id = ?";    String SQL_STUDENT_DELETE = "DELETE FROM stu WHERE id = ?";    String SQL_STUDENT_FIND_BY_ID = "SELECT id, name, username, pwd FROM stu WHERE id = ?";    String SQL_STUDENT_FIND_ALL = "SELECT id, name, username, pwd FROM stu";}
public class StudentDAOImpl implements StudentDAO {    @Override    public boolean save(Student student) {        try(                Connection connection = DBConnection.getConnection();                final PreparedStatement preparedStatement = connection.prepareStatement(Constants.SQL_STUDENT_SAVE);                ) {            // 设置参数            preparedStatement.setString(1, student.getName());            preparedStatement.setString(2, student.getUsername());            preparedStatement.setString(3, student.getPwd());            return preparedStatement.executeUpdate() > 0;        }catch (SQLException e){            e.printStackTrace();        }        return false;    }    @Override    public boolean delete(int id) {        try(                Connection connection = DBConnection.getConnection();                final PreparedStatement preparedStatement = connection.prepareStatement(Constants.SQL_STUDENT_DELETE);        ) {            // 设置参数            preparedStatement.setInt(1, id);            return preparedStatement.executeUpdate() > 0;        }catch (SQLException e){            e.printStackTrace();        }        return false;    }    @Override    public boolean update(Student student) {        try(                Connection connection = DBConnection.getConnection();                final PreparedStatement preparedStatement = connection.prepareStatement(Constants.SQL_STUDENT_UPDATE);        ) {            // 设置参数            preparedStatement.setString(1, student.getName());            preparedStatement.setString(2, student.getUsername());            preparedStatement.setString(3, student.getPwd());            preparedStatement.setInt(4, student.getId());            return preparedStatement.executeUpdate() > 0;        }catch (SQLException e){            e.printStackTrace();        }        return false;    }    @Override    public Student findById(int id) {        try(                Connection connection = DBConnection.getConnection();                final PreparedStatement preparedStatement = connection.prepareStatement(Constants.SQL_STUDENT_FIND_BY_ID);        ) {            // 设置参数            preparedStatement.setInt(1, id);            final ResultSet resultSet = preparedStatement.executeQuery();            while (resultSet.next()){                return new Student(                        resultSet.getInt("id"),                        resultSet.getString("name"),                        resultSet.getString("username"),                        resultSet.getString("pwd")                        );            }        }catch (SQLException e){            e.printStackTrace();        }        return null;    }    @Override    public List<Student> findAll() {        List<Student> list = new ArrayList<>();        try(                Connection connection = DBConnection.getConnection();                final PreparedStatement preparedStatement = connection.prepareStatement(Constants.SQL_STUDENT_FIND_ALL);        ) {            final ResultSet resultSet = preparedStatement.executeQuery();            while (resultSet.next()){                final Student student = new Student(                        resultSet.getInt("id"),                        resultSet.getString("name"),                        resultSet.getString("username"),                        resultSet.getString("pwd")                );                list.add(student);            }        }catch (SQLException e){            e.printStackTrace();        }        return list;    }}
十、Service层

业务逻辑层,也写作Business(简写Biz)。

代表软件中的功能。

作用:一般情况下,一个业务就是一个方法。在业务中调用数据库操作。

十一、三层架构
  • 界面层View
  • 业务层Service
  • 数据访问层DAO

调用顺序:View -> Service -> DAO

作用:需要修改时,只需要考虑其中某一层。

高内聚,低耦合:将代码中相似或相同的内容,抽取出相似的部分,写到一起,其他的对他进行调用,称为高内聚。低耦合,是指降低代码中相互的依赖性。

包的名称方式:

  • entity:存放实体类
  • dao:数据库操作
  • service:业务逻辑
  • view:界面
  • util:帮助类

案例:学生信息管理系统

十二、事务
12.1 事务的基本使用

步骤:

connection.setAutoCommit(false);

connection.commit();在执行最后执行。

connection.rollback()在代码异常时执行。

注意:

  • 如果在DAO中获取了连接,然后在Service中也获取连接,那么在多个连接中无法实现事务处理。

要想实现事务处理,必须在同一个连接中。为了实现同一个连接,有以下几种处理方式:

  • 1、将连接作为参数传递,可以实现,但是会导致代码的侵入性。如果service调用service还是多个连接。会出错。
  • 2、将连接存在一个公共位置,谁用谁取。看似可行,其实有线程安全问题,而且多线程操作名字相同会覆盖。
  • 为了解决上面2的问题,又要实现1的不足(耦合度高),系统提供一个类ThreadLocal。
12.2 ThreadLocal【经典面试题】

每个线程通过ThreadLocal绑定一个map对象。

当前线程中的所有流程步骤都共享该map对象、

// ThreadLocal源码// 通过当前线程绑定的map设置值public void set(T value) {    // 获得当前线程    Thread t = Thread.currentThread();    // 根据当前线程获得该线程绑定的map    ThreadLocalMap map = getMap(t);    if (map != null)        // 将对象设置到当前map中,key为当前ThreadLocal对象        map.set(this, value);    else        // 如果没有,则通过该线程创建一个map        createMap(t, value);}// 通过当前线程绑定的map获取值public T get() {    // 获得当前线程    Thread t = Thread.currentThread();    // 根据当前线程获得该线程绑定的map    ThreadLocalMap map = getMap(t);    if (map != null) {        // 通过key为当前ThreadLocal对象来获取存储的对象        ThreadLocalMap.Entry e = map.getEntry(this);        if (e != null) {            @SuppressWarnings("unchecked")            // 返回该对象            T result = (T)e.value;            return result;        }    }    return setInitialValue();}
public class DBConnection {    private static final Properties PROPERTIES = new Properties();    private static final ThreadLocal<Connection> THREAD_LOCAL = new ThreadLocal<>();    static {        final InputStream inputStream = DBConnection.class.getResourceAsStream("/dbconfig.properties");        try {            PROPERTIES.load(inputStream);            Class.forName(PROPERTIES.getProperty("jdbc.driver"));        } catch (Exception e) {            e.printStackTrace();        }    }    public static Connection getConnection() throws SQLException {        // 在当前线程绑定的map中获取连接        Connection connection = THREAD_LOCAL.get();        if (connection == null){            // 创建连接            connection = DriverManager.getConnection(PROPERTIES.getProperty("jdbc.url"),                    PROPERTIES.getProperty("jdbc.user"),                    PROPERTIES.getProperty("jdbc.password"));            // 设置到当前线程绑定的map中            THREAD_LOCAL.set(connection);        }        return connection;    }    public static void closeAll(){        // 在当前线程绑定的map中获取连接        Connection connection = THREAD_LOCAL.get();        if (connection != null){            try {                connection.close();                // 在当前线程绑定的map中删除连接                THREAD_LOCAL.remove();            } catch (SQLException e) {                e.printStackTrace();            }        }    }}
public class AccountServiceImpl implements AccountService {    private AccountDAO accountDAO = new AccountDAOImpl();    @Override    public void transfer(Account from, Account to) {        Connection connection = null;        try{            connection = DBConnection.getConnection();            connection.setAutoCommit(false);            accountDAO.decrease(from);//            int i = 5 / 0;            accountDAO.increase(to);            connection.commit();        }catch (Exception e){            e.printStackTrace();            if (connection != null){                try {                    connection.rollback();                } catch (SQLException throwables) {                    throwables.printStackTrace();                }            }        }finally {            DBConnection.closeAll();        }    }}
public class AccountDAOImpl implements AccountDAO {    @Override    public boolean increase(Account account) throws SQLException {        Connection connection = DBConnection.getConnection();        final PreparedStatement preparedStatement = connection.prepareStatement(Constants.SQL_ACCOUNT_INCREASE);        preparedStatement.setInt(1, account.getMoney());        preparedStatement.setString(2, account.getAccount());        return preparedStatement.executeUpdate() > 0;    }    @Override    public boolean decrease(Account account) throws SQLException {        Connection connection = DBConnection.getConnection();        final PreparedStatement preparedStatement = connection.prepareStatement(Constants.SQL_ACCOUNT_DECREASE);        preparedStatement.setInt(1, account.getMoney());        preparedStatement.setString(2, account.getAccount());        return preparedStatement.executeUpdate() > 0;    }}
十三、DAO的封装DaoUtils
public interface RowMapper<T> {    T getMapper(ResultSet resultSet) throws SQLException;}
public class DAOUtils<T> {    public boolean update(String sql, Object... args) throws SQLException {        // 获得连接        final Connection connection = DBConnection.getConnection();        // 获得sql预编译操作对象        final PreparedStatement preparedStatement = connection.prepareStatement(sql);        // 设置参数        for (int i = 0; i < args.length; i++) {            preparedStatement.setObject(i + 1, args[i]);        }        // 执行        return preparedStatement.executeUpdate() > 0;    }    public List<T> queryList(String sql, RowMapper<T> mapper, Object... args) throws SQLException {        List<T> list = new ArrayList<>();        final Connection connection = DBConnection.getConnection();        final PreparedStatement preparedStatement = connection.prepareStatement(sql);        for (int i = 0; i < args.length; i++) {            preparedStatement.setObject(i + 1, args[i]);        }        final ResultSet resultSet = preparedStatement.executeQuery();        // 循环结果集        while (resultSet.next()){            // 封装结果集的行            T t = mapper.getMapper(resultSet);            // 添加到集合中            list.add(t);        }        return list;    }    public T queryOne(String sql, RowMapper<T> mapper, Object... args) throws SQLException {        final Connection connection = DBConnection.getConnection();        final PreparedStatement preparedStatement = connection.prepareStatement(sql);        for (int i = 0; i < args.length; i++) {            preparedStatement.setObject(i + 1, args[i]);        }        final ResultSet resultSet = preparedStatement.executeQuery();        while (resultSet.next()){            T t = mapper.getMapper(resultSet);            return t;        }        return null;    }}
public class StudentDAO {    private DAOUtils<Student> daoUtils = new DAOUtils();    public boolean save(Student student) throws SQLException {        return daoUtils.update(Constants.SQL_STUDENT_SAVE,                student.getName(), student.getSex(),                student.getAge(), student.getPhone());    }    public boolean update(Student student) throws SQLException {        return daoUtils.update(Constants.SQL_STUDENT_UPDATE,                student.getName(), student.getSex(),                student.getAge(), student.getPhone(), student.getId());    }    public boolean delete(int id) throws SQLException {        return daoUtils.update(Constants.SQL_STUDENT_DELETE, id);    }    public List<Student> findAll() throws SQLException{        return daoUtils.queryList(Constants.SQL_STUDENT_FIND_ALL, new RowMapper<Student>() {            @Override            public Student getMapper(ResultSet resultSet) throws SQLException {                return new Student(                        resultSet.getInt("id"),                        resultSet.getString("name"),                        resultSet.getString("sex"),                        resultSet.getInt("age"),                        resultSet.getString("phone")                );            }        });    }    public Student findById(int id) throws SQLException{        return daoUtils.queryOne(Constants.SQL_STUDENT_FIND_BY_ID, resultSet -> new Student(                    resultSet.getInt("id"),                    resultSet.getString("name"),                    resultSet.getString("sex"),                    resultSet.getInt("age"),                    resultSet.getString("phone")            )        , id);    }}
十四、连接池

避免频繁创建和关闭连接。

连接池有很多种:DBCP、C3P0、druid(阿里出品)

driverClassName=com.mysql.jdbc.Driverurl=jdbc:mysql://localhost:3306/stu_sys?useUnicode=true&characterEncoding=utf-8username=rootpassword=root#初始化连接数initialSize=10#最大活动连接数maxActive=50#最小空闲连接minIdle=5#最大等待时间5秒maxWait=5000

上面的配置信息,key不能改,采用约定优于配置原则

约定优于配置:事先约定好key的名称,如果遵守约定,那么就无需配置,如果不遵守约定,就需要添加额外的配置。

public class DBConnection {    private static final Properties PROPERTIES = new Properties();    private static final ThreadLocal<Connection> THREAD_LOCAL = new ThreadLocal<>();    private static DataSource dataSource; // 数据源连接池    static {        final InputStream inputStream = DBConnection.class.getResourceAsStream("/druid.properties");        try {            PROPERTIES.load(inputStream);            dataSource = DruidDataSourceFactory.createDataSource(PROPERTIES);        } catch (Exception e) {            e.printStackTrace();        }    }    public static DataSource getDataSource(){        return dataSource;    }    // dbutils类只有需要事务时才使用    public static Connection getConnection() throws SQLException {        Connection connection = THREAD_LOCAL.get();        if (connection == null){            connection = dataSource.getConnection();            THREAD_LOCAL.set(connection);        }        return connection;    }    public static void closeAll() throws SQLException {        Connection connection = THREAD_LOCAL.get();        if (connection != null){            // 在连接池中获取的连接,关闭时会还到池中再次使用            connection.close();            THREAD_LOCAL.remove();        }    }}
十五、DBUtils帮助类用法

当没有事务时,可以直接使用:

private QueryRunner runner = new QueryRunner(DBConnection.getDataSource());

注意:结果集的封装,使用反射的方式需要字段名和属性名一致。

public class StudentDAOImpl implements StudentDAO {    // DBUtils中的操作类的对象    // 当没有事务时,直接使用连接池对象    private QueryRunner runner = new QueryRunner(DBConnection.getDataSource());    @Override    public boolean save(Student student) throws SQLException {        return runner.update(Constants.SQL_STUDENT_SAVE, student.getName(), student.getSex(),                student.getAge(), student.getPhone()) > 0;    }    @Override    public boolean update(Student student) throws SQLException {        return runner.update(Constants.SQL_STUDENT_UPDATE, student.getName(), student.getSex(),                student.getAge(), student.getPhone(), student.getId()) > 0;    }    @Override    public boolean delete(int id) throws SQLException {        return runner.update(Constants.SQL_STUDENT_DELETE, id) > 0;    }//    @Override//    public List findAll() throws SQLException {//        // 通过反射封装结果集,但是需要字段名与属性名一致//        return runner.query(Constants.SQL_STUDENT_FIND_ALL, new BeanListHandler<>(Student.class));//    }    // 当字段名与属性不一致时,可以使用以下办法:    // 1、当个别属性不一致时,可以通过别名的方式    // 2、当很多属性不一致时,可以自己手动封装结果集    @Override    public List<Student> findAll() throws SQLException {        // 通过反射封装结果集,但是需要字段名与属性名一致        return runner.query(Constants.SQL_STUDENT_FIND_ALL, new ResultSetHandler<List<Student>>() {            @Override            public List<Student> handle(ResultSet resultSet) throws SQLException {                List<Student> list = new ArrayList<>();                while (resultSet.next()){                    Student student = new Student(resultSet.getInt("id"),resultSet.getString("name1"),resultSet.getString("sex"),resultSet.getInt("age"),resultSet.getString("phone")                    );                    list.add(student);                }                return list;            }        });    }    @Override    public Student findById(int id) throws SQLException {        return runner.query(Constants.SQL_STUDENT_FIND_BY_ID, new BeanHandler<>(Student.class), id);    }}

当有事务时:

public class AccountDAOImpl implements AccountDAO {    private QueryRunner runner = new QueryRunner();    @Override    public boolean increase(Account account) throws SQLException {        return runner.update(DBConnection.getConnection(),                Constants.SQL_ACCOUNT_INCREASE,                account.getMoney(), account.getAccount()) > 0;    }    @Override    public boolean decrease(Account account) throws SQLException {        return runner.update(DBConnection.getConnection(),                Constants.SQL_ACCOUNT_DECREASE,                account.getMoney(), account.getAccount()) > 0;    }}
public class AccountServiceImpl implements AccountService {    private AccountDAO accountDAO = new AccountDAOImpl();    @Override    public void transfer(Account from, Account to) throws SQLException {        Connection connection = null;        try{            connection = DBConnection.getConnection();            connection.setAutoCommit(false);            accountDAO.decrease(from);            int i = 5 / 0;            accountDAO.increase(to);            connection.commit();        }catch (Exception e){            e.printStackTrace();            if (connection != null){                try {                    connection.rollback();                } catch (SQLException throwables) {                    throwables.printStackTrace();                }            }        }finally {            DBConnection.closeAll();        }    }}

来源地址:https://blog.csdn.net/weixin_45427945/article/details/129916719

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

JDBC

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

JavaWeb——JDBC

内容索引1. JDBC基本概念2. 快速入门3. 对JDBC中各个接口和类详解JDBC:1. 概念:Java DataBase Connectivity Java 数据库连接, Java语言操作数据库* JDBC本质:其实是官方(sun公司)定义的一套操作所
JavaWeb——JDBC
2016-05-23

mysql-jdbc

mysql-jdbcJava通过jdbc连接远程数据库并执行最简单的sql查询获取数据。更多jdbc介绍,请参考官方文档准备假设远端有一个数据库mydb和一张简单的表student:创建Java工程: 接下来创建一个jdbc demo工程,这里使用idea,e
mysql-jdbc
2016-10-25
2023-10-27

Impala Jdbc

首先要引入ImpalaJDBC41.jar包。可以网上找,也可以直接下面的地址下载。 链接:https://pan.baidu.com/s/1MTJ0Wn1pwEmtXwp-_E4gIw  提取码:j00u  public static void main(S
Impala Jdbc
2014-11-16

JDBC代码

可以建一个properties的文件jdbc.username=scottjdbc.password=tigerjdbc.driver=oracle.jdbc.driver.OracleDriverjdbc.url=jdbc:oracle:
2023-06-03

JDBC简介

文章目录 一、JDBC简介二、JDBC执行步骤三、执行步骤中类的简介1、DriverManager类2.Connection类3、ResultSet类 一、JDBC简介 1.什么是jdbc JDBC全称:java datab
2023-08-20

【JDBC】笔记(3)-

1.Statement 编译一次,只执行一次,PreparedStatement 编译一次,可执行n次,所以 PreparedStatement 效率较高...... 一.实现功能:    1.解决“应用Statement的登录系统”存在的SQL注入问题
【JDBC】笔记(3)-
2015-01-20
2024-04-02

JDBC编程

文章目录 一、JDBC简介二、驱动的下载三、JDBC的使用DriverManagerDataSourceConnectionStatementResultSetPreparedStatement数据库连接池 一、JDBC简
2023-08-18
2024-04-02

【JDBC】笔记(4)-

但是在实际的业务中,通常是多条 DML语句 联合完成的,那么就必须保证这些 DML语句 在同一个事务中同时成功或失败...... 楔子:   JDBC 的事务默认是自动提交的:   只要执行一条 DML语句,则自动提交一次。但是在实际的业务中,通常是多条
【JDBC】笔记(4)-
2021-09-15

JDBC | JDBC API详解及数据库连接池

👑 博主简介:    🥇 Java领域新星创作者    🥇 阿里云开发者社区专家博主、星级博主、技术博主 🤝 交流社区:BoBooY(优质编程学习笔记社区) 前言:
2023-08-20

【JDBC】编程(2)-

实现模糊查询(以“查哪个用户的密码中的第二个字符为‘a’为例)......  import java.sql.*;public class DBUtil { /** * 工具类的构造方
【JDBC】编程(2)-
2017-06-28

【JDBC】笔记(5)-

总结:在当前事务中,用行级锁锁住的记录,那么在此事务结束之前,其他事务将无法对“锁住的记录”进行操作(update/delete),但是select可以...... 1.悲观锁和乐观锁的概念:2.演示行级锁机制:注意:DBUtil类 为博主之前自己写的类
【JDBC】笔记(5)-
2019-02-13

编程热搜

目录