0


JDBC详细全解(示例超多)

文章目录

JDBC

JDBC的概念

1.jdbc的概念

JDBC ( Java DataBaseConnectivity java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系型数据库提供统一访问,它是由一组用Java语言编写的类和接口组成的。

2.jdbc的本质

其实就是java官方提供的一套规范(接口)。用于帮助开发人员快速实现不同关系型数据库的连接!

JDBC快速入门

jdbc的快速入门步骤:

1.导入jar包

2.注册驱动

3.获取数据库连接

4.获取执行者对象

5.执行sql语句并返回结果

6.处理结果

7.释放资源

示例代码:

importjava.sql.Connection;importjava.sql.DriverManager;importjava.sql.ResultSet;importjava.sql.Statement;publicclassJDBC_index1{publicstaticvoidmain(String[] args)throwsException{//注册驱动Class.forName("com.mysql.cj.jdbc.Driver");//MySQL5以后可直接省略//获取数据库连接Connection con=DriverManager.getConnection("jdbc:mysql://localhost:3306/cadastre","root","XXXXXX");//获取执行者对象Statement stat=con.createStatement();//执行sql语句并返回结果String sql="select * from 网易云热评";ResultSet re=stat.executeQuery(sql);//处理结果while(re.next()){System.out.println(re.getString("userId")+"\t"+re.getString("nickname")+"\t"+re.getString("content"));}//释放资源
        con.close();}}

JDBC功能详解

1、DriverManager驱动管理对象

(1)注册驱动:(mysql5以后可直接省略驱动)
1.注册给定的驱动程序: staticvoid registerDriver(Driver driver);

2.写代码使用:Class.forName(“com.mysql.jdbc.Driver”);

3.在com.mysql.jdbc.Driver类中存在静态代码块

(2)获取数据库连接:
1.获取数据库连接对象: static ConnectiongetConnection(Stringurl, String user,String password);

2.返回值:Connection数据库连接对象

3.参数
url:指定连接的路径。语法: jdbc:mysql://ip地址(域名):端口号/数据库名称

​ user:用户名

​ password:密码

2、Connection数据库连接对象

1.获取执行者对象:
获取普通执行者对象: Statement createStatement0;
获取预编译执行者对象:PreparedStatement prepareStatement(String sql);

2.管理事务
开启事务 : setAutoCommit(boolean autoCommit);参数为false,则开启事务

​ 提交事务:commit();

​ 回滚事务: rollback();

3.释放资源
立即将数据库连接对象释放:void close();

3、Statement执行sql语句的对象

(1)执行DML语句: int executeUpdate(String sql);

返回值int :返回影响的行数。

参数sql:可以执行insert、update、delete语句。

(2) 执行DQL语句:ResultSet executeQuery(String sql);

返回值ResultSet:封装查询的结果。

参数sql:可以执行select语句。

(3)释放资源
立即将数据库连接对象释放:void close();

4、ResultSet结果集对象

1.判断结果集中是否还有数据: boolean next();

有数据返回true,并将索引向下移动一行。没有数据返回false。

2.获取结果集中的数据:XXX getXxx(“列名”);XXX代表数据类型(要获取某列数据,这一列的数据类型)。

例如: String getString(“name”);int getInt(" age");

3.释放资源

立即将结果集对象释放:void close();

JDBC案例

案例需求

使用JDBC完成对student表的CRUD操作

数据准备

1、数据库数据准备

-- 创建数据库
create DATABASE db14;

-- 使用数据库
use db14

-- 创建student表
CREATE TABLE student
(
   id int PRIMARY KEY,
     sname VARCHAR(20),
   age int,
     brithday date
);

-- 添加数据
INSERT into student VALUES(1,'张飞',23,'1999-08-11'),(2,'李四',23,'1998-08-11'),(3,'王五',23,'1997-08-11'),(4,'关羽',23,'1995-08-11');

2、创建student类

packageCom.Stuclass;importjava.util.Date;publicclassStudent{privateInteger id;privateString sname;privateInteger age;privateDate birthday;publicStudent(Integer id,String sname,Integer age,Date birthday){this.id = id;this.sname = sname;this.age = age;this.birthday = birthday;}publicIntegergetId(){return id;}publicvoidsetId(Integer id){this.id = id;}publicStringgetSname(){return sname;}publicvoidsetSname(String sname){this.sname = sname;}publicIntegergetAge(){return age;}publicvoidsetAge(Integer age){this.age = age;}publicDategetBirthday(){return birthday;}publicvoidsetBirthday(Date birthday){this.birthday = birthday;}@OverridepublicStringtoString(){return"Student{"+"id="+ id +", sname='"+ sname +'\''+", age="+ age +", birthday="+ birthday +'}';}}

功能实现

1、查询所有学生信息

publicArrayList<Student>findAll(){ArrayList<Student> list=newArrayList<>();Connection con=null;try{
            con=DriverManager.getConnection(conName,name,password);Statement statement = con.createStatement();String sql="select * from student";ResultSet resultSet = statement.executeQuery(sql);while(resultSet.next()){Integer id=resultSet.getInt("id");String sname=resultSet.getString("sname");Integer age=resultSet.getInt("age");Date birthday=resultSet.getDate("brithday");Student s=newStudent(id,sname,age,birthday);
                list.add(s);}}catch(SQLException e){
            e.printStackTrace();}finally{try{
                con.close();}catch(SQLException e){
                e.printStackTrace();}}return list;}

2、通过ID查询学生信息

publicStudentfindById(Integer id){Connection con=null;Student s =null;try{
            con=DriverManager.getConnection(conName,name,password);String sql="select * from student where id=?";PreparedStatement pstate = con.prepareStatement(sql);
            pstate.setInt(1,id);ResultSet resultSet = pstate.executeQuery();while(resultSet.next()){
                s=newStudent(id,resultSet.getString("sname"),resultSet.getInt("age"),resultSet.getDate("brithday"));}}catch(SQLException e){
            e.printStackTrace();}finally{try{
                con.close();}catch(SQLException e){
                e.printStackTrace();}}return s;}

3、添加学生记录

publicintinsert(Integer id,String sname,Integer age,String  birthday){Connection con=null;int re=0;Date date=newDate();//需要new一个Date对象SimpleDateFormat dateFormat =newSimpleDateFormat("yyyy-MM-dd");//设置日期格式  yyyy-MM-dd-HH-mm-ss这个是完整的try{
            date = dateFormat.parse(birthday);}catch(ParseException e){
            e.printStackTrace();}try{
            con=JDBCUtils.getConnect();String sql="insert into student values(?,?,?,?)";PreparedStatement p=con.prepareStatement(sql);
            p.setInt(1,id);
            p.setString(2,sname);
            p.setInt(3,age);
            p.setDate(4,newjava.sql.Date(date.getTime()));
            re = p.executeUpdate();}catch(SQLException e){
            e.printStackTrace();}finally{try{
                con.close();}catch(SQLException e){
                e.printStackTrace();}}return re;}

4、修改学生信息

publicintupdate(String name1,Integer age){Connection con=null;int result=0;String sql="update student "+"set age=? "+"where sname=?";try{
            con=JDBCUtils.getConnect();PreparedStatement p = con.prepareStatement(sql);
            p.setInt(1,age);
            p.setString(2,name1);
            result = p.executeUpdate();}catch(SQLException e){
            e.printStackTrace();}finally{try{
                con.close();}catch(SQLException e){
                e.printStackTrace();}}return result;}

5、删除学生记录

publicintdelete(Integer id){Connection con=null;int result=0;try{
            con=JDBCUtils.getConnect();String sql="delete from student where id=?";PreparedStatement p = con.prepareStatement(sql);
            p.setInt(1,id);
            result = p.executeUpdate();}catch(SQLException e){
            e.printStackTrace();}finally{try{
                con.close();}catch(SQLException e){
                e.printStackTrace();}}return result;}

推荐使用工具类

配置信息:(在src目录下创建config.properties文件)

driverClass=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/db14
username=root
password=XXXXXXx

工具类:

packageCom.Stuclass.utils;importjava.io.IOException;importjava.io.InputStream;importjava.sql.*;importjava.util.Properties;/*
* JDBC工具类
* */publicclassJDBCUtils{//    1、构造方法私有privateJDBCUtils(){}//    2、声明所需要的配置变量privatestaticString driverClass;privatestaticString url;privatestaticString username;privatestaticString password;privatestaticConnection con;//    3、提供静态代码块,读取配置文件信息为变量赋值,注册驱动static{try{//            赋值InputStream is =JDBCUtils.class.getClassLoader().getResourceAsStream("config.properties");Properties pro=newProperties();
            pro.load(is);
            driverClass=pro.getProperty("driverClass");
            url=pro.getProperty("url");
            username=pro.getProperty("username");
            password=pro.getProperty("password");//            注册驱动Class.forName(driverClass);}catch(IOException e){
            e.printStackTrace();}catch(ClassNotFoundException e){
            e.printStackTrace();}}//        获取数据库连接publicstaticConnectiongetConnect(){try{
            con=DriverManager.getConnection(url,username,password);}catch(SQLException e){
            e.printStackTrace();}return con;}//    关闭连接publicstaticvoidclose(Connection con,Statement state,ResultSet rs){if(con!=null){try{
                con.close();}catch(SQLException e){
                e.printStackTrace();}}if(state!=null){try{
                state.close();}catch(SQLException e){
                e.printStackTrace();}}if(rs!=null){try{
                rs.close();}catch(SQLException e){
                e.printStackTrace();}}}publicstaticvoidclose(Connection con,Statement state){if(con!=null){try{
                con.close();}catch(SQLException e){
                e.printStackTrace();}}if(state!=null){try{
                state.close();}catch(SQLException e){
                e.printStackTrace();}}}}

SQL注入攻击

利用SQL语句漏洞对系统进行攻击

例如:

按照正常道理来说,我们在密码处输入的所有内容,都应该认为是密码的组成

但是现在Statement对象在执行sql语句时,将密码的一部分内容当做查询条件来执行了

解决方式:

利用预编译SQL语句

JDBC事务管理

JDBC如何管理事务

管理事务的功能类:Connection

​ 开启事务: setAutoCommit(boolean autoCommit);参数为false,则开启事务。

​ 提交事务:commit();

​ 回滚事务:rollback();

数据库连接池

1.数据库连接的背景
数据库连接是一种关键的、有限的、昂贵的资源,这一点在多用户的网页应用程序中体现得尤为突出对数据库连接的管理能显著影响到整个应用程序的性能指标,数据库连接池正是针对这个问题提出来的

⒉.数据库连接池
数据库连接池负责分配、管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个。这项技术能明显提高对数据库操作的性能

自定义数据库连接池

1.DataSource接口概述
javax.sql.DataSource接口∶数据源(数据库连接池)。

Java官方提供的数据库连接池规范(接口)如果想完成数据库连接池技术,就必须实现DataSource接口

核心功能:获取数据库连接对象:Connection getConnection();

2.自定义数据库连接池

定义一个类,实现DataSource接口。

定义一个容器,用于保存多个Connection连接对象。

定义静态代码块,通过JDBC工具类获取10个连接保存到容器中。

重写getConnection方法,从容器中获取一个连接并返回。

定义getSize方法,用于获取容器的大小并返回。

准备:

上文中的JDBCutill工具类和相关配置文件

示例:

packageJDBCplus.Demo1;/*
* 自定义数据库连接池
* */importJDBCplus.JDBCUtils;importjavax.sql.DataSource;importjava.io.PrintWriter;importjava.sql.Connection;importjava.sql.SQLException;importjava.sql.SQLFeatureNotSupportedException;importjava.util.ArrayList;importjava.util.Collections;importjava.util.List;importjava.util.logging.Logger;publicclassMyDataSourceimplementsDataSource{//    1、准备容器  注意必须是线程安全的privatestaticList<Connection> pool=Collections.synchronizedList(newArrayList<>());//    2、通过工具类获取10个连接对象static{for(int i =0; i <10; i++){Connection con=JDBCUtils.getConnect();
        pool.add(con);}}//    3、重写getConnection方法@OverridepublicConnectiongetConnection()throwsSQLException{if(pool.size()>0){return pool.remove(0);}else{thrownewRuntimeException("连接池已空");}}//    4、定义getSize方法获取连接池大小publicintgetSize(){return pool.size();}@OverridepublicConnectiongetConnection(String username,String password)throwsSQLException{returnnull;}@Overridepublic<T>Tunwrap(Class<T> iface)throwsSQLException{returnnull;}@OverridepublicbooleanisWrapperFor(Class<?> iface)throwsSQLException{returnfalse;}@OverridepublicPrintWritergetLogWriter()throwsSQLException{returnnull;}@OverridepublicvoidsetLogWriter(PrintWriter out)throwsSQLException{}@OverridepublicvoidsetLoginTimeout(int seconds)throwsSQLException{}@OverridepublicintgetLoginTimeout()throwsSQLException{return0;}@OverridepublicLoggergetParentLogger()throwsSQLFeatureNotSupportedException{returnnull;}}

使用测试:

packageJDBCplus.Demo1;importjava.sql.Connection;importjava.sql.ResultSet;importjava.sql.SQLException;importjava.sql.Statement;publicclassTest{publicstaticvoidmain(String[] args)throwsSQLException{MyDataSource myDataSource =newMyDataSource();Connection con=myDataSource.getConnection();String sql="select * from student";Statement statement = con.createStatement();ResultSet resultSet = statement.executeQuery(sql);while(resultSet.next()){System.out.println(resultSet.getInt("id")+" "+resultSet.getString("sname"));}
        resultSet.close();
        statement.close();
        con.close();}}

image-20221013150926078

归还连接

归还数据库连接的方式:

继承方式

装饰设计模式

适配器设计模式

动态代理方式

归还连接-继承方式

1.继承方式归还数据库连接的思想。

通过打印连接对象,发现DriverManager获取的连接实现类是JDBC4Connection那我们就可以自定义一个类,继承JDBC4Connection这个类,重写close()方法完成连接对象的归还。

2.继承方式归还数据库连接的实现步骤。

1定义一个类,继承JDBC4Connection。

2定义Connection连接对象和连接池容器对象的成员变量。

3通过有参构造方法完成对成员变量的赋值。

4重写close方法,将连接对象添加到池中。

3.继承方式归还数据库连接存在的问题。

通过查看JDBC工具类获取连接的方法发现∶我们虽然自定义了一个子类,完成了归还连接的操作。但是DriverManager获取的还是JDBC4Connection这个对象,并不是我们的子类对象,而我们又不能整体去修改驱动包中类的功能,所继承这种方式行不通!心

(此处我的MySQL包中未找到JDBC4Connection类不能展示)

归还连接-装饰设计模式

1.装饰设计模式归还数据库连接的思想。

我们可以自定义一个类,实现Connection接口。

这样就具备了和JDBC4Connection相同的行为了重写close()方法,完成连接的归还。其余的功能还调用mysql驱动包实现类原有的方法即可。

2.装饰设计模式归还数据库连接的实现步骤。

1、定义一个类,实现Connection接口

2、定义Connection连接对象和连接池容器对象的成员变量

3、通过有参构造方法完成对成员变量的赋值

4、重写close()方法,将连接对象添加到池中

5、剩余方法,只需要调用mysql驱动包的连接对象完成即可

6、在自定义连接池中,将获取的连接对象通过自定义连接对象进行包装

3.装饰设计模式归还数据库连接存在的问题。

实现Connection接口后,有大量的方法需要在自定义类中进行重写

示例代码:

packageJDBCplus.Demo2;importjava.sql.*;importjava.util.*;importjava.util.concurrent.Executor;publicclassMyConnection2implementsConnection{//    定义连接对象和连接池对象privateConnection con;privateList<Connection> pool;//    构造方法赋值publicMyConnection2(Connection con,List<Connection> pool){this.con=con;this.pool=pool;}//     重写close方法@Overridepublicvoidclose()throwsSQLException{
        pool.add(con);}@OverridepublicStatementcreateStatement()throwsSQLException{return con.createStatement();}@OverridepublicPreparedStatementprepareStatement(String sql)throwsSQLException{return con.prepareStatement(sql);}@OverridepublicCallableStatementprepareCall(String sql)throwsSQLException{return con.prepareCall(sql);}@OverridepublicStringnativeSQL(String sql)throwsSQLException{return con.nativeSQL(sql);}@OverridepublicvoidsetAutoCommit(boolean autoCommit)throwsSQLException{
        con.setAutoCommit(false);}@OverridepublicbooleangetAutoCommit()throwsSQLException{return con.getAutoCommit();}@Overridepublicvoidcommit()throwsSQLException{
        con.commit();}@Overridepublicvoidrollback()throwsSQLException{
        con.rollback();}@OverridepublicbooleanisClosed()throwsSQLException{return con.isClosed();}@OverridepublicDatabaseMetaDatagetMetaData()throwsSQLException{return con.getMetaData();}@OverridepublicvoidsetReadOnly(boolean readOnly)throwsSQLException{
         con.setReadOnly(false);}@OverridepublicbooleanisReadOnly()throwsSQLException{return con.isReadOnly();}@OverridepublicvoidsetCatalog(String catalog)throwsSQLException{
        con.setCatalog(catalog);}@OverridepublicStringgetCatalog()throwsSQLException{return con.getCatalog();}@OverridepublicvoidsetTransactionIsolation(int level)throwsSQLException{
        con.setTransactionIsolation(level);}@OverridepublicintgetTransactionIsolation()throwsSQLException{return con.getTransactionIsolation();}@OverridepublicSQLWarninggetWarnings()throwsSQLException{return con.getWarnings();}@OverridepublicvoidclearWarnings()throwsSQLException{
        con.clearWarnings();}@OverridepublicStatementcreateStatement(int resultSetType,int resultSetConcurrency)throwsSQLException{return con.createStatement(resultSetType,resultSetConcurrency);}@OverridepublicPreparedStatementprepareStatement(String sql,int resultSetType,int resultSetConcurrency)throwsSQLException{return con.prepareStatement(sql,resultSetType,resultSetConcurrency);}@OverridepublicCallableStatementprepareCall(String sql,int resultSetType,int resultSetConcurrency)throwsSQLException{return con.prepareCall(sql,resultSetType,resultSetConcurrency);}@OverridepublicMap<String,Class<?>>getTypeMap()throwsSQLException{return con.getTypeMap();}@OverridepublicvoidsetTypeMap(Map<String,Class<?>> map)throwsSQLException{
        con.setTypeMap(map);}@OverridepublicvoidsetHoldability(int holdability)throwsSQLException{
        con.setHoldability(holdability);}@OverridepublicintgetHoldability()throwsSQLException{return con.getHoldability();}@OverridepublicSavepointsetSavepoint()throwsSQLException{return con.setSavepoint();}@OverridepublicSavepointsetSavepoint(String name)throwsSQLException{return con.setSavepoint(name);}@Overridepublicvoidrollback(Savepoint savepoint)throwsSQLException{
        con.rollback();}@OverridepublicvoidreleaseSavepoint(Savepoint savepoint)throwsSQLException{
        con.releaseSavepoint(savepoint);}@OverridepublicStatementcreateStatement(int resultSetType,int resultSetConcurrency,int resultSetHoldability)throwsSQLException{return con.createStatement(resultSetType,resultSetConcurrency,resultSetHoldability);}@OverridepublicPreparedStatementprepareStatement(String sql,int resultSetType,int resultSetConcurrency,int resultSetHoldability)throwsSQLException{return con.prepareStatement(sql,resultSetType,resultSetConcurrency);}@OverridepublicCallableStatementprepareCall(String sql,int resultSetType,int resultSetConcurrency,int resultSetHoldability)throwsSQLException{return con.prepareCall(sql,resultSetType,resultSetConcurrency,resultSetHoldability);}@OverridepublicPreparedStatementprepareStatement(String sql,int autoGeneratedKeys)throwsSQLException{return con.prepareStatement(sql,autoGeneratedKeys);}@OverridepublicPreparedStatementprepareStatement(String sql,int[] columnIndexes)throwsSQLException{return con.prepareStatement(sql,columnIndexes);}@OverridepublicPreparedStatementprepareStatement(String sql,String[] columnNames)throwsSQLException{return con.prepareStatement(sql,columnNames);}@OverridepublicClobcreateClob()throwsSQLException{return con.createClob();}@OverridepublicBlobcreateBlob()throwsSQLException{return con.createBlob();}@OverridepublicNClobcreateNClob()throwsSQLException{return con.createNClob();}@OverridepublicSQLXMLcreateSQLXML()throwsSQLException{return con.createSQLXML();}@OverridepublicbooleanisValid(int timeout)throwsSQLException{return con.isValid(timeout);}@OverridepublicvoidsetClientInfo(String name,String value)throwsSQLClientInfoException{
        con.setClientInfo(name,value);}@OverridepublicvoidsetClientInfo(Properties properties)throwsSQLClientInfoException{
        con.setClientInfo(properties);}@OverridepublicStringgetClientInfo(String name)throwsSQLException{return con.getClientInfo(name);}@OverridepublicPropertiesgetClientInfo()throwsSQLException{return con.getClientInfo();}@OverridepublicArraycreateArrayOf(String typeName,Object[] elements)throwsSQLException{return con.createArrayOf(typeName,elements);}@OverridepublicStructcreateStruct(String typeName,Object[] attributes)throwsSQLException{return con.createStruct(typeName,attributes);}@OverridepublicvoidsetSchema(String schema)throwsSQLException{
        con.setSchema(schema);}@OverridepublicStringgetSchema()throwsSQLException{return con.getSchema();}@Overridepublicvoidabort(Executor executor)throwsSQLException{
        con.abort(executor);}@OverridepublicvoidsetNetworkTimeout(Executor executor,int milliseconds)throwsSQLException{
        con.setNetworkTimeout(executor,milliseconds);}@OverridepublicintgetNetworkTimeout()throwsSQLException{return con.getNetworkTimeout();}@Overridepublic<T>Tunwrap(Class<T> iface)throwsSQLException{return con.unwrap(iface);}@OverridepublicbooleanisWrapperFor(Class<?> iface)throwsSQLException{return con.isWrapperFor(iface);}}

更改MyDataSouce(数据库连接池方法):

//    3、重写getConnection方法@OverridepublicConnectiongetConnection()throwsSQLException{if(pool.size()>0){Connection con = pool.remove(0);MyConnection2 myCon=newMyConnection2(con,pool);return myCon;}else{thrownewRuntimeException("连接池已空");}}

测试代码:

packageJDBCplus.Demo1;importjava.sql.Connection;importjava.sql.ResultSet;importjava.sql.SQLException;importjava.sql.Statement;publicclassTest{publicstaticvoidmain(String[] args)throwsSQLException{MyDataSource myDataSource =newMyDataSource();System.out.println(myDataSource.getSize());Connection con=myDataSource.getConnection();System.out.println(myDataSource.getSize());System.out.println(con.getClass());String sql="select * from student";Statement statement = con.createStatement();ResultSet resultSet = statement.executeQuery(sql);while(resultSet.next()){System.out.println(resultSet.getInt("id")+" "+resultSet.getString("sname"));}
        resultSet.close();
        statement.close();
        con.close();System.out.println(myDataSource.getSize());}}

image-20221013164305855
发现父类为自定义类,使用后连接池大小为10

归还连接-适配器设计模式

1.适配器设计模式归还数据库连接的思想。

我们可以提供一个适配器类,实现Connection接口,将所有方法进行实现(除了close方法

自定义连接类只需要继承这个适配器类,重写需要改进的close方法即可

2.适配器设计模式归还数据库连接的实现步骤。

1定义一个适配器类,实现Connection接口。

2定义Connection连接对象的成员变量。

3通过有参构造方法完成对成员变量的赋值。

4重写所有方法(除了close ),调用mysq驱动包的连接对象完成即可。

5定义一个连接类,继承适配器类。

6定义Connection连接对象和连接池容器对象的成员变量,并通过有参构造进行赋值。

7重写close()方法,完成归还连接。

8在自定义连接池中,将获取的连接对象通过自定义连接对象进行包装。

3.适配器设计模式归还数据库连接存在的问题。

自定义连接类虽然很简洁了,但适配器类还是我们自己编写的,也比较的麻烦

示例代码:

适配器类:(重写除close外的所有方法,抽象类)

packageJDBCplus.Dome3;importjava.sql.*;importjava.util.Map;importjava.util.Properties;importjava.util.concurrent.Executor;/*
* 适配器类
* */publicabstractclassMyAdapterimplementsConnection{privateConnection con;publicMyAdapter(Connection con){this.con=con;}@OverridepublicStatementcreateStatement()throwsSQLException{return con.createStatement();}@OverridepublicPreparedStatementprepareStatement(String sql)throwsSQLException{return con.prepareStatement(sql);}@OverridepublicCallableStatementprepareCall(String sql)throwsSQLException{return con.prepareCall(sql);}@OverridepublicStringnativeSQL(String sql)throwsSQLException{return con.nativeSQL(sql);}@OverridepublicvoidsetAutoCommit(boolean autoCommit)throwsSQLException{
        con.setAutoCommit(false);}@OverridepublicbooleangetAutoCommit()throwsSQLException{return con.getAutoCommit();}@Overridepublicvoidcommit()throwsSQLException{
        con.commit();}@Overridepublicvoidrollback()throwsSQLException{
        con.rollback();}@OverridepublicbooleanisClosed()throwsSQLException{return con.isClosed();}@OverridepublicDatabaseMetaDatagetMetaData()throwsSQLException{return con.getMetaData();}@OverridepublicvoidsetReadOnly(boolean readOnly)throwsSQLException{
        con.setReadOnly(false);}@OverridepublicbooleanisReadOnly()throwsSQLException{return con.isReadOnly();}@OverridepublicvoidsetCatalog(String catalog)throwsSQLException{
        con.setCatalog(catalog);}@OverridepublicStringgetCatalog()throwsSQLException{return con.getCatalog();}@OverridepublicvoidsetTransactionIsolation(int level)throwsSQLException{
        con.setTransactionIsolation(level);}@OverridepublicintgetTransactionIsolation()throwsSQLException{return con.getTransactionIsolation();}@OverridepublicSQLWarninggetWarnings()throwsSQLException{return con.getWarnings();}@OverridepublicvoidclearWarnings()throwsSQLException{
        con.clearWarnings();}@OverridepublicStatementcreateStatement(int resultSetType,int resultSetConcurrency)throwsSQLException{return con.createStatement(resultSetType,resultSetConcurrency);}@OverridepublicPreparedStatementprepareStatement(String sql,int resultSetType,int resultSetConcurrency)throwsSQLException{return con.prepareStatement(sql,resultSetType,resultSetConcurrency);}@OverridepublicCallableStatementprepareCall(String sql,int resultSetType,int resultSetConcurrency)throwsSQLException{return con.prepareCall(sql,resultSetType,resultSetConcurrency);}@OverridepublicMap<String,Class<?>>getTypeMap()throwsSQLException{return con.getTypeMap();}@OverridepublicvoidsetTypeMap(Map<String,Class<?>> map)throwsSQLException{
        con.setTypeMap(map);}@OverridepublicvoidsetHoldability(int holdability)throwsSQLException{
        con.setHoldability(holdability);}@OverridepublicintgetHoldability()throwsSQLException{return con.getHoldability();}@OverridepublicSavepointsetSavepoint()throwsSQLException{return con.setSavepoint();}@OverridepublicSavepointsetSavepoint(String name)throwsSQLException{return con.setSavepoint(name);}@Overridepublicvoidrollback(Savepoint savepoint)throwsSQLException{
        con.rollback();}@OverridepublicvoidreleaseSavepoint(Savepoint savepoint)throwsSQLException{
        con.releaseSavepoint(savepoint);}@OverridepublicStatementcreateStatement(int resultSetType,int resultSetConcurrency,int resultSetHoldability)throwsSQLException{return con.createStatement(resultSetType,resultSetConcurrency,resultSetHoldability);}@OverridepublicPreparedStatementprepareStatement(String sql,int resultSetType,int resultSetConcurrency,int resultSetHoldability)throwsSQLException{return con.prepareStatement(sql,resultSetType,resultSetConcurrency);}@OverridepublicCallableStatementprepareCall(String sql,int resultSetType,int resultSetConcurrency,int resultSetHoldability)throwsSQLException{return con.prepareCall(sql,resultSetType,resultSetConcurrency,resultSetHoldability);}@OverridepublicPreparedStatementprepareStatement(String sql,int autoGeneratedKeys)throwsSQLException{return con.prepareStatement(sql,autoGeneratedKeys);}@OverridepublicPreparedStatementprepareStatement(String sql,int[] columnIndexes)throwsSQLException{return con.prepareStatement(sql,columnIndexes);}@OverridepublicPreparedStatementprepareStatement(String sql,String[] columnNames)throwsSQLException{return con.prepareStatement(sql,columnNames);}@OverridepublicClobcreateClob()throwsSQLException{return con.createClob();}@OverridepublicBlobcreateBlob()throwsSQLException{return con.createBlob();}@OverridepublicNClobcreateNClob()throwsSQLException{return con.createNClob();}@OverridepublicSQLXMLcreateSQLXML()throwsSQLException{return con.createSQLXML();}@OverridepublicbooleanisValid(int timeout)throwsSQLException{return con.isValid(timeout);}@OverridepublicvoidsetClientInfo(String name,String value)throwsSQLClientInfoException{
        con.setClientInfo(name,value);}@OverridepublicvoidsetClientInfo(Properties properties)throwsSQLClientInfoException{
        con.setClientInfo(properties);}@OverridepublicStringgetClientInfo(String name)throwsSQLException{return con.getClientInfo(name);}@OverridepublicPropertiesgetClientInfo()throwsSQLException{return con.getClientInfo();}@OverridepublicArraycreateArrayOf(String typeName,Object[] elements)throwsSQLException{return con.createArrayOf(typeName,elements);}@OverridepublicStructcreateStruct(String typeName,Object[] attributes)throwsSQLException{return con.createStruct(typeName,attributes);}@OverridepublicvoidsetSchema(String schema)throwsSQLException{
        con.setSchema(schema);}@OverridepublicStringgetSchema()throwsSQLException{return con.getSchema();}@Overridepublicvoidabort(Executor executor)throwsSQLException{
        con.abort(executor);}@OverridepublicvoidsetNetworkTimeout(Executor executor,int milliseconds)throwsSQLException{
        con.setNetworkTimeout(executor,milliseconds);}@OverridepublicintgetNetworkTimeout()throwsSQLException{return con.getNetworkTimeout();}@Overridepublic<T>Tunwrap(Class<T> iface)throwsSQLException{return con.unwrap(iface);}@OverridepublicbooleanisWrapperFor(Class<?> iface)throwsSQLException{return con.isWrapperFor(iface);}}

自定义连接类:

packageJDBCplus.Dome3;importjava.sql.Connection;importjava.sql.SQLException;importjava.util.List;/*
* 自定义连接类
* */publicclassMyConnection3extendsMyAdapter{//    定义连接对象和连接池对象privateConnection con;privateList<Connection> pool;//    构造方法赋值publicMyConnection3(Connection con,List<Connection> pool){super(con);this.con=con;this.pool=pool;}@Overridepublicvoidclose()throwsSQLException{
        pool.add(con);}}

数据库连接池更改:

//    3、重写getConnection方法@OverridepublicConnectiongetConnection()throwsSQLException{if(pool.size()>0){Connection con = pool.remove(0);MyConnection3 myCon=newMyConnection3(con,pool);return myCon;}else{thrownewRuntimeException("连接池已空");}}

测试代码:

(同装饰设计模式)
image-20221013170409082
目标到达

动态代理

动态代理:

在不改变目标对象方法的情况下对方法进行增强

组成:

被代理对象︰真实的对象

代理对象︰内存中的一个对象

要求:

代理对象必须和被代理对象实现相同的接口

示例:

student类:

packageproxy;publicclassStudentimplementsStudentInterface{@Overridepublicvoideat(String name){System.out.println("学生吃"+name);}@Overridepublicvoidstudy(){System.out.println("在家自学");}}

StudentInterface接口:

package proxy;

public interface StudentInterface {
    public void eat(String name);
    public void study();
}

测试:

packageproxy;importjava.lang.reflect.InvocationHandler;importjava.lang.reflect.Method;importjava.lang.reflect.Proxy;publicclassTest{publicstaticvoidmain(String[] args){Student student =newStudent();
        student.study();
        student.eat("米饭");/*
        * 要求不改动Student的代码,更改study方法的输出内容
        * *///参数一:类加载器,参数二:接口类型class数组,参数三:代理规则StudentInterface proxy=(StudentInterface)Proxy.newProxyInstance(student.getClass().getClassLoader(),newClass[]{StudentInterface.class},newInvocationHandler(){/*
            * 执行student类中所有的方法都会经过invoke方法
            * 对method方法判断,修改想要的方法
            * */@OverridepublicObjectinvoke(Object proxy,Method method,Object[] args)throwsThrowable{if(method.getName().equals("study")){System.out.println("不去学习");returnnull;}else{return method.invoke(student,args);}}});
        proxy.eat("米饭");
        proxy.study();}}

运行结果:
image-20221013173931028
成功修改

动态代理归还数据库连接:

1.动态代理方式归还数据库连接的思想。

我们可以通过Proxy来完成对Connection实现类对象的代理

代理过程中判断如果执行的是close方法,就将连接归还池中。

如果是其他方法则调用连接对象原来的功能即可

2.动态代理方式归还数据库连接的实现步骤。

定义一个类,实现DataSource接口

定义一个容器,用于保存多个Connection连接对象

定义静态代码块,通过JDBC工具类获取10个连接保存到容器中

重写getConnection方法,从容器中获取一个连接

通过 Proxy代理,如果是close方法,就将连接归还池中。如果是其他方法却则调用原有功能

定义getSize方法,用于获取容器的大小并返回

实现重写MyDataSource中的getConnection方法(使用动态代理方式实现)

//   3、重写getConnection方法   使用动态代理方式实现@OverridepublicConnectiongetConnection()throwsSQLException{if(pool.size()>0){Connection con = pool.remove(0);Connection myCon =(Connection)Proxy.newProxyInstance(con.getClass().getClassLoader(),newClass[]{Connection.class},newInvocationHandler(){@OverridepublicObjectinvoke(Object proxy,Method method,Object[] args)throwsThrowable{if(method.getName().equals("close")){
                        pool.add(con);returnnull;}else{return method.invoke(con,args);}}});return myCon;}else{thrownewRuntimeException("连接池已空");}}

使用上文中测试代码:

image-20221014160000515

开源数据库连接池

C3P0数据库连接池

1.C3PO数据库连接池的使用步骤。

导入jar包。

导入配置文件到src目录下。

创建C3PO连接池对象。

获取数据库连接进行使用。

注意:C3PO的配置文件会自动加载,但是必须叫c3p0-config.xml或 c3pO-config.properties

下载jar包:

官网:https://sourceforge.net/projects/c3p0/files/latest/download

别人百度网盘:百度网盘下载链接:https://pan.baidu.com/s/1o9cBkMVb_kZmAksZjjoZYg 密码:c7pr

导入jar包:

image-20221014163706222

导入配置文件到src目录:

image-20221014163828508

使用示例:

package C3P0;importcom.mchange.v2.c3p0.ComboPooledDataSource;importjava.sql.Connection;importjava.sql.PreparedStatement;importjava.sql.ResultSet;importjava.sql.SQLException;publicclassTest1{publicstaticvoidmain(String[] args)throwsSQLException{//        1、创建c3p0数据库连接池ComboPooledDataSource dataSource =newComboPooledDataSource();//        2、通过连接池获取数据库连接Connection con = dataSource.getConnection();//        3、执行数据库操作String sql="select * from student";PreparedStatement p = con.prepareStatement(sql);ResultSet re = p.executeQuery();while(re.next()){System.out.println(re.getInt("id")+"\t"+re.getString("sname"));}}}

image-20221014163917795

Druid数据库连接池

1、介绍

Druid(德鲁伊)是阿里巴巴开发的号称为监控而生的数据库连接池,Druid是目前最好的数据库连接池。在功能、性能、扩展性方面,都超过其他数据库连接池,同时加入了日志监控,可以很好的监控DB池连接和SQL的执行情况。Druid已经在阿里巴巴部署了超过600个应用,经过一年多生产环境大规模部署的严苛考验。

1.Druid数据库连接池的使用步骤:

导入jar包。

编写配置文件,放在src目录下。

通过Properties集合加载配置文件。

通过Druid连接池工厂类获取数据库连接池对象。

获取数据库连接进行使用。

注意:Druid不会自动加载配置文件,需要我们手动加载,但是文件的名称可以自定义。

下载jar包:

别人的百度网盘::https://pan.baidu.com/s/1U9v5c_DindqXva92JeRVJQ 密码:nquq

导入jar包:

image-20221014171619816

编写配置文件:

driverClassName=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/db14
username=root
password=xxxxxx
initialSize=5
maxActive=10
maxWait=3000

示例代码:

packageDruid;importcom.alibaba.druid.pool.DruidDataSource;importcom.alibaba.druid.pool.DruidDataSourceFactory;importjavax.sql.DataSource;importjava.io.InputStream;importjava.sql.Connection;importjava.sql.PreparedStatement;importjava.sql.ResultSet;importjava.util.Properties;publicclass test1 {publicstaticvoidmain(String[] args)throwsException{//        获取配置文件的流对象InputStream is = test1.class.getClassLoader().getResourceAsStream("druid.properties");//        通过properties集合,加载配置文件Properties properties =newProperties();
        properties.load(is);//        通过Druid连接池工厂类获取连接池对象DataSource dataSource =DruidDataSourceFactory.createDataSource(properties);//        连接池中获取连接对象Connection con = dataSource.getConnection();//        执行数据库操作String sql="select * from student";PreparedStatement p = con.prepareStatement(sql);ResultSet re = p.executeQuery();while(re.next()){System.out.println(re.getInt("id")+"\t"+re.getString("sname"));}}}

image-20221014174345716

基于Druid数据库连接池创建的工具类

代码:

packageDruid;importcom.alibaba.druid.pool.DruidDataSourceFactory;importjavax.sql.DataSource;importjava.io.InputStream;importjava.sql.Connection;importjava.sql.ResultSet;importjava.sql.SQLException;importjava.sql.Statement;importjava.util.Properties;publicclassDruidUtils{//    私有化构造方法privateDruidUtils(){}//    声明数据源变量privatestaticDataSource dataSource;//    静态代码块完成配置文件加载和获取数据库连接对象static{InputStream is =DruidUtils.class.getClassLoader().getResourceAsStream("druid.properties");Properties properties =newProperties();try{
        properties.load(is);
        dataSource =DruidDataSourceFactory.createDataSource(properties);}catch(Exception e){
        e.printStackTrace();}}//   获取数据库连接publicstaticConnectiongetConnection(){Connection con=null;try{
            con = dataSource.getConnection();}catch(SQLException e){
            e.printStackTrace();}return con;}//   获取数据库连接池publicstaticDataSourcegetDataSource(){return dataSource;}//    关闭连接publicstaticvoidclose(Connection con,Statement state,ResultSet rs){if(con!=null){try{
                con.close();}catch(SQLException e){
                e.printStackTrace();}}if(state!=null){try{
                state.close();}catch(SQLException e){
                e.printStackTrace();}}if(rs!=null){try{
                rs.close();}catch(SQLException e){
                e.printStackTrace();}}}publicstaticvoidclose(Connection con,Statement state){if(con!=null){try{
                con.close();}catch(SQLException e){
                e.printStackTrace();}}if(state!=null){try{
                state.close();}catch(SQLException e){
                e.printStackTrace();}}}}

使用示例:

packageDruid;importjava.sql.Connection;importjava.sql.PreparedStatement;importjava.sql.ResultSet;importjava.sql.SQLException;publicclass test2 {publicstaticvoidmain(String[] args)throwsSQLException{Connection con=DruidUtils.getConnection();String sql="select * from student";PreparedStatement p = con.prepareStatement(sql);ResultSet re = p.executeQuery();while(re.next()){System.out.println(re.getInt("id")+"\t"+re.getString("sname"));}}}

image-20221014180438643

标签: 数据库 java sql

本文转载自: https://blog.csdn.net/qq_54353206/article/details/127325477
版权归原作者 爱打辅助的小可爱 所有, 如有侵权,请联系我们删除。

“JDBC详细全解(示例超多)”的评论:

还没有评论