JDBC中解

文章目录


前言

Java数据库连接

一、获取数据库连接(依次迭代)

方式一:获取Driver实现类对象

		Driver driver=new com.mysql.cj.jdbc.Driver();
        String url = "jdbc:mysql://localhost:3306/myblog";
        Properties properties = new Properties();
        properties.setProperty("user", "root");
        properties.setProperty("password", "root");
        Connection connect = driver.connect(url, properties);
        System.out.println(connect);

方式二:使用反射

  • 获取Driver实现类对象:使用反射
  • 提供要连接的数据库
  • 提供连接需要的用户名和密码
  • 获取连接
		//在下面的程序中不出现第三方的api,使得程序具有更好的可移植性
		Class<?> clazz = Class.forName("com.mysql.cj.jdbc.Driver");
        Driver driver = (Driver) clazz.getDeclaredConstructor().newInstance();
        String url="jdbc:mysql://localhost:3306/myblog";
        Properties properties = new Properties();
        properties.setProperty("user", "root");
        properties.setProperty("password", "root");
        Connection connect = driver.connect(url, properties);
        System.out.println(connect);

方式三:使用DriverManager替换Driver

  • 获取Driver实现类对象
  • 提供另外三个连接的基本信息
  • 注册驱动
  • 获取连接
		Class<?> clazz = Class.forName("com.mysql.cj.jdbc.Driver");
        Driver driver = (Driver) clazz.getDeclaredConstructor().newInstance();
        String url="jdbc:mysql://localhost:3306/myblog";
        String user="root";
        String password="root";
        DriverManager.registerDriver(driver);
        Connection connection = DriverManager.getConnection(url, user, password);
        System.out.println(connection);

方式四:隐式注册驱动

  • 提供另外三个连接的基本信息
  • 加载Driver
  • 获取连接
		String url="jdbc:mysql://localhost:3306/myblog";
        String user="root";
        String password="root";
        Class.forName("com.mysql.cj.jdbc.Driver");
        Connection connection = DriverManager.getConnection(url, user, password);
        System.out.println(connection);

为什么可以省略–Class.forName(“com.mysql.cj.jdbc.Driver”);–操作呢?
在mysql的Driver实现类中,声明了如下的操作:

		static {
                try {
                    DriverManager.registerDriver(new Driver());
                } catch (SQLException var1) {
                    throw new RuntimeException("Can't register driver!");
                }
            }

方式五:声明配置文件

  • 读取配置文件中的4个基本信息
  • 加载驱动
  • 获取连接

将数据库连接需要的4个基本信息声明在配置文件中,通过读取配置文件的方式,获取连接

  • 实现了数据与代码的分离。实现了解耦
  • 如果需要修改配置文件信息,可以避免程序重新打包。
		InputStream is = ConnectionTest.class.getClassLoader().getResourceAsStream("jdbc.properties");
        Properties properties = new Properties();
        properties.load(is);
        String user = properties.getProperty("user");
        String password = properties.getProperty("password");
        String url = properties.getProperty("url");
        String driverClass = properties.getProperty("driverClass");
        Class.forName(driverClass);
        Connection connection = DriverManager.getConnection(url, user, password);
        System.out.println(connection);

jdbc.properties文件内容如下
JDBC中解

二、使用

1.查询

a.查询某个表

		Connection connection=null;
        PreparedStatement statement=null;
        ResultSet resultSet=null;
        try {
            connection = JDBCUtils.getConnection();
            String sql ="select * from t_article where  id = ?";
            statement = connection.prepareStatement(sql);
            statement.setObject(1, 27);
            //执行,并返回结果集
            resultSet = statement.executeQuery();
            //处理结果集
            if (resultSet.next()){
                //判断结果集的下一条是否有数据,如果有数据返回true,并指针下移;如果返回false,指针不会下移。
                int id = resultSet.getInt(1);
                String title = resultSet.getString(2);
                String author = resultSet.getString(3);
                String sort = resultSet.getString(4);
                Date date = resultSet.getDate(5);
                int star = resultSet.getInt(6);
                int comment = resultSet.getInt(7);
                int visit = resultSet.getInt(8);
                String content = resultSet.getString(9);
                Article article = new Article(id,star,comment,visit,title,author,sort,content,date);
                System.out.println(article);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            JDBCUtils.closeResource(connection, statement,resultSet);
        }

b.通过反射生成方法

	public Article queryForArticle(String sql,Object ... args) {
        Connection connection = null;
        PreparedStatement statement = null;
        ResultSet resultSet = null;
        try {
            connection = JDBCUtils.getDBCPConnection();
            statement = connection.prepareStatement(sql);
            for (int i = 0; i < args.length; i++) {
                statement.setObject(i+1, args[i]);
            }
            resultSet = statement.executeQuery();
            //获取结果集的元数据
            ResultSetMetaData metaData = resultSet.getMetaData();
            //通过ResultSetMetaData获取结果集中的列数
            int columnCount = metaData.getColumnCount();
            if (resultSet.next()){
                Article article = new Article();
                //处理结果集一行数据中的每一个列
                for (int i = 0; i < columnCount; i++) {
                    //获取列值
                    Object columnValue = resultSet.getObject(i + 1);
                    ///获取每个列的列名
                    String columnName = metaData.getColumnName(i + 1);
                    //给Article对象指定的columnName属性,赋值为columnValue,通过反射
                    Field field = Article.class.getDeclaredField(columnName);
                    field.setAccessible(true);
                    field.set(article, columnValue);
                }
                return article;
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            JDBCUtils.closeResource(connection, statement,resultSet);
        }
        return null;
    }

c.别名

针对于表的字段名与类的属性名不相同的情况:

  • 必须声明sql时,使用类的属性名来命名字段的别名
  • 使用ResultSetMetaData时,需要使用getColumnLabel()来替换getColumnName()获取列的别名。

说明:如果sql中没有给字段其别名,getColumnLabel()缺取的就是列名

	public Comment commentQuery(String sql,Object ... args){
        Connection connection =null;
        PreparedStatement statement=null;
        ResultSet resultSet=null;
        try {
            connection = JDBCUtils.getDruidConnection();
            statement = connection.prepareStatement(sql);
            for (int i = 0; i < args.length; i++) {
                statement.setObject(i+1,args[i]);
            }
            resultSet = statement.executeQuery();
            ResultSetMetaData rsmd = resultSet.getMetaData();
            int columnCount = rsmd.getColumnCount();
            if (resultSet.next()){
                Comment comment = new Comment();
                for (int i = 0; i < columnCount; i++) {
                    Object value = resultSet.getObject(i + 1);
                    //获取列的列名:getColumnName()---不推荐使用
                    // 获取列的别名:getColumnLabel()
//                    String columnName = rsmd.getColumnName(i + 1);
                    String columnName = rsmd.getColumnLabel(i + 1);
                    Field field = Comment.class.getDeclaredField(columnName);
                    field.setAccessible(true);
                    field.set(comment, value);
                }
                return comment;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            JDBCUtils.closeResource(connection,statement,resultSet);
        }
        return null;
        
 @Test
    public void testCommentQuery(){
        String sql="select id,article_id articleId,nickname nickName,content,time,star,diss dis from t_comment where id=?";
        System.out.println(commentQuery(sql,25));
    }

d.生成泛型方法

public <T> T getInstance(Class<T> clazz,String sql,Object ... args){
        Connection connection =null;
        PreparedStatement statement=null;
        ResultSet resultSet=null;
        try {
            connection = JDBCUtils.getConnection();
            statement = connection.prepareStatement(sql);
            for (int i = 0; i < args.length; i++) {
                statement.setObject(i+1,args[i]);
            }
            resultSet = statement.executeQuery();
            ResultSetMetaData rsmd = resultSet.getMetaData();
            int columnCount = rsmd.getColumnCount();
            if (resultSet.next()){
                T t=clazz.getDeclaredConstructor().newInstance();
                for (int i = 0; i < columnCount; i++) {
                    Object value = resultSet.getObject(i + 1);
                    String columnName = rsmd.getColumnLabel(i + 1);
                    Field field = clazz.getDeclaredField(columnName);
                    field.setAccessible(true);
                    field.set(t, value);
                }
                return t;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            JDBCUtils.closeResource(connection,statement,resultSet);
        }
        return null;
    }
public <T> List<T> getForList(Class<T> clazz, String sql, Object ... args){
        Connection connection =null;
        PreparedStatement statement=null;
        ResultSet resultSet=null;
        try {
            connection = JDBCUtils.getConnection();
            statement = connection.prepareStatement(sql);
            for (int i = 0; i < args.length; i++) {
                statement.setObject(i+1,args[i]);
            }
            resultSet = statement.executeQuery();
            ResultSetMetaData rsmd = resultSet.getMetaData();
            int columnCount = rsmd.getColumnCount();
            ArrayList<T> list = new ArrayList<>();
            while (resultSet.next()){
                T t=clazz.getDeclaredConstructor().newInstance();
                for (int i = 0; i < columnCount; i++) {
                    Object value = resultSet.getObject(i + 1);
                    String columnName = rsmd.getColumnLabel(i + 1);
                    Field field = clazz.getDeclaredField(columnName);
                    field.setAccessible(true);
                    field.set(t, value);
                }
                list.add(t);
            }
            return list;
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            JDBCUtils.closeResource(connection,statement,resultSet);
        }
        return null;
    }

JDBC中解

2.插入,更新,删除

单个修改

		Connection connection = null;
        PreparedStatement preparedStatement = null;
        try {
            connection = JDBCUtils.getConnection();
            String sql = "update t_article set author = ? where id = ?";
            preparedStatement = connection.prepareStatement(sql);
            preparedStatement.setObject(1, "弟弟");
            preparedStatement.setObject(2, 13);
            preparedStatement.execute();
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            JDBCUtils.closeResource(connection, preparedStatement);
        }

生成方法

	public int update(String sql,Object ... args){
        Connection connection = null;
        PreparedStatement preparedStatement = null;
        try {
            connection = JDBCUtils.getConnection();
            //String sql = "update t_article set author = ? where id = ?";
            preparedStatement = connection.prepareStatement(sql);
            for (int i = 0; i < args.length; i++) {
                preparedStatement.setObject(i+1,args[i]);
            }
            /*
            ps,execute():
            如果执行的是查询操作,有返回结果,则此方法返回true;
            如果执行的是增、删、改操作,没有返回结果,则此方法返回false
            * */
            return preparedStatement.executeUpdate();
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            JDBCUtils.closeResource(connection, preparedStatement);
        }
        //'order'
        return 0;
    }

3.PreparedStatement对比Statement的优点

类型 大小(单位:字节)
TinyBlob 最大255
Blob 最大65K
MediumBlob 最大16M
LongBlob 最大4G

操作Blob的数据

插入

		Connection connection=null;
        PreparedStatement statement=null;
        try {
            connection = JDBCUtils.getConnection();
            String sql = "insert into dormitory(name,photo) values (?,?) ";
            statement = connection.prepareStatement(sql);
            statement.setObject(1, "刘鑫");
            FileInputStream fis = new FileInputStream(new File("laida.png"));
            statement.setBlob(2, fis);
            statement.execute();
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            JDBCUtils.closeResource(connection, statement);
        }

查询

		Connection connection=null;
        PreparedStatement statement=null;
        ResultSet resultSet=null;
        InputStream is=null;
        FileOutputStream fos=null;
        try {
            connection = JDBCUtils.getConnection();
            String sql="select id,name,photo from dormitory where id=?";
            statement = connection.prepareStatement(sql);
            statement.setInt(1, 1);
            resultSet = statement.executeQuery();
            if (resultSet.next()){
                int id = resultSet.getInt(1);
                String name = resultSet.getString("name");
                //将Blob类型的字段下载下来,以文件的方式保存在本地
                Blob photo = resultSet.getBlob(3);
                is = photo.getBinaryStream();
                fos = new FileOutputStream("liuxin.png");
                byte[] buffer = new byte[1024];
                int len;
                while ((len=is.read(buffer))!=-1){
                    fos.write(buffer, 0, len);
                }
                System.out.println(id+","+name);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            JDBCUtils.closeResource(connection, statement,resultSet);
        }

可以实现更高效的批量操作

update、delete本身就具有批量操作的效果。 此时的批量操作,主要指的是批量插入。使用PreparedStatement如何实现更高效的批量插入?


题目:向goods表中插入20000条数据CREATE TABLE goods(id INT PRIMARY KEY AUTO_INCREMENT,NAME VARCHAR(25));

方式一:使用Statement

Connection conn = JDBCUtils.getConnection( );
Statement st = conn.createStatement( );
for(int i = 1;i <= 20000;i++){
     String sql = "insert into goods(name)values( ' name_" + i + "')";
     st.execute(sql);
 }

方式二:使用PreparedStatement

		Connection connection=null;
        PreparedStatement statement=null;
        try {
            connection= JDBCUtils.getConnection();
            String sql="insert into dormitory(name) values (?)";
            statement = connection.prepareStatement(sql);
            for (int i = 0; i < 20000; i++) {
                statement.setString(1,"name_"+i);
                statement.execute();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            JDBCUtils.closeResource(connection, statement);
        }

方式三

  • addBatch()、executeBatch()、clearBatch()
  • mysql服务器默认是关闭批处理的,我们需要通过一个参数,让mysql开启批处理的支持。
  • ?rewriteBatchedStatements=true写在配置文件的url后面
  • 使用更新的mysql 驱动:mysql-connector-java-5.1.37-bin.jar
		Connection connection=null;
        PreparedStatement statement=null;
        try {
            connection= JDBCUtils.getConnection();
            String sql="insert into goods(name) values (?)";
            statement = connection.prepareStatement(sql);
            for (int i = 0; i < 20000; i++) {
                statement.setString(1,"name_"+i);
                //1."攒"sql
                statement.addBatch();
                if (i%500==0){
                    //执行batch
                    statement.executeBatch();
                    //清空batch
                    statement.clearBatch();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            JDBCUtils.closeResource(connection, statement);
        }

方式四:事务

		Connection connection=null;
        PreparedStatement statement=null;
        try {
            connection= JDBCUtils.getConnection();
            //设置不允许自动提交
            connection.setAutoCommit(false);
            String sql="insert into goods(name) values (?)";
            statement = connection.prepareStatement(sql);
            for (int i = 0; i <= 20000; i++) {
                statement.setString(1,"name_"+i);
                //1."攒"sql
                statement.addBatch();
                if (i%500==0){
                    //执行batch
                    statement.executeBatch();
                    //清空batch
                    statement.clearBatch();
                }
            }
            connection.commit();
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            JDBCUtils.closeResource(connection, statement);
        }

4.数据类型

Java与SQL对应数据类型转换表

项目 Value
boolean BIT
byte TINYINT
short SMALLINT
int INTEGER
long BIGINT
String CHAR,VARCHAR,LONGVARCHAR
byte array BINARY , VAR BINARY
java.sql.Date DATE
java.sql.Time TIME
java.sql.Timestamp TIMESTAMP

四:事务

概念

  • 一组逻辑操作单元(一个或多个DML操作(Data Manipulation Language)),使数据从一种状态变换到另一种状态。
  • 事务处理的原则:保证所有事务都作为一个工作单元来执行,即使出现了故障,都不能改变这种执行方式。当在一个事务中执行多个操作时,要么所有的事务都被提交(commit),那么这些修改就永久地保存下来,要么数据库管理系统将放弃所作的所有修改,整个事务回滚(rollback)到最初状态。
  • 数据一旦提交,就不可回滚
  • 哪些操作会导致数据的自动提交?

DDL操作(Data Definition Language)一旦执行,都会自动提交。
--------set autocommit = false 对DDL操作失效
DML默认情况下,一旦执行,就会自动提交。
--------我们可以通过set autocommit = false的方式取消DML操作的自动提交。
默认在关闭连接时,会自动的提交数据

事务的ACID属性

原子性( Atomicity )

原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。

—致性( consistency )

事务必须使数据库从一个一致性状态变换到另外一个一致性状态。

隔离性( lsolation )

事务的隔离性是指一个事务的执行不能被其他事务干扰,即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。

持久性(Durability )

持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来的其他操作和数据库故障不应该对其有任何影响。

并发问题

对于同时运行的多个事务,当这些事务访问数据库中相同的数据时,如果没有采取必要的隔离机制,就会导致各种并发问题。

脏读

对石两个事务T1,T2,T1读取了已经被T2更新但还没有被提交的字段。之后,若T2回滚, T1读取的内容就是临时且无效的。

不可重复读

对于两个事务T1,T2,T1读取了一个字段,然后T2更新了该字段。之后,T1再次读取同一个字段,值就不同了。

幻读

对于两个事务T1,T2,T1从一个表中读取了一个字段,然后T2在该表中插入了一些新的行。之后,如果T1再次读取同一个表,就会多出几行。

  • 数据库事务的隔离性:数据库系统必须具有隔离并发运行各个事务的能力,使它们不会相互影响,避免各种并发问题。
  • 一个事务与其他事务隔离的程度称为隔离级别。数据库规定了多种事务隔离级别,不同隔离级别对应不同的干扰程度,隔离级别越高,数据一致性就越好,但并发性越弱。

银行转账问题

问题再现

----------------------------------未考虑数据库事务情况下的转账操作----------------------------------
针对于数据表user_table来说:AA用户给BB用户转账10日
update user_table set balance = balance - 100 where user = ‘AA’
update user_table set balance = balance + 100 where user = ‘BB’

		String sql1="update user_table set balance = balance - 100 where user = ?";
        update(sql1, "AA");
        System.out.println(10/0);
        String sql2="update user_table set balance = balance + 100 where user = ?";
        update(sql2, "BB");
        System.out.println("转账成功");

通用的增删改操作(考虑上事务)

	public int update(Connection connection,String sql,Object ... args){
        PreparedStatement preparedStatement = null;
        try {
            preparedStatement = connection.prepareStatement(sql);
            for (int i = 0; i < args.length; i++) {
                preparedStatement.setObject(i+1,args[i]);
            }
            return preparedStatement.executeUpdate();
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            JDBCUtils.closeResource(null, preparedStatement);
        }
        return 0;
    }

通用的查询操作(考虑上事务),用于返回数据表中的一条记录

public <T> T getInstance(Connection connection,Class<T> clazz,String sql,Object ... args){
        PreparedStatement statement=null;
        ResultSet resultSet=null;
        try {
            statement = connection.prepareStatement(sql);
            for (int i = 0; i < args.length; i++) {
                statement.setObject(i+1,args[i]);
            }
            resultSet = statement.executeQuery();
            ResultSetMetaData rsmd = resultSet.getMetaData();
            int columnCount = rsmd.getColumnCount();
            if (resultSet.next()){
                T t=clazz.getDeclaredConstructor().newInstance();
                for (int i = 0; i < columnCount; i++) {
                    Object value = resultSet.getObject(i + 1);
                    String columnName = rsmd.getColumnLabel(i + 1);
                    Field field = clazz.getDeclaredField(columnName);
                    field.setAccessible(true);
                    field.set(t, value);
                }
                return t;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            JDBCUtils.closeResource(null,statement,resultSet);
        }
        return null;
    }

加入事务改进后

		Connection connection = null;
        try {
            connection = JDBCUtils.getConnection();
            //1.建立连接
            connection.setAutoCommit(false);
            String sql1="update user_table set balance = balance - 100 where user = ?";
            update(connection,sql1, "AA");
            System.out.println(10/0);
            String sql2="update user_table set balance = balance + 100 where user = ?";
            update(connection,sql2, "BB");
            System.out.println("转账成功");
            //2.提交操作
            connection.commit();
        } catch (Exception e) {
            e.printStackTrace();
            //3.回滚
            assert connection != null;
            connection.rollback();
        } finally {
            //4.修改其为自动提交数据,主要针对于使用数据库连接池的使用
            assert connection != null;
            connection.setAutoCommit(true);
            JDBCUtils.closeResource(connection, null);
        }

隔离级别

隔离级别 描述
READ UNCOMMITTED(读未提交数据) 允许事务读取未被其他事物提交的变更,脏读、不可重复读和幻读的问题都会出现
READ COMMITED(读已提交数据) 只允许事务读取已经被其它事务提交的变更,可以避免脏读,但不可重复读和幻读问题仍然可能出现
REPEATABLE READ(可重复读) 确保事务可以多次从一个字段中读取相同的值,在这个事务持续期问,禁止其他事物对这个字段进行更新,可以避免脏读和不可重复读,但幻读的问题仍然存在。
SERIALIZABLE(串行化) 确保事务可以从一个表中读取相同的行.在这个事务持续期间.禁止其他事务对该表执行插入.更新和删除操作.所有并发问题都可以避免,但性能十分低下.
  • Oracle支持的2种事务隔离级别:READ COMMITED, SERIALIZABLE。Oracle默认的事务隔离级别为:READ COMMITED。
  • Mysql支持4种事务隔离级别。Mysql默认的事务隔离级别为: REPEATABLE READ。
		Connection connection=null;
        try {
            connection = JDBCUtils.getConnection();
            //获取当前连接的隔离级别
            System.out.println(connection.getTransactionIsolation());
            //设置数据库的隔离级别:
            connection.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
            connection.setAutoCommit(false);
            String sql="select id ,name,url,image from t_link where id =?";
            System.out.println(getInstance(connection, Link.class, sql, 1));
        } catch (Exception e) {
            e.printStackTrace();
        }

五:数据库连接池

CP30

设置驱动

		//获取c3pO数据库连接池
        ComboPooledDataSource cpds = new ComboPooledDataSource();
        cpds.setDriverClass("com.mysql.cj.jdbc.Driver");
        cpds.setJdbcUrl("jdbc:mysql://localhost:3306/myblog?characterEncoding=utf-8&&rewriteBatchedStatements=true");
        cpds.setUser("root");
        cpds.setPassword("root");
        //通过设置相关的参数,对数据库连接池进行管理:
        //设置初始时数据库连接池中的连接数
        cpds.setInitialPoolSize(10);
        Connection connection = cpds.getConnection();
        System.out.println(connection);
        //销毁cp30数据库连接池
        DataSources.destroy(cpds);

配置文件

		ComboPooledDataSource cpds = new ComboPooledDataSource("helloc3p0");
        try {
            System.out.println(cpds.getConnection());
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
    <named-config name="helloc3p0">
<!--        提供获取连接的4个基本信息-->
        <property name="driverClass">com.mysql.cj.jdbc.Driver</property>
        <property name="jdbcUrl">jdbc:mysql://localhost:3306/myblog?characterEncoding=utf-8</property>
        <property name= "user">root</property>
        <property name="password">root</property>
<!--        进行数据库连接池管理的基本信息-->
<!--        当数据库连接池中的连接数不够时,c3p日一次性向数据库服务器申请的连接数-->
        <property name="acquireIncrement">5</property>
<!--        C3p0数据库连接池中初始化时的连接数-->
        <property name="initialPoolSize">10</property>
<!--        c3p0数据库连接池维护的最少连接数-->
        <property name= "minPoolSize">10</property>
<!--        c3p0数据库连接池维护的最多连接数-->
        <property name= "maxPoolSize">1000</property>
<!--        c3p0数据库连接池最多维护的Statement的个数·-->
        <property name= "maxStatements">50</property>
<!--        每个连接中可以最多使用的Statement的个数-->
        <property name= "maxStatementsPerConnection">2</property>
    </named-config>
</c3p0-config>

封装到JDBCUtils

	private  static final ComboPooledDataSource cpds = new ComboPooledDataSource("helloc3p0");
    public static Connection getC3P0Connection() throws Exception {
        return cpds.getConnection();
    }

DBCP

设置驱动

		//创建了DBCP的数据库连接池
        BasicDataSource source=new BasicDataSource();
        //设置基本信息
        source.setDriverClassName("com.mysql.cj.jdbc.Driver");
        source.setUrl("jdbc:mysql://localhost:3306/myblog?characterEncoding=utf-8&&rewriteBatchedStatements=true");
        source.setUsername("root");
        source.setPassword("root");
        //还可以设置其他涉及数据库连接池管理的相关属性:
        source.setInitialSize(10);
        source.setMaxTotal(10);
        Connection connection = source.getConnection();
        System.out.println(connection);

配置文件

		Properties properties =new Properties() ;
        //1.
        InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream("dbcp.properties");
        //2.
//        FileInputStream fis = new FileInputStream("src/dbcp.properties");
        properties.load(is);
        BasicDataSource source = BasicDataSourceFactory.createDataSource(properties);
        Connection connection = source.getConnection();
        System.out.println(connection);

JDBC中解

封装到JDBCUtils

	private static  BasicDataSource source;
    public static Connection getDBCPConnection() throws Exception {
        return source.getConnection();
    }
    static {
        try {
            Properties properties =new Properties() ;
            InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream("dbcp.properties");
            properties.load(is);
            source = BasicDataSourceFactory.createDataSource(properties);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

Druid

使用

		Properties properties =new Properties() ;
        InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream("druid.properties");
        properties.load(is);
        DataSource source = DruidDataSourceFactory.createDataSource(properties);
        System.out.println(source.getConnection());

JDBC中解

封装到JDBCUtils

	private static DataSource dataSource;
    public static Connection getDruidConnection() throws Exception {
        return dataSource.getConnection();
    }
    static {
        try {
            Properties properties =new Properties() ;
            InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream("druid.properties");
            properties.load(is);
            dataSource = DruidDataSourceFactory.createDataSource(properties);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

六:Dbutils

commons-dbutils是Apache 组织提供的一个开源JDBC工具类库,封装了针对于数据库的增删改查操作

更新操作

		Connection connection=null;
        try {
            QueryRunner runner = new QueryRunner();
            connection = JDBCUtils.getDruidConnection();
            String sql ="insert into t_link (name,url,image) values (?,?,?)" ;
            int i = runner.update(connection, sql, "王宁", "www.baidu.com", "big");
            System.out.println("添加了"+i+"条记录");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            JDBCUtils.closeResource(connection, null);
        }

查询操作

BeanHandler

BeanHandler是ResultSetHandler接口的实现类,用于封装表中的一条记录。

		QueryRunner runner = new QueryRunner();
        Connection connection = JDBCUtils.getDruidConnection();
        String sql = "select id,name,url,image from t_link where id = ?";
        BeanHandler<Link> handler = new BeanHandler<>(Link.class);
        System.out.println(runner.query(connection, sql, handler,2));

		QueryRunner runner = new QueryRunner();
        Connection connection = JDBCUtils.getDruidConnection();
        String sql="select id,name,url,image from t_link where id > ?";
        BeanListHandler<Link> listHandler = new BeanListHandler<>(Link.class);
        List<Link> list = runner.query(connection, sql, listHandler, 2);
        for (Link link : list) {
            System.out.println(link);
        }

MapHandler

MapHandler是ResultSetHandler接口的实现类,对应表中的一条记录(将字段及相应字段的值作为map中的key和value)。

		QueryRunner runner = new QueryRunner();
        Connection connection = JDBCUtils.getDruidConnection();
        String sql="select id,name,url,image from t_link where id > ?";
        MapHandler handler = new MapHandler();
        Map<String, Object> query = runner.query(connection, sql, handler, 2);
        System.out.println(query+"-----"+query.size());

MapListHandler

MapListHandler:是ResultSetHandler接口的实现类,对应表中的一条记录(将字段及相应字段的值作为map中的key和value)。

		QueryRunner runner = new QueryRunner();
        Connection connection = JDBCUtils.getDruidConnection();
        String sql="select id,name,url,image from t_link where id > ?";
        MapListHandler handler = new MapListHandler();
        List<Map<String, Object>> query = runner.query(connection, sql, handler, 2);
        System.out.println(query+"-----"+query.size());

ScalarHandler

用于查询特殊值

		QueryRunner runner = new QueryRunner();
        Connection connection = JDBCUtils.getDruidConnection();
        String sql="select count(*) from t_link ";
        ScalarHandler<Long> handler = new ScalarHandler<>();
        Long query = runner.query(connection, sql, handler);
        System.out.println(query+"-----");

自定义

		QueryRunner runner = new QueryRunner();
        Connection connection = JDBCUtils.getDruidConnection();
        String sql = "select id,name,url,image from t_link where id = ?";
        ResultSetHandler<Link> handler = new ResultSetHandler<Link>() {
            @Override
            public Link handle(ResultSet resultSet) throws SQLException {
                return new Link(5, "Z战士", "www", "small");
            }
        };
        Link query = runner.query(connection, sql, handler, 6);
        System.out.println(query+"-----");

关闭数据库连接操作

public static void closeUtilsResource(Connection connection, PreparedStatement statement, ResultSet resultSet){
        DbUtils.closeQuietly(resultSet);
        DbUtils.closeQuietly(connection);
        DbUtils.closeQuietly(statement);
    }
上一篇:在 Mac OS X 上创建的 .NET 命令行程序访问数据库 (使用Entity Framework 7 )


下一篇:JDBC中execute、executeQuery和executeUpdate的区别