JDBC与JAVA程序笔记

文章小结

  • 开发过程中,对于配置文件以及相关的工具包使用可以很好的将代码简化,提升代码的可读性
  • 文章层层深入,其中的有些知识点在日后的开发中,不一定都能使用到,最长使用的方法是使用德鲁伊连接池和相关的工具类进行开发。
  • statement 存在 SQL 注入的问题。在后期开发中不能使用 statement
  • C3P0 数据库连接池在目前的大部分已经开发的项目中还有使用,应做相应的了解
  • 在 DRUID 和 Apache 的部分中,QueryRunner 中使用反射和泛型的相关知识

一、连接方式

1.通过new Driver()

// 这种方式采用 statement 与 connect 使用存在   SQL注入的问题
// 解决办法,使用预处理
// 导入的Driver类应该和对应的版本相匹配
// mysql 5.1 导入import com.mysql.jdbc.Driver;
// mysql 8.0 导入import com.mysql.cj.jdbc.Driver;
import com.mysql.cj.jdbc.Driver;
import java.io.IOException;
import java.sql.*;
import java.util.Properties;
/*** @author River* @datetime 2022/3/29 15:55*/
@SuppressWarnings({"all"})
public class Jdbc01 {public static void main(String[] args) throws SQLException, IOException, ClassNotFoundException {// 1.在项目下创建一个文件夹,导入mysql.jar,并添加到此项目中// 2.注册驱动Driver driver = new Driver();// 注册驱动,mysql 8.0之后自动导入,不建议直接使用这种凡是注册驱动// 3.得到连接String url = "jdbc:mysql://localhost:3306/dbem"; // mysql默认连接端口:3306//将 用户名和密码放入到 Properties 对象Properties properties = new Properties();//说明 user 和 password 是规定好,后面的值根据实际情况写properties.setProperty("user", "root");// 用户properties.setProperty("password", "200622"); //密码Connection connect = driver.connect(url, properties);// 4.执行 SQLString sql = "INSERT INTO employee VALUES ('102221','刘江','本科','1972/10/18','1','3','虎距路100                                   号','83606608','5')";// statement 用于执行静态 SQL 语句并返回其生成的结果的对象Statement statement = connect.createStatement();int rows = statement.executeUpdate(sql); // 返回影响得行数System.out.println(rows>0?"执行语句成功":"执行语句失败");// 5.关闭连接资源statement.close();connect.close();}
}

2. 使用反射加载

@Testpublic void connect02() throws ClassNotFoundException, InstantiationException, IllegalAccessException, SQLException {// 使用反射加载 Driver 类 , 动态加载,更加的灵活,减少依赖Class<?> aClass = Class.forName("com.mysql.cj.jdbc.Driver");// mysql 5.0 使用com.mysql.jdbc.DriverDriver driver =(Driver) aClass.newInstance();String url = "jdbc:mysql://localhost:3306/dbem"; // mysql默认连接端口:3306// 将 用户名和密码放入到 Properties 对象Properties properties = new Properties();// 说明 user 和 password 是规定好,后面的值根据实际情况写properties.setProperty("user", "root");// 用户properties.setProperty("password", "200622"); //密码Connection connect = driver.connect(url, properties);System.out.println(connect);// 执行sql语句相同//.....}

3.反射自动注册

@Testpublic void connect04() throws ClassNotFoundException, SQLException {// 使用反射加载了Driver类,在加载的时候自动完成注册// 在加载driver的时候,静态代码块已经执行了一次注册工作了Class.forName("com.mysql.cj.jdbc.Driver"); // mysql 8.0 使用//Class.forName("com.mysql.jdbc.Driver"); // mysql 5.1 使用String url = "jdbc:mysql://localhost:3306/dbem"; // mysql默认连接端口:3306String user = "root";String pwd = "200622";Connection connection = DriverManager.getConnection(url, user, pwd);System.out.println(connection);
}

4.使用配置文件

@Testpublic void connect05() throws IOException, ClassNotFoundException, SQLException {// 生成配置文件对象,加载排至文件信息Properties properties = new Properties();properties.load(new FileInputStream("src\\Information.properties"));String user = properties.getProperty("user");String pwd = properties.getProperty("pwd");String url = properties.getProperty("url");// 可以不用写,但是建议写上Class.forName("com.mysql.cj.jdbc.Driver");   Connection connection = DriverManager.getConnection(url, user, pwd);System.out.println(connection);}

二、ResultSet【结果集】

/*
基本介绍:1. 表示数据库结果集的数据表,通常通过指向查询数据库的语句生成2. ResultSet对象默认保持一个光标指向其当前的数据行。最初光标位于第一行之前3. next方法可以将光标移动到下一行,无下一行后返回NULL
使用方法:// 1. 得到连接connection// 2. 使用连connection 获得statement// 3. 通过statenment 执行sql语句得到ResultSet集// 4. 读取数据库返回的set信息while(resaultSet.next(){.......}// 5. 关闭连接资源
*/

三、事务

1.PreparedStatement[预处理]

1. Statement 对象用于执行静态的 SQL语句并返回其生成的结果对象
2. 在建立连接后,需要对数据库进行访问,执行命名或者是 sql 语句,可以通过+ Statement[存在SQL注入]+ PreparedStatement[预处理]+ CallableStatement[存储过程]
3. Sql注入:系统没有对用户输入的数据进行充分的检查,而在用户输入的数据中注入非法的SQL语句或命令,恶意攻击数据库
4.防范 sql注入问题,使用PreparedStatement取代Statement就可以了

实例:

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.sql.*;
import java.util.Properties;/*** @author River* @datetime 2022/3/30 18:30*/
// 1. Statement 对象用于执行静态的 SQL语句并返回其生成的结果对象
// 2. 在建立连接后,需要对数据库进行访问,执行命名或者是 sql 语句,可以通过
//        + Statement[存在SQL注入]
//        + PreparedStatement[预处理]
//        + CallableStatement[存储过程]
// 3. Sql注入:系统没有对用户输入的数据进行充分的检查,
//    而在用户输入的数据中注入非法的 SQL 语句或命令,恶意攻击数据库
// 4.防范 sql注入问题,使用 PreparedStatement 取代 Statement 就可以了 6
@SuppressWarnings({"all"})
public class JDBC_Statement {/*基本介绍:1. PreparedStatement 执行的 SQL 语句中的参数使用(?)表示。2. PreparedStatement 对象的 一系列 setXXX() 犯法来设置这些参数(索引,value)3. 调用 executeQuery(),返回 Resalut 对象4. 调用 executeUpdate(): 执行更新、包括增、删、改预处理的好处:1. 不在使用 + 来拼接 sql 语句 ,减少语法错误2. 有效的解决了 sql 注入的问题3. 大大的减少了编译的次数,效率较高*/public static void main(String[] args) throws IOException, ClassNotFoundException, SQLException {Properties properties = new Properties();properties.load(new FileInputStream("src\\Information.properties")); String user = properties.getProperty("user");String pwd = properties.getProperty("pwd");String url = properties.getProperty("url");// 可以不用写,但是建议写上Class.forName("com.mysql.cj.jdbc.Driver");Connection connection = DriverManager.getConnection(url, user, pwd);// 组织 sql 语句,?相当于占位符String sql = "SELECT * FROM employee WHERE employeeID = ?" ;// 使用连接获得 PreperedStatement 对象PreparedStatement preparedStatement = connection.prepareStatement(sql);// 给 sql 的 ?语句赋值preparedStatement.setString(1,"504209");// 执行 select 语句使用 executeQuery// 如果执行的是 dml(update, insert ,delete) executeUpdate()ResultSet resultSet = preparedStatement.executeQuery();// 使用 while 取出结果while(resultSet.next()){String id = resultSet.getString(1);String name = resultSet.getString("NAME");String education = resultSet.getString(3);Date date = resultSet.getDate(4);int gender = resultSet.getInt(5);int workYear = resultSet.getInt(6);String address = resultSet.getString(7);System.out.println(id+"\t"+name+"\t" +education+"\t"+date+"\t"+gender+"\t"+workYear+"\t"+address);}// 关闭连接资源preparedStatement.close();resultSet.close();connection.close();}}

2.Jdbc 工具类封装

  1. 配置文件mysql.properties

    pwd=200622
    user=root
    url=jdbc:mysql://localhost:3306/dbem?rewriteBatchedStatements=true
    driver=com.mysql.cj.jdbc.Driver
    
  2. 工具类JdbcUtils.java

    import java.io.FileInputStream;
    import java.io.IOException;
    import java.sql.*;
    import java.util.Properties;/*** @author River* @datetime 2022/3/30 20:59*/
    public class JdbcUtils {private  final static String USER;private final static String PASSWORD;private final static String URL;private final static String DRIVER;static {Properties properties = new Properties();try {properties.load(new FileInputStream("src\\mysql.properties"));USER = properties.getProperty("user");PASSWORD = properties.getProperty("pwd");URL = properties.getProperty("url");DRIVER = properties.getProperty("driver");} catch (IOException e) {// 1. 将编译异常转成 运行异常// 2. 调用者,可以选择捕获该异常,也可以选择默认处理该异常,比较方便throw new RuntimeException(e);}}/*** 连接到数据库* @return 返回数据库的连接*/public static Connection getConnection(){try {// 可以不写,建议写上Class.forName(DRIVER);return DriverManager.getConnection(URL,USER,PASSWORD);} catch (Exception e) {throw new RuntimeException(e);}}/*** 关闭相关资源**/public static void close(ResultSet set, Statement statement,Connection connection){try {if(set!=null){set.close();if (statement != null) {statement.close();}if (connection != null) {connection.close();}}} catch (SQLException e) {throw new RuntimeException(e);}}
    }
  3. 工具类测试 utilstest.java

import java.sql.*;/*** @author River* @datetime 2022/3/30 21:57*/
public class UtilsTest {public static void main(String[] args) throws SQLException {Connection connection = null;String sql = "SELECT * FROM employee WHERE employeeID = ?" ;PreparedStatement preparedStatement = null;ResultSet resultSet = null;connection = JdbcUtils.getConnection();preparedStatement = connection.prepareStatement(sql);preparedStatement.setString(1,"504209");resultSet = preparedStatement.executeQuery();while(resultSet.next()){String id = resultSet.getString(1);String name = resultSet.getString("NAME");String education = resultSet.getString(3);Date date = resultSet.getDate(4);int gender = resultSet.getInt(5);int workYear = resultSet.getInt(6);String address = resultSet.getString(7);System.out.println(id+"\t"+name+"\t" +education+"\t"+date+"\t"+gender+"\t"+workYear+"\t"+address);}JdbcUtils.close(resultSet,preparedStatement,connection);}
}

3.事务案例

  • 事务流程
  /***  jdbc 程序中当一个 Connection 对象创建是,默认情况下是自动提交事务;* 为了让多个 sql 语句作为一个整体执行,需要使用事务* 调用 Connection 的 setAutoCommit(false) 可以取消自动提交事务* 使用 Connection 的 commit()  提交事务* 使用 Connection 的 rollback() 回滚事务*/
  • 事务案例
package Transaction;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import com.river.test.util.JdbcUtils;/*** @author River* @datetime 2022/3/31 14:25*/public class Transaction01 {public static void main(String[] args)  {// sql 语句String sql1 = "INSERT INTO department VALUES (?,?,?);";String sql2 = "INSERT INTO department VALUES (?,?,?);";
//        String sql3 = "DELETE FROM department WHERE departmentID = 10;";
//        String sql4 = "DELETE FROM department WHERE departmentID = 11;";Connection connection = null;PreparedStatement preparedStatement = null;try {// 获得连接connection = JdbcUtils.getConnection();// 将自动提交提交关闭;默认情况下事务自动提交;connection.setAutoCommit(false);// 为 sql 语句赋值preparedStatement = connection.prepareStatement(sql1);preparedStatement.setInt(1,10);preparedStatement.setString(2,"信息部");preparedStatement.setString(3,"信息处理");preparedStatement.executeUpdate();
//            preparedStatement = connection.prepareStatement(sql3);
//            preparedStatement.executeUpdate();preparedStatement = connection.prepareStatement(sql2);preparedStatement.setInt(1,11);preparedStatement.setString(3,"宿舍管理");preparedStatement.setString(2,"宿舍部");preparedStatement.executeUpdate();
//            preparedStatement = connection.prepareStatement(sql4);
//            preparedStatement.executeUpdate();connection.commit();System.out.println();System.out.println("sql执行插入成功");} catch (SQLException e) {try {System.out.println("发生异常");// 发生异常事务回滚connection.rollback();} catch (SQLException throwable) {throwable.printStackTrace();}} finally {// 关闭资源JdbcUtils.close(null,preparedStatement,connection);}}
}

4.批处理

  • 批处理流程
* 成批的插入和修改数据,使用批处理更加的高效;
* addBatch():
* executeBatch():
* clearBatch():
* 参数 rewriteBatchedStatements=true;
  • 注意事项
* 使用 sql 语句时不使用分号结尾,否则会导致 sql 语句不正确的异常抛出
* 在连接中添加  url=jdbc:mysql://localhost:3306/dbem?rewriteBatchedStatements=true
  • 批处理实例
package Transaction;
import com.river.test.util.JdbcUtils;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;/*** @author River* @datetime 2022/3/31 18:55*/
public class Batch {/*** 成批的插入和修改数据,使用批处理更加的高效;* addBatch():* executeBatch():* clearBatch():* 参数 rewriteBatchedStatements=true;* @param args*/public static void main(String[] args) throws SQLException {// 使用连接工具类JdbcUtils获得连接Connection connection = JdbcUtils.getConnection();// 编写 sql 语句String sql = "INSERT INTO department VALUES (?,?,?)";// 通过 connection 获得 PreparedStatement 对象PreparedStatement preparedStatement = connection.prepareStatement(sql);System.out.println("开始执行");long begin = System.currentTimeMillis();// 对 sql 语句赋值for(int i = 0; i < 50000;i++){preparedStatement.setString(1,i+"");preparedStatement.setString(2,i+"部");preparedStatement.setString(3,i+"处理");preparedStatement.addBatch();// 满 1000 条 sql 以后直接if((i + 1) % 1000 == 0) {// 执行批处理 sql 语句preparedStatement.executeBatch();// 将执行后的批处理保存的 sql 语句清理后在接受新的语句preparedStatement.clearBatch();}}long end = System.currentTimeMillis();// 关闭相关的连接资源JdbcUtils.close(null, preparedStatement, connection);System.out.println(end -begin);}
}

四、连接池

  • /*** C3P0 数据库连接池,速度相对较慢,稳定性好* Druid (德鲁伊)是阿里提供的数据库连接池,集DBCP、C3P0、Proxool 优点于一身*/
    

1.C3P0

  • 使用之前需要加载 c3p0相应的 jar 包
  • 传统连接方式
// 传统的连接方式
import java.beans.PropertyVetoException;
import java.io.FileInputStream;
import java.io.IOException;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;@SuppressWarnings({"all"})
public class C3P0_ {public static void main(String[] args) throws IOException, SQLException, PropertyVetoException {// 获取数据源ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource();// 导入数据库连接的配置文件Properties properties = new Properties();properties.load(new FileInputStream("src\\mysql.properties"));// 读取相关的属性值String user = properties.getProperty("user");String password = properties.getProperty("password");String url = properties.getProperty("url");String driver = properties.getProperty("driver");// 给数据源 comboPooledDataSource 设置相关的参数// 注意:连接管理是由 comboPooledDataSource 来管理comboPooledDataSource.setDriverClass(driver);comboPooledDataSource.setJdbcUrl(url);comboPooledDataSource.setUser(user);comboPooledDataSource.setPassword(password);// 设置初始化连接数comboPooledDataSource.setInitialPoolSize(10);// 最大连接数comboPooledDataSource.setMaxPoolSize(50);// 测试连接池的效率, 测试对 mysql 5000 次操作long start = System.currentTimeMillis();for (int i = 0; i < 5000; i++) {// 这个方法就是从 DataSource 接口实现的Connection connection = comboPooledDataSource.getConnection();//connection.close();}long end = System.currentTimeMillis();//c3p0 5000 连接 mysql 耗时=391System.out.println("c3p0 5000 连接 mysql 耗时=" + (end - start));}
}
  • 使用配置文件进行连接
@Testpublic void testC3P0_02() throws SQLException {// 配置文件放在 src 目录下// 配置文件中的连接池名字ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource("river");//测试 5000 次连接 mysqllong start = System.currentTimeMillis();System.out.println("开始执行....");for (int i = 0; i < 500000; i++) {Connection connection = comboPooledDataSource.getConnection();connection.close();}long end = System.currentTimeMillis();System.out.println("c3p0 的第二种方式(500000) 耗时=" + (end - start));//1917}
  • 配置文件: 放置在 src 目录下
<c3p0-config><named-config name="river">
<!-- 驱动类 --><property name="driverClass">com.mysql.cj.jdbc.Driver</property><!-- url--><property name="jdbcUrl">jdbc:mysql://127.0.0.1:3306/dbem</property><!-- 用户名 --><property name="user">root</property><!-- 密码 --><property name="password">200622</property><!-- 每次增长的连接数--><property name="acquireIncrement">5</property><!-- 初始的连接数 --><property name="initialPoolSize">10</property><!-- 最小连接数 --><property name="minPoolSize">5</property><!-- 最大连接数 --><property name="maxPoolSize">10</property><!-- 可连接的最多的命令对象数 --><property name="maxStatements">5</property> <!-- 每个连接对象可连接的最多的命令对象数 --><property name="maxStatementsPerConnection">2</property></named-config>
</c3p0-config>

2.Druid

  • 使用流程
1. 加入 Druid.jar 包
2. 加入配置文件 druid.properties 将文件拷贝到 src 文件目录下
3. 生成 properties 对象,读取配置文件
4. 创建一个指定参数的数据库连接池,用 DruidDataSourceFactory.createDataSource(properties) 得到 datasource
5. 使用 dataSource.getConnection() 进行连接
  • 连接实例
import com.alibaba.druid.pool.DruidDataSourceFactory;
import javax.sql.DataSource;
import java.io.FileInputStream;
import java.sql.Connection;
import java.util.Properties;@SuppressWarnings({"all"})
public class Druid_ {public static void main(String[] args) throws Exception {// 1. 加入 Druid jar 包// 2. 加入 配置文件 druid.properties , 将该文件拷贝项目的 src 目录// 3. 创建 Properties 对象, 读取配置文件Properties properties = new Properties();properties.load(new FileInputStream("src\\druid.properties"));//4. 创建一个指定参数的数据库连接池, Druid 连接池DataSource dataSource =                              DruidDataSourceFactory.createDataSource(properties);long start = System.currentTimeMillis();for (int i = 0; i < 500000; i++) {Connection connection = dataSource.getConnection();// 将连接使用后的连接放回到连接池当中去connection.close();}long end = System.currentTimeMillis();System.out.println("druid 连接池 操作 500000 耗时=" + (end - start));}
}

3.JdbcUtilsDruid工具类

package com.river.test.util;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import javax.sql.DataSource;
import java.io.FileInputStream;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;/*** @author River* @datetime 2022/4/1 12:15*/
public class JdbcUtilsDruid {private static  DataSource ds;static {Properties properties = new Properties();try {properties.load(new FileInputStream("src\\druid.properties"));ds = DruidDataSourceFactory.createDataSource(properties);} catch (Exception e) {e.printStackTrace();}}/***    使用 dataSource 连接*/public static Connection getConnection() throws SQLException {return ds.getConnection();}public  static void close(ResultSet resultSet , Statement statement, Connection connection){try {if (resultSet != null){resultSet.close();}if (statement != null) {statement.close();}if (connection != null) {connection.close();}} catch (SQLException throwables) {throwables.printStackTrace();}}
}

五、Apache—DBUtils

1.背景问题

 1. 利用传统方法得到的 resultSet 结果集在 connection 关闭后无法使用2. 不利于数据的管理3. 使用 Apache—DBUtils 可以很好的解决这个问题

2.基本介绍

  • commons-dbutils 是 Apache 组织提供的一个开源的 JDBC 工具类库,可以极大的简化 jdbc 编码的工作量
  • QueryRunner 类:封装了 SQL 的执行,是线程安全的。
  • 使用 QueryRunner 类实施查询,可以在连接关闭后任然可以使用所查询得到的结果集。

3. 使用步骤

1. 导入 DBUtils 相关的 commoms-dbutils-1.3.jar 包,加入到本地的工程中
2. 获得数据库连接
3. 组织 sql 语句
4. 获得 QueryRunner 对象
5. 执行相关的 增、删、改、查 方法
6. 关闭相关的连接资源( resultSet , statement 在 query 执行完成后已经被关闭了,不需要在进行关闭)

4.使用案例

  • domain(Partment.java)
package Druid_;/*** @author River* @datetime 2022/4/1 23:36*/
public class Partment {private String departmentId;private String departName;private String comment;public Partment(){}public Partment(String departmentId, String departName, String comment) {this.departmentId = departmentId;this.departName = departName;this.comment = comment;}public String getdepartmentId() {return departmentId;}public void setdepartmentId(String departmentId) {this.departmentId = departmentId;}public String getDepartName() {return departName;}public void setDepartName(String departName) {this.departName = departName;}public String getComment() {return comment;}public void setComment(String comment) {this.comment = comment;}@Overridepublic String toString() {return "Partment{" +"departmentId='" + departmentId + '\'' +", departName='" + departName + '\'' +", comment='" + comment + '\'' +'}';}
}
  • 使用案例
package DBUtils;
import Druid_.Partment;
import com.river.test.util.JdbcUtilsDruid;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;
import org.junit.Test;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;/*** @author River* @datetime 2022/4/2 14:55*/
public class UseDbutils {public static void main(String[] args) {// DBUtils 使用方法}/*** 使用 DBUtils 进行查询,返回结果集列表*  new BeanListHandler<>( xxx.class );* @throws SQLException*/@Testpublic void DBUtils_use01() throws SQLException {// 使用德鲁伊连接工具类得到连接Connection connection = JdbcUtilsDruid.getConnection();// 创建 QuerRunner 实例QueryRunner queryRunner = new QueryRunner();// sql 语句String sql = "SELECT *  FROM department WHERE departmentID > ? ORDER BY departmentID desc " ;List<Partment> query = queryRunner.query(connection, sql, new BeanListHandler<>(Partment.class), 1);// 输出集合的信息for(Partment partment : query){System.out.println(partment);}// 关闭连接资源JdbcUtilsDruid.close(null,null,connection);}/*** 使用 DBUtils 进行查询,返回单个对象*  new BeanHandler<>( xxx.class );* @throws SQLException*/@Testpublic void DBUtils_use02() throws SQLException {// 使用 druid 工具类得到连接Connection connection = JdbcUtilsDruid.getConnection();// sql 语句String sql = "SELECT * FROM department WHERE departmentID = ?";// 得到 QueryRunner 对象QueryRunner queryRunner = new QueryRunner();// 得到查询结果Partment partment = queryRunner.query(connection, sql, new BeanHandler<>(Partment.class), 50);System.out.println(partment);// 关闭相关的资源JdbcUtilsDruid.close(null,null,connection);}/*** 使用 DBUtils 进行 dml ,返回影响的行数*  QueryRunner.update();* @throws SQLException*/@Testpublic void DBUtils_use03() throws SQLException {// 使用 druid 工具类得到连接Connection connection = JdbcUtilsDruid.getConnection();QueryRunner queryRunner = new QueryRunner();// sql 语句String sql = "insert into department values(?,?,?)";// 进行更新操作,返回更新操作影响的行数int update = queryRunner.update(connection, sql, "50", "50bu", "50部管理");if(update>0){System.out.println("更新成功");}else {System.out.println("更新失败");}// 关闭相关的连接资源JdbcUtilsDruid.close(null,null,connection);}/*** 使用 DBUtils 进行单值单列查询 ,返回查询结果*  QueryRunner.query(connection,sql,new ScalarHandler(),params...);* @throws SQLException*/@Testpublic void Single() throws SQLException {// 使用 druid 工具类得到连接Connection connection = JdbcUtilsDruid.getConnection();QueryRunner queryRunner = new QueryRunner();// sql 语句String sql = "select departmentID from department where departmentID = ?";// 进行单值单列查询Object query = queryRunner.query(connection, sql, new ScalarHandler(), 50);System.out.println(query);// 关闭相关的连接资源JdbcUtilsDruid.close(null,null,connection);}
}

六、DAO(data access object)

1. 基本说明

1. DAO : data access object (数据访问对象)。
2. 为了解决使用 DBUtils 代码复用性不高,将 sql 语句写死。
3. BasicDao 通用类 ,通过使用泛型,专门和数据库进行交互,完成对标的增删改查。
4. 在 BasicDao 的基础上,实现一张表对应一个 Dao ,更好的完成相关的功能。

2.配置文件以及相关的 jar 包

bins:
1. commons-dbutils-1.3.jar
2. druid-1.1.10.jar
3. mysql-connector-java-8.0.27.jar
properties:
1. druid.properties
2. mysql.properties

3. BasicDao

package com.river.Dao_.dao;import com.river.Dao_.untils.JdbcUtilsDruid;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;
import javax.xml.ws.handler.Handler;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;/*** @author River* @datetime 2022/4/2 19:58* 开发 BasicDAO ,是其它 DAO 的父类*/
public class BasicDAO<T> {private  QueryRunner qr =  new QueryRunner();/***   // 开发公共的 dml 方法,针对任意的表* @param sql* @param parameters 动态形参* @return 受影响的行数*/public int update(String sql,Object...parameters){Connection connection = null;try {connection = JdbcUtilsDruid.getConnection();int update = qr.update(connection, sql, parameters);return update;} catch (SQLException e) {// 将编译异常转换成运行异常throw new RuntimeException(e);} finally {JdbcUtilsDruid.close(null,null,connection);}}/*** sql 语句,返回对应的结果集* @param sql   sql 语句,可以有 ?* @param clazz 传入一个类的 Class 对象* @param parameters 可变形参* @return 查询的结果集*/public List<T> QueryMulti(String sql,Class<T> clazz, Object... parameters){Connection connection = null ;try {connection = JdbcUtilsDruid.getConnection();return qr.query(connection, sql, new BeanListHandler<T>(clazz), parameters);} catch (SQLException e ) {throw new RuntimeException(e);} finally {JdbcUtilsDruid.close(null,null,connection);}}/**** @param sql* @param clazz* @param parameters* @return*/public T QuerySingle(String sql ,Class<T> clazz,Object... parameters){Connection connection = null ;try {connection = JdbcUtilsDruid.getConnection();return qr.query(connection, sql, new BeanHandler<T>(clazz), parameters);} catch (SQLException e ) {throw new RuntimeException(e);} finally {JdbcUtilsDruid.close(null,null,connection);}}/*** 查询单值单列* @param sql sql 语句 可以含有 ?* @param parameters 动态参数* @return 查询到的对象*/public Object QueryScalar(String sql,Object... parameters){Connection connection = null ;try {connection = JdbcUtilsDruid.getConnection();return qr.query(connection, sql, new ScalarHandler(), parameters);} catch (SQLException e ) {throw new RuntimeException(e);} finally {JdbcUtilsDruid.close(null,null,connection);}}}

4. PartmentDAO

package com.river.Dao_.dao;import com.river.Dao_.domain.Partment;import java.util.List;/*** @author River* @datetime 2022/4/2 20:23*/
public class PartmentDAO extends BasicDAO<Partment>{public List<Partment> QueryMulti(String sql, Object... parameters) {return super.QueryMulti(sql, Partment.class, parameters);}public Partment QuerySingle(String sql, Object... parameters){return super.QuerySingle(sql,Partment.class,parameters);}}

5.testDAO

package com.river.Dao_.test;
import com.river.Dao_.dao.PartmentDAO;
import com.river.Dao_.domain.Partment;
import java.util.List;/*** @author River* @datetime 2022/4/2 20:24*/
public class testDAO {public static void main(String[] args) {// 生成具体的 DAO 对象,调用其相关的方法PartmentDAO partmentDAO = new PartmentDAO();// 查询多个对象结果List<Partment> partments =partmentDAO.QueryMulti("select * from department where deparmentid > ?", 10);for(Partment p : partments){System.out.println(p);}// 查询单个对象结果Partment partment =partmentDAO.QuerySingle("select * from department where departmentid = ?", 10);System.out.println(partment);// 进行插入,删除partmentDAO.update("insert into department values (?,?,?)",10,"10部","管理10部");partmentDAO.update("delete from department where departmentid = ?",10);// 对单值单列的查询Object o = partmentDAO.QueryScalar("select departname from department where departmentid = ?", 10);System.out.println(o);}}

JDBC与JAVA程序笔记相关推荐

  1. Java程序与数据库连接

    一个网络关系数据库应用系统是一个三层次结构.客户机与服务器采用网络连接,客户机端应用程序按通信协议与服务器端的数据库程序通信:数据库服务程序通过SQL命令与数据库管理系统通信. Java程序与数据库连 ...

  2. JDBC(Java Data Base Connectivity,java数据库连接)

    2019独角兽企业重金招聘Python工程师标准>>> JDBC是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java语言编写的类和接口组成 ...

  3. day30 | 黑马程序员Java全程笔记 | 第二阶段MySQL高级 JDBC

    01.反馈回顾 事务: ★ 概述: 逻辑上的一组操作,组成这组操作的各个单元要么同时成功,要么同时失败. 事务是一个最小的执行单元. mysql中的事务控制: 手动事务: 需要手动开启,提交,回滚开启 ...

  4. Java学习笔记之:Java JDBC

    一.介绍 JDBC(Java Data Base Connectivity,java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用java语言编写 ...

  5. ebs java并发_EBS中Java并发程序笔记(1)

    在Oracle EBS中的Java并发程序(Java Concurrent Program)是系统功能中的一个亮点,它的出现使得用户可以在ERP系统中运行自己定义的Java程序.本文为学习笔记,所以不 ...

  6. EBS中Java并发程序笔记(1)

    在Oracle EBS中的Java并发程序(Java Concurrent Program)是系统功能中的一个亮点,它的出现使得用户可以在ERP系统中运行自己定义的Java程序.本文为学习笔记,所以不 ...

  7. Java七步创建以JDBC连接数据库的程序

    JDBC连接数据库 ◆ 创建一个以JDBC连接数据库的程序,包含7个步骤: 1.加载JDBC驱动程序: 在连接数据库之前,首先要加载想要连接的数据库的驱动到JVM(Java虚拟机), 这通过java. ...

  8. Java程序猿的JavaScript学习笔记(12——jQuery-扩展选择器)

    计划按例如以下顺序完毕这篇笔记: Java程序猿的JavaScript学习笔记(1--理念) Java程序猿的JavaScript学习笔记(2--属性复制和继承) Java程序猿的JavaScript ...

  9. Java程序猿的JavaScript学习笔记(汇总文件夹)

    最终完结了,历时半个月. 内容包含: JavaScript面向对象特性分析,JavaScript高手必经之路. jQuery源代码级解析. jQuery EasyUI源代码级解析. Java程序猿的J ...

最新文章

  1. 非常有必要了解的Springboot启动扩展点
  2. 持久层框架之MyBatis
  3. .net中窗体之间的数据交换总结
  4. 计算机主机外设接口,计算机是如何自动识别外设~~凯凯最终成果!
  5. linux 解压xz包
  6. python调用父类对象的几个方法
  7. 微软开源 Tye 项目,可简化微服务开发
  8. HttpServletResponse说明
  9. 计算机视觉论文-2021-06-21
  10. 取代不了 C/C++ 的 Rust 如何“逆袭”?
  11. WinXP中自带的netsh命令自动切换IP(zz)
  12. python学习资源分享(编程基础_数据分析_机器学习模型_行业资讯)
  13. 网页顶部广告展开与收起
  14. AJAX异步请求解决跨域问题的三种方式
  15. CentOS下配置apache虚拟主机
  16. 苹果怎么换行打字_通过这 684 关小游戏,你的打字速度可以赢过专业录入员
  17. 关于苹果支付ApplePay的一些个人总结
  18. 小程序无限插屏广告实现方法
  19. Elasticsearch在Linux中的单节点部署和集群部署
  20. 如何从R和Gmail发送电子邮件

热门文章

  1. Vue --- 登陆+注册
  2. 《信息安全保障》一1.3 信息系统安全保障概念与模型
  3. 无力吐槽的 create-shortcut .exe
  4. Android设备上一张图片的显示过程
  5. 如何以厘米为单位精确设置Excel表格的行高列宽?
  6. 游戏直播的下一站在哪?战旗TV开启线上线下联动
  7. 万得数据写入Excel
  8. IDEA 统计Statistic插件下载地址
  9. gis计算频数_频数 (分析)
  10. Linux安装Oracle报Checking operating system version must be redhat-3, SuSE-9, redhat-4, UnitedLin