前部分就是上一篇jdbc与jdbc工具类的内容,增加了jdbc数据库连接池DataSource与jdbctemplete的内容
JDBC
抽取JDBC工具类
使用JDBC数据库连接池
JDBCTemplete
代码
最原始的jdbc
抽取jdbc工具类
自己更改后的JDBC工具类(不确定是否有问题)
使用C3P0后的jdbc工具类抽取
使用Druid连接池技术抽取工具类
使用JdbcTemplate对数据库进行操作(使用c3p0或druid连接池技术封装的工具类)
JDBC
JDBC :java 数据库连接,Java语言操作数据库
JDBC本质:其实是官方(sun公司)定义的一套操作所有关系型数据库的规则,即接口。各个数据库厂商去实现这套接口,提供数据库驱动jar包。我们可以使用这套接口(JDBC)编程,真正执行的代码是驱动jar包中的实现类。
实现java 与 数据库具体步骤:
- 步骤:
1. 导入驱动jar包 mysql-connector-java-5.1.37-bin.jar
1.复制mysql-connector-java-5.1.37-bin.jar到项目的libs目录下
2.右键–>Add As Library
2. 注册/加载驱动
3. 获取数据库连接对象 Connection
4. 定义sql
5. 获取执行sql语句的对象 Statement
6. 执行sql,接受返回结果
7. 处理结果
8. 释放资源
详解:
一、什么是数据库驱动?
数据库驱动是不同数据库开发商(比如oracle mysql等)为了某一种开发语言环境(比如java)能够实现统一的数据库调用而开发的一个程序,他的作用相当于一个翻译人员,将Java语言中对数据库的调用语言通过这个翻译翻译成各个种类的数据库自己的数据库语言,当然这个翻译(数据库驱动)是由各个开发商针对统一的接口自定义开发的
二、我们对JDBC进行编程是为了什么?
JDBC只是提供了一个操作数据库的规则,但具体怎么操作要靠自己编程,我们将要怎么操作的java代码写出来后由数据库驱动去实现这些操作
就好像是一整套规则已经定义在哪,数据库驱动已经将这些规则具体要怎么做已经写了出来,我们要做的是调用这些接口,即我们要选择我们要执行那些规则,我们要做哪些事,我们要做哪些行为,这些就体现在我们编程的代码里,我们调用了哪些接口就是要做哪些事,我们要怎么去做这些事,接口是行为的抽象,我们要进行哪些行为就调用哪些接口,要怎么实现就要看数据库驱动怎么实现它
JDBC只定义接口,具体实现由各个数据库厂商负责。
程序员使用时只需要调用接口,实际调用的是底层数据库厂商的实现部分。
三、注册驱动:
实际上就是将具体的数据库驱动加载进来,我们要操作那个数据库,就要先加载这个数据库的具体实现方法进来,相当于对不同的人有不同的规则操作,要对你进行什么操作首先要确定你是什么人
四、连接数据库:
不同的数据库有不同的连接方式,,要连接数据库,首先要先表明我要连接(jdbc),怎么连接,先看是什么数据库,然后你要做什么操作,这个操作的具体操作怎么做(由数据库驱动搞定),数据库驱动来具体实现这个连接操作
五、执行sql语句的对象
会有一个对象来具体做这些操作,所以我们要先创建出这个对象出来
六、执行sql语句
由执行sql语句的对象执行sql语句,
七、接受结果
执行后,接收结果是什么
一、使用PreparedStatementt替换Statement
- 为什么要替换
PreparedStatement能够解决sql语句注入问题
2.什么是sql注入问题
形如 "select * from user where username = ‘lisi’ and password =‘123456’;“这种的sql语句查询数据库是否存在此人时,如果在password中输入a’ or ‘a’ = 'a 那么该sql语句就变成了"select * from user where username = ‘lisi’ and password =‘a’ or ‘a’ = ‘a’;” 该sql语句的语义就发生了变化 就一定能狗登陆成功,如果登陆的是管理员等高权限的用户的话,就会造成数据的不安全,而PreparedStatement使用?占位符解决了该问题,PreparedStatement中该语句为"select * from user where username = ?and password =?;"该sql语句先进行加载,上面的语句就会只是单纯的a’ or ‘a’ = 'a,会在数据库查询该用户的密码是否是这样,不会存在修改sql语句语义的情况,而且提前将sql语句加载进去还可以提高效率
3.如何给?占位符赋值
setXxx(参数1,参数2)
* 参数1:?的位置编号 从1 开始
* 参数2:?的值
抽取JDBC工具类
1.为什么要抽取
java连接数据库要进行加载驱动 获取连接对象 获取执行sql语句 释放资源的对象这一系列动作,但假设我们是对同一数据库的数据进行增删改查,那么每执行一条sql语句我们都要再次加载驱动 获取连接对象,获取执行sql语句的对象,但是这显然是非常麻烦且非常多余的,这些对象及驱动我们只需要执行一次就可以了,因此我们将这些都抽取出来,这样我们执行同一数据库的sql语句时就只用定义sql语句,获取结果就可以,这是很方便的
2.怎么抽取
2.1抽取加载驱动:
2.1.1原本应该如何加载驱动: Class.forName(驱动类的全类名)
2.1.2 现在如何把加载驱动抽取到工具类中
第一步:添加配置文件 配置文件中包含该驱动类的全类名
第二步:读取配置文件,获取配置文件中的驱动类的全类名并用String类型变量接收
第三步:加载驱动 Class.forName(String型变量)
第四步: 读取配置文件以及加载驱动在外部类中都不会在使用,并且只加载一次,所以可以写到静态代码块里面
2.1.3 在外部类里如何使用
获取该类时就自动加载不需要在外部类在写其他代码
2.2抽取获取连接的操作
2.2.1原本应如何获取连接:DriverManager.getConnection(目标数据库,用户名,密码);
2.2.2如何把获取连接对象抽取到jdbc工具类中
第一步:将相应的信息写入到配置文件中 目标数据库 用户名 密码
第二步:读取配置文件,获取配置文件中的相应信息,并将其保存到String类型的url user password中
第三步:获取连接 DriverManager.getConnection(url, user, password);
第四步:获取到的连接对象在其他类中还会再次使用 因此使用静态方法将获取连接对象抽取出来并返回一个Connection型变量 但第一二步与抽取加载驱动的一二步相同,因此这两步就与加载驱动的一二步结合起来使用
2.2.3 在外部类里如何使用
conn = JDBCUtils.getConnection()
2.3抽取关闭资源的操作
2.3.1原本应该如何关闭资源:先判断这些资源是否为null ,在进行关闭资源操作conn.close; state.close; 以及他们的捕获异常操作 ------->如果不先进行判断那么如果在获取的过程中失败了再关闭资源就会出现运行时异常
2.3.2 如何将关闭资源操作抽取
第一步 直接将其操作抽取到一个静态方法里
第二步 将其抽取成重载方法 --------> 参数分别为connection, connection statement, connection statement ResultSet
第三步 仅在参数最多的一个方法里进行判断并关闭资源,在其他的重载方法里调用该方法即可,没有的参数传null即可
2.4 可以在抽取获取连接的时候同时将获取执行sql语句的对象也一起获取。因为获取连接对象仅仅在获取执行sql语句的对象时使用,这样就可以再少写一条代码,具体有没有其他的问题还不明确,但在将statement换成preparedstatement后就不能这样写了,因为preparedstatement需要传入一个sql语句 问过别的大佬说可以这样抽取。
使用JDBC数据库连接池
一、什么是jdbc数据库连接池
就是一个用来存放数据库连接的容器--------->最终目的:获取连接
二、怎么使用jdbc连接池
使用jdbc连接池的步骤
1实现DataSource接口 (数据源就是数据库连接池)
2.获取连接 getConnection() DataSource的是实现类对象.getConnection()
3.归还连接 Connection.close() 连接对象.close() 归还连接和关闭资源虽然都是close,但是两者不同
已有的jdbc连接池实现技术
c3p0
如何使用C3P0获取连接
1.实现DataSource接口
`DataSource ds = new ComboPooledDataSource();`
2.获取连接 ds.getConnection() (事先配置好连接数据库的配置文件)
未使用jdbc连接池技术的获取连接
Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/db4","root","root");
使用jdbc连接池技术的获取连接
Connection connection = ds.getConnection();
c3p0连接池技术的配置文件
<c3p0-config>
<!-- 使用默认的配置读取连接池对象 -->
<default-config>
<!-- 连接参数 -->
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/db3</property>
<property name="user">root</property>
<property name="password">root</property>
<!-- 连接池参数 -->
<!--默认使用该配置文件-->
<!-- 初始化申请的连接数量-->
<property name="initialPoolSize">5</property>
<!--最大的连接数量-->
<property name="maxPoolSize">10</property>
<!--超时时间-->
<property name="checkoutTimeout">3000</property>
</default-config>
<!--c3p0允许同一配置文件下配置多个配置-->
<!--otherc3p0配置文件-->
<named-config name="otherc3p0">
<!-- 连接参数 -->
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/day25</property>
<property name="user">root</property>
<property name="password">root</property>
<!-- 连接池参数 -->
<property name="initialPoolSize">5</property>
<property name="maxPoolSize">8</property>
<property name="checkoutTimeout">1000</property>
</named-config>
</c3p0-config>
3.归还连接 connection .close();
druid
如何使用druid连接池技术获取连接
1.实现DataSource接口
DataSource ds= DruidDataSourceFactory.createDataSource(properties);
实现前提:读取配置文件,C3P0的配置文件是默认位置的默认文件,所以不用手动读取,会自动读取
//1.获取配置文件
InputStream resourceAsStream = DruidDemo.class.getClassLoader().getResourceAsStream("druid.properties");
//2.读取配置文件
//2.1 创建Properties类对象 一般来说java中读取配置文件都是用Properties对象
Properties properties = new Properties();
//2.2 读取配置文件
properties.load(resourceAsStream );
2.获取连接 ds.getConnection(); (事先配置好连接数据库的配置文件)
未使用jdbc连接池技术的获取连接
Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/db4","root","root");
使用jdbc连接池技术的获取连接
Connection connection = ds.getConnection();
druid连接池技术的配置文件
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/db4
username=root
password=root
#初始化连接数
initialSize=5
#最大连接数
maxActive=10
#最大等待时间
maxWait=3000
3.归还连接
conn.close();
三、为什么要使用jdbc连接池
原有的获取连接的缺点:
在使用开发基于数据库的web程序时,传统的模式基本是按以下步骤:
①在主程序(如servlet、beans)中建立数据库连接。
②进行sql操作
③断开数据库连接。
这种模式开发,存在的问题:
①普通的JDBC数据库连接使用 DriverManager 来获取,每次向数据库建立连接的时候都要将 Connection 加载到内存中,再验证用户名和密码(得花费0.05s~1s的时间)。需要数据库连接的时候,就向数据库要求一个,执行完成后再断开连接。这样的方式将会消耗大量的资源和时间。数据库的连接资源并没有得到很好的重复利用.若同时有几百人甚至几千人在线,频繁的进行数据库连接操作将占用很多的系统资源,严重的甚至会造成服务器的崩溃。
②对于每一次数据库连接,使用完后都得断开。否则,如果程序出现异常而未能关闭,将会导致数据库系统中的内存泄漏,最终将导致重启数据库。
③这种开发不能控制被创建的连接对象数,系统资源会被毫无顾及的分配出去,如连接过多,也可能导致内存泄漏,服务器崩溃。
使用jdbc连接的优点:
资源重用:
①由于数据库连接得以重用,避免了频繁创建,释放连接引起的大量性能开销。在减少系统消耗的基础上,另一方面也增加了系统运行环境的平稳性。
更快的系统反应速度:
数据库连接池在初始化过程中,往往已经创建了若干数据库连接置于连接池中备用。此时连接的初始化工作均已完成。对于业务请求处理而言,直接利用现有可用连接,避免了数据库连接初始化和释放过程的时间开销,从而减少了系统的响应时间
新的资源分配手段:
对于多应用共享同一数据库的系统而言,可在应用层通过数据库连接池的配置,实现某一应用最大可用数据库连接数的限制,避免某一应用独占所有的数据库资源
统一的连接管理,避免数据库连接泄露:
在较为完善的数据库连接池实现中,可根据预先的占用超时设定,强制回收被占用连接,从而避免了常规数据库连接操作中可能出现的资源泄露
## JDBCTemplete
一、什么是jdbctemplete
Spring框架对JDBC的简单封装。提供了一个JDBCTemplate对象简化JDBC的开发
二、如何使用JDBCTemplete
1.创建jdbctemplete对象
创建JdbcTemplate对象。依赖于数据源DataSource,也就是说必须使用连接池技术(druid/c3p0/......)抽取JDBCUtils工具类
JdbcTemplate template = new JdbcTemplate(ds);
2.调用jdbctemplete的方法实现对数据库的CRUD操作
1. update():执行DML语句。增、删、改语句
2.query...语句 执行DQL语句 查
queryForMap():查询结果将结果集封装为map集合,将列名作为key,将值作为value 将这条记录封装为一个map集合
* 注意:这个方法查询的结果集长度只能是1
queryForList():查询结果将结果集封装为list集合
* 注意:将每一条记录封装为一个Map集合,再将Map集合装载到List集合中
* query():查询结果,将结果封装为JavaBean对象
* query的参数:RowMapper
queryForObject:查询结果,将结果封装为对象
* 一般用于聚合函数的查询 结果只能为1
一般我们使用BeanPropertyRowMapper实现类。可以完成数据到JavaBean的自动封装
* new BeanPropertyRowMapper<类型>(类型.class)
1、使用BeanProperytRowMapper要求sql数据查询出来的列和实体属性需要一一对应。如果数据中列明和属性名不一致,在sql语句中需要用as重新取一个别名
2、使用JdbcTemplate对象不能获取关联对象
3.execute:可以执行所有SQL语句,一般用于执行DDL语句
三、为什么要使用
可以简化对数据库的操作,使用前要导入相应jar包
未使用jdbctemplete时进行查询操作
```java
1.获取连接
2.创建执行对象
3.定义sql语句给prepareStatememnt问号赋值
4.执行sql 如果时select语句还要封装结果集
5.关闭资源
try {
//获取连接
conn = DruidJDBCUtils.getConnection();
//定义sql语句
String s = "INSERT INTO score VALUES(?,?,?,?);";
//创建执行对象
ps = conn.prepareStatement(s);
//给问号赋值
ps.setInt(1,34);
ps.setInt(2,906);
ps.setString(3,"英语");
ps.setInt(4,85);
//执行sql语句
int i = ps.executeUpdate();
//获取结果
System.out.println(i);
} catch (Exception e) {
e.printStackTrace();
} finally {
//释放资源
DruidJDBCUtils.close(ps,conn);
}
使用jdbctemplete进行查询操作
不用自己手动获取连接和释放资源
1.创建jdbctemplete对象(要在工具类额外增加一个方法返回数据源)
2.定义sql语句
3.调用jdbctemplete对象的方法执行sql语句,并通过new BeanPropertyRowMapper自动将结果封装成对象,返回相应的结果集
//2.创建JDBCTemplate
JdbcTemplate jdbcTemplate = new JdbcTemplate(DruidJDBCUtils.getDataSource());
//3.调用JDBCTemplate对象的方法,完成数据库的操作;
String s ="INSERT INTO score VALUES(?,?,?,?);";
//JDBCTemplate对象的方法是一个可变参数的方法,有几个问好写几个参数,没有就不写
int count = jdbcTemplate.update(s, null, 910, "英语", 98);
代码
最原始的jdbc
JDBC对数据库数据进行增加操作(抛出异常)
package com.it.jdbc;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
/**
* JDBC:java 数据库连接 ,jdbc就是一个数据库驱动
*
*/
public class ConnectorDemo {
public static void main(String[] args) throws Exception{
//2. 注册驱动
/*
1.Class.forName("驱动类的全路径名称")
2.手动的调用
查看源码发现:在com.mysql.jdbc.Driver类中存在静态代码块
static {
try {
java.sql.DriverManager.registerDriver(new Driver());
} catch (SQLException E) {
throw new RuntimeException("Can't register driver!");
}
}DriverManager.registerDeiver(new Driver())
3.啥都不用写,自动注册驱动:
mysql驱动jar包5版本之后;
*/
//要使用JDBC接口,需要先将对应数据库的实现部分(驱动)加载进来。
//驱动类加载方式
Class.forName("com.mysql.jdbc.Driver");//这条语句的含义是:装载驱动类,驱动类通过static块实现在DriverManager中的“自动注册”。com.mysql.jdbc.Driver,driver类的全限定修饰符,创建Driver类的对象,静态代码块随着类的加载而加载,就完成了自动注册
//3. 获取数据库连接对象 Connection 具体要连接那个数据库
//Connection接口负责应用程序对数据库的连接,在加载驱动之后,使用url、username、password三个参数,创建到具体数据库的连接。
//当调用方法getConnection , DriverManager将尝试从初始化中加载的驱动程序中找到合适的驱动程序,并使用与当前应用程序相同的类加载器明确加载驱动程序。
Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/db4","root","root");//DriverManager类实现了连接接口
//4. 定义sql
//你要做什么操作
String s = "INSERT INTO score VALUES(NULL,907, '英语',75);";
//5. 获取执行sql语句的对象 Statement
//Statement接口用来处理发送到数据库的SQL语句对象,通过Connection对象创建。
Statement statement = connection.createStatement();
//6. 执行sql,接受返回结果
// 1. boolean execute(String sql) :可以执行任意的sql 了解
// 2. int executeUpdate(String sql) :执行DML(insert、update、delete)语句、DDL(create,alter、drop)语句
// * 返回值:影响的行数,可以通过这个影响的行数判断DML语句是否执行成功 返回值>0的则执行成功,反之,则失败。
// 3. ResultSet executeQuery(String sql) :执行DQL(select)语句
int i = statement.executeUpdate(s);
//7. 处理结果,
// 如果是dml操作就返回一个具体数值,代表该操作影响了几行表中数据
//如果是ddl操作就返回一个0,因为ddl是对表进行操作,对表中数据没有任何影响就返回0
//如果是dql操作就返回一个结果集,dql操作结果是一张表,我们用ResultSet来接收这张表
System.out.println(i);
//8. 释放
//调用接口是会占据资源的,我们要释放资源,才能保证内存不会溢出
//该方法显然是不合适的,如果在上面出了错,程序就结束了就不进行到释放资源,资源就一直占着内存
statement.close();
connection.close();
}
}
JDBC对数据库语句进行增加操作
package com.it.jdbc;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
public class ConnectorAll {
public static void main(String[] args) {
System.out.println(findAll());
}
public static List<ConnectorClass> findAll(){
Connection conn = null;
Statement statement = null;
ResultSet resultSet = null;
ConnectorClass cc;
List<ConnectorClass> connectorClasses = new ArrayList<>();
ArrayList<ConnectorClass> ac = new ArrayList<>();
try {
//加载驱动
Class.forName("com.mysql.jdbc.Driver");
//创建连接
conn = DriverManager.getConnection("jdbc:mysql:///db4","root","root");
//创建执行对象
statement = conn.createStatement();
//创建sql语句
String s = "SELECT * FROM student;";
//执行sql语句
resultSet = statement.executeQuery(s);
//接收结果,封装对象获得结果集
while (resultSet.next()){
int id = resultSet.getInt("id");
String name = resultSet.getString("name");
String sex = resultSet.getString("sex");
Date birth = resultSet.getDate("birth");
String department = resultSet.getString("department");
String address = resultSet.getString("address");
cc = new ConnectorClass();
cc.setId(id);
cc.setName(name);
cc.setSex(sex);
cc.setBirth(birth);
cc.setDepartment(department);
cc.setAddress(address);
connectorClasses.add(cc);
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}finally {
//关闭资源
if(resultSet!=null){
try {
resultSet.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(statement!=null){
try {
statement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(conn!=null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
return connectorClasses;
}
}
抽取jdbc工具类
JDBC工具类
package com.it.jdbc;
import java.io.IOException;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;
public class JDBCUtis {
private static String driver;
private static String url;
private static String user;
private static String password;
//创建静态代码块,随着类的加载而加载
static {
try {
//创建properties对象
Properties properties = new Properties();
//加载到内存
ClassLoader classLoader = JDBCUtiss.class.getClassLoader();
//获取配置文件对应的字节流
InputStream resourceAsStream = classLoader.getResourceAsStream("pro.properties");
//读取字节流
properties.load(resourceAsStream);
//获取对应的数据
driver = properties.getProperty("driver");
url = properties.getProperty("url");
user = properties.getProperty("user");
password = properties.getProperty("password");
//加载驱动
Class.forName(driver);
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
//连接数据库
public static Connection conn() throws SQLException {
return DriverManager.getConnection(url,user,password);
}
//关闭资源重载
public static void close(Connection conn , PreparedStatement stat){
close(conn,stat,null);
}
public static void close(Connection conn , PreparedStatement stat, ResultSet rs){
if(conn != null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(stat != null){
try {
stat.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(rs != null){
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
工具类的测试类
package com.it.jdbc;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
public class JDBCShiXian {
public static void main(String[] args) {
//初始化连接对象以及获取sql语句执行的对象
Connection conn = null;
Statement statement = null;
//加载驱动
// 静态代码块自动加载
try {
//获取连接
conn = JDBCUtiss.conn();
//获取执行语句的对象
statement = conn.createStatement();
//sql语句
String s = "INSERT INTO score VALUES(NULL,906, '计算机',90);";
//执行语句
int i = statement.executeUpdate(s);
//获得结果
System.out.println(i);
} catch (SQLException e) {
e.printStackTrace();
} finally {
//关闭资源
JDBCUtils.close(conn,statement);
}
}
}
自己更改后的JDBC工具类(不确定是否有问题)
package com.it.jdbc;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;
public class JDBCUtils {
private static String driver;
private static String url;
private static String user;
private static String password;
//加载驱动,常与配置文件搭配使用,增强程序的复用性
//仅需加载一次,使用静态代码块的方法加载驱动
static{
try {
//1.加载配置文件
//1.1创建properties对象用于加载配置文件
Properties properties = new Properties();
//1.2获取class目录下的配置文件,使用类加载器将类加载到内存中
ClassLoader classLoader = JDBCUtils.class.getClassLoader();
//1.3获取配置文件资源对应的字节流
InputStream resourceAsStream = classLoader.getResourceAsStream("pro.properties");
//1.4读取字节流
properties.load(resourceAsStream);
//获取配置文件中的数据
driver = properties.getProperty("driver");
url = properties.getProperty("url");
user = properties.getProperty("user");
password = properties.getProperty("password");
//注册驱动
Class.forName(driver);
//连接数据库 但测试类会使用该连接对象,这样写无法获取到连接对象
//Connection conn = DriverManager.getConnection(url, user, password);
//获取执行sql语句的对象 写到静态代码块里就无法获取到连接对象,因此不能写在里面 获取该对象仅需要一句,因此抽不抽取没有什么意义
//Statement state = conn.createStatement();
} catch (Exception e) {
e.printStackTrace();
}
}
//连接数据库 在获取连接时与此同时也获取了执行sql语句的对象 可以少写一句代码 连接对象仅在获取执行sql语句时使用,因此可以不返回连接对象
/*public static Connection conn() throws SQLException {*/
public static Statement conn() throws SQLException {
Connection conn = DriverManager.getConnection(url, user, password);
return conn.createStatement();
//return DriverManager.getConnection(url,user,password);
}
//关闭资源的重载方法,常在小的重载方法里调用大的重载方法,减少类似的程序
public static void close(Connection conn, Statement statement){
close(conn,statement,null);
}
public static void close(Connection conn, Statement statement, ResultSet resultSet){
if(conn!=null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(statement!=null){
try {
statement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(resultSet!=null){
try {
resultSet.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
测试类
package com.it.jdbc;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class JDBCText {
public static void main(String[] args) {
//连接数据库判断是否登录成功
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
//1.获取连接
try {
// conn = JDBCUtils.conn();
//2.定义sql
String sql = "SELECT stu_id FROM score;";
//3.获取执行sql的对象
//stmt = conn.createStatement();
stmt = JDBCUtils.conn();
//4.执行查询
rs = stmt.executeQuery(sql);
//5.判断
while (rs.next()){
String stu_id = rs.getString("stu_id");
System.out.println(stu_id);
}
} catch (SQLException e) {
e.printStackTrace();
}finally {
//JDBCUtils.close(rs,stmt,conn);
}
}
}
使用C3P0后的jdbc工具类抽取
需要导入c3p0-0.9.5.2.jar mchange-commons-java-0.2.12.jar两个包
C3P0配置文件要写在src目录下
名称必须为c3p0.properties/c3p0-config.xml
c3p0.properties
<c3p0-config>
<!-- 使用默认的配置读取连接池对象 -->
<default-config>
<!-- 连接参数 -->
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/db3</property>
<property name="user">root</property>
<property name="password">root</property>
<!-- 连接池参数 -->
<!--默认使用该配置文件-->
<!-- 初始化申请的连接数量-->
<property name="initialPoolSize">5</property>
<!--最大的连接数量-->
<property name="maxPoolSize">10</property>
<!--超时时间-->
<property name="checkoutTimeout">3000</property>
</default-config>
<!--c3p0允许同一配置文件下配置多个配置-->
<!--otherc3p0配置文件-->
<named-config name="otherc3p0">
<!-- 连接参数 -->
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/day25</property>
<property name="user">root</property>
<property name="password">root</property>
<!-- 连接池参数 -->
<property name="initialPoolSize">5</property>
<property name="maxPoolSize">8</property>
<property name="checkoutTimeout">1000</property>
</named-config>
</c3p0-config>
使用c3p0抽取jdbc工具类
package com.it.itcast.jdbc;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import javax.sql.DataSource;
import java.io.IOException;
import java.sql.*;
import java.util.Properties;
/**
* Druid连接池工具类
*
*/
public class DruidJDBCUtils {
//定义成员变量ds 创建DataSource接口(数据库连接池接口)
private static DataSource ds;
//静态代码块 获取连接池对象
static{
try {
//设置静态代码块将配置文件加载进来并读取配置文件
Properties pro = new Properties();
pro.load(DruidJDBCUtils.class.getClassLoader().getResourceAsStream("druid.properties"));
//获取连接池对象 使用druid实现DataSource接口
ds= DruidDataSourceFactory.createDataSource(pro);
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
//获取连接
public static Connection getConnection() throws Exception{
return ds.getConnection();
}
//释放资源及其重载方法
public static void close(ResultSet rs, PreparedStatement st , Connection conn) {
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (st != null) {
try {
st.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (conn != null) {
try {
conn.close();//归还连接
} catch (SQLException e) {
e.printStackTrace();
}
}
}
public static void close(PreparedStatement st , Connection conn){
close(null,st,conn);
}
public static void close(Connection conn){
close(null,null,conn);
}
/*//使用jdbctemplete时才会用到该方法
//获取连接池的方法
public static DataSource getDataSource(){
return ds;
}*/
}
测试类
package com.it.itcast.jdbc;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class C3P0JDBCDemo {
public static void main(String[] args) throws SQLException {
Connection conn = null;
PreparedStatement ps = null;
try {
//获取连接
conn = C3P0JDBCUtils.getConnection();
//定义sql语句
String s = "INSERT INTO score VALUES(?,?,?,?);";
//创建执行对象
ps = conn.prepareStatement(s);
//给问号赋值
ps.setInt(1,33);
ps.setInt(2,906);
ps.setString(3,"英语");
ps.setInt(4,85);
//执行sql语句
int i = ps.executeUpdate();
//获取结果
System.out.println(i);
} catch (Exception e) {
e.printStackTrace();
} finally {
//释放资源
C3P0JDBCUtils.close(ps,conn);
}
}
}
使用Druid连接池技术抽取工具类
导入druid-1.0.9.jar包
druid配置文件必须是properties文件
druid.properties
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/db4
username=root
password=root
#初始化连接数
initialSize=5
#最大连接数
maxActive=10
#最大等待时间
maxWait=3000
抽取工具类
package com.it.itcast.jdbc;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
/**
* Druid连接池工具类
*
*/
public class DruidJDBCUtils {
//定义成员变量ds 创建DataSource接口(数据库连接池接口)
private static DataSource ds= new ComboPooledDataSource();
//获取连接
public static Connection getConnection() throws Exception{
return ds.getConnection();
}
//释放资源及其重载方法
public static void close(ResultSet rs, PreparedStatement st , Connection conn) {
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (st != null) {
try {
st.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (conn != null) {
try {
conn.close();//归还连接
} catch (SQLException e) {
e.printStackTrace();
}
}
}
public static void close(PreparedStatement st , Connection conn){
close(null,st,conn);
}
public static void close(Connection conn){
close(null,null,conn);
}
/*//使用jdbctemplete时才会用到该方法
//获取连接池的方法
public static DataSource getDataSource(){
return ds;
}*/
}
测试类
package com.it.itcast.jdbc;
import java.sql.Connection;
import java.sql.PreparedStatement;
public class DruidJDBCDemo {
public static void main(String[] args) {
Connection conn = null;
PreparedStatement ps = null;
try {
//获取连接
conn = DruidJDBCUtils.getConnection();
//定义sql语句
String s = "INSERT INTO score VALUES(?,?,?,?);";
//创建执行对象
ps = conn.prepareStatement(s);
//给问号赋值
ps.setInt(1,34);
ps.setInt(2,906);
ps.setString(3,"英语");
ps.setInt(4,85);
//执行sql语句
int i = ps.executeUpdate();
//获取结果
System.out.println(i);
} catch (Exception e) {
e.printStackTrace();
} finally {
//释放资源
DruidJDBCUtils.close(ps,conn);
}
}
}
使用JdbcTemplate对数据库进行操作
jdbc工具类,使用druid连接池技术
package cn.itcast.travel.util;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import javax.sql.DataSource;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
/*
1. 声明静态数据源成员变量
2. 创建连接池对象
3. 定义公有的得到数据源的方法
//4. 定义得到连接对象的方法
//5. 定义关闭资源的方法
*/
public class JDBCUtils {
// 1. 声明静态数据源成员变量 创建数据库连接池DataSource接口
private static DataSource ds;
// 2. 创建连接池对象
static {
// 加载配置文件中的数据
InputStream is = JDBCUtils.class.getClassLoader().getResourceAsStream("druid.properties");
Properties pp = new Properties();
try {
pp.load(is);
// 创建连接池,使用配置文件中的参数 使用druid连接池实现DataSource接口
ds = DruidDataSourceFactory.createDataSource(pp);
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
// 3. 定义公有的得到数据源的方法
public static DataSource getDataSource() {
return ds;
}
//使用jdbctemplete就可以不定义这几个方法,但为了当不使用jdbctemplete时,仍能正常使用工具类建议加上(复用性更高)
/*// 4. 定义得到连接对象的方法
public static Connection getConnection() throws SQLException {
return ds.getConnection();
}
// 5.定义关闭资源的方法
public static void close(Connection conn, Statement stmt, ResultSet rs) {
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {}
}
if (stmt != null) {
try {
stmt.close();
} catch (SQLException e) {}
}
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {}
}
}
// 6.重载关闭方法
public static void close(Connection conn, Statement stmt) {
close(conn, stmt, null);
}*/
}
jdbc开发类
package com.it.itcast.jdbc;
import org.springframework.jdbc.core.JdbcTemplate;
/**
* 是对原生的jdbc操作的封装;可以简化程序员对数据库的操作
* 1.导包 依赖于导入了驱动以及连接池jar包
* 2.创建JDBCTemplate
* 3.调用JDBCTemplate对象的方法,完成数据库的操作;
* */
public class JdbcTemplateDemo01 {
public static void main(String[] args) {
//2.创建JDBCTemplate
JdbcTemplate jdbcTemplate = new JdbcTemplate(DruidJDBCUtils.getDataSource());
//3.调用JDBCTemplate对象的方法,完成数据库的操作;
String s ="INSERT INTO score VALUES(?,?,?,?);";
//JDBCTemplate对象的方法是一个可变参数的方法,有几个问好写几个参数,没有就不写
int count = jdbcTemplate.update(s, null, 910, "英语", 98);
System.out.println(count);
}
}