JDBC工具类
属性
private static String user;
private static String password;
private static String url;
private static String driver;
初始化
//在static代码块中初始化
static {
try {
Properties properties = new Properties();
properties.load(new FileInputStream("D://JavaProject//Hello//src//mysql.properties"));
user = properties.getProperty("user");
password = properties.getProperty("password");
url = properties.getProperty("url");
driver = properties.getProperty("driver");
} catch (IOException e) {
//在实际开发中,我们经常把编译异常转换成运行异常
//这样调用者可以选择捕获该异常,也可以选择默认处理该异常
throw new RuntimeException(e);
}
}
获取Connection方法
//连接数据库,返回Connection
public static Connection getConnection(){
try {
return DriverManager.getConnection(url,user,password);
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
关闭资源方法
//关闭相关资源
/*
1.ResultSet结果集
2.Statement 或者 PreparedStatement
3.Connection
4.如果需要关闭资源,就传入对象,否则传入null
*/
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);
}
}
工具类的使用
DML语句:
public class JDBCUtilas_DML {
public static void main(String[] args) {
//1.得到连接
Connection connection = null;
//2.组织一个sql
String sql = "update t01 set age = ? where name = ?";
//3.创建PreparedStatement对象
PreparedStatement preparedStatement = null;
try {
connection = JDBCUtils.getConnection();
preparedStatement = connection.prepareStatement(sql);
//给占位符赋值
preparedStatement.setInt(1,18);
preparedStatement.setString(2,"张三");
//把"张三"修改为18岁,执行
preparedStatement.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
} finally {
JDBCUtils.close(null,preparedStatement,connection);
}
}
}
Select语句
public static void main(String[] args) {
//1.得到连接
Connection connection = null;
//2.组织一个sql
String sql = "select * from t01";
//3.创建PreparedStatement对象
PreparedStatement preparedStatement = null;
//4.创建ResultSet对象
ResultSet resultSet = null;
try {
connection = JDBCUtils.getConnection();
preparedStatement = connection.prepareStatement(sql);
resultSet = preparedStatement.executeQuery();
while(resultSet.next()){ //while循环读取
String name = resultSet.getString("name");
int age = resultSet.getInt("age");
System.out.println(name + "\t" + age);
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
JDBCUtils.close(resultSet,preparedStatement,connection);
}
}
事务
setAutoCommit相当于开启一个事务,rollback默认返回开启事务的地方。
批处理
public void batch() throws Exception{
Connection connection = JDBCUtils.getConnection(); //获取链接
String sql = "insert into t01 values(?,?)"; //sql语句
PreparedStatement preparedStatement = connection.prepareStatement(sql);
for(int i = 0;i<5000;i++){
preparedStatement.setString(1,"jack"+i);
preparedStatement.setInt(2,18+i);
//将sql语句加入到批处理包中
preparedStatement.addBatch();
//当有1000条记录时,批量执行
if((i+1)%1000==0){
preparedStatement.executeBatch(); //执行
//清空
preparedStatement.clearBatch();
}
}
JDBCUtils.close(null,preparedStatement,connection);
}
如果想成功使用批处理,url需要加上?后面的语句:
url=jdbc:mysql://localhost:3306/shang_02?rewriteBatchedStatements=true
1. 底层创建了 ArrayList,名字为elementData,是Object数组,存放我们预处理的sql语句。
2. 当elementData满后,就按照1.5倍扩容。
3. 批量处理会减少我们发送sql语句的网络开销,而且减少编译次数,因此效率提高。
数据库连接池
传统获取Connection问题分析
数据库连接池介绍
数据库连接池种类
主要了解C3P0以及Druid。
C3P0
前期准备
下载参考:C3P0jar包下载方法_小猪的日常Java-CSDN博客_c3p0jar包下载
类似connector,我们需要把 c3p0-0.9.5.5.jar(可以变化) 加入到项目中(add to library),如果最后连接失败,一直提示 java.lang.NoClassDefFoundError: com/mchange/v2/ser/Indirector
解决方法:把 mchange-commons-java-0.2.19.jar 也导入项目中
另外还需要在src目录下导入 c3p0-config.xml,注意这个文件是自己写的,详细可以看这个博客
https://blog.csdn.net/caychen/article/details/79625411
最后差不多是这样,jar和xml是必须导入的
实例代码
第一种方式:不使用 c3p0-config.xml (不推荐,代码太多了)
public static void main(String[] args) throws Exception{
//1.创建一个数据源对象
ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource();
//2.通过配置文件properties获取相关连接的信息
Properties properties = new Properties();
properties.load(new FileInputStream("D://JavaProject//Hello//src//mysql.properties"));
//3.读取相关属性值
String user = properties.getProperty("user");
String password = properties.getProperty("password");
String url = properties.getProperty("url");
String driver = properties.getProperty("driver");
//4.给数据源 comboPooledDataSource 设置相关的参数
comboPooledDataSource.setDriverClass(driver);
comboPooledDataSource.setJdbcUrl(url);
comboPooledDataSource.setUser(user);
comboPooledDataSource.setPassword(password);
//设置初始化连接数
comboPooledDataSource.setInitialPoolSize(10);
//设置最大连接数
comboPooledDataSource.setMaxPoolSize(50);
//5.连接
Connection connection = comboPooledDataSource.getConnection();
System.out.println("连接OK");
}
第二种方式:使用 c3p0.config.xml ,该文件指定了连接数据库和连接池的相关参数
注意需要写上 <named-config name="SHANG"> 用来指定连接池的名字,才能用。
public static void main(String[] args) throws Exception{
ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource("SHANG");
Connection connection = comboPooledDataSource.getConnection();
System.out.println("连接OK");
}
Druid
前期准备
下载druid.jar和druid.properties,加入到项目中。
druid.jar加入到libs文件夹,然后add to library,properties文件直接放在src根目录下。 至于怎么设置上网看就行了。
连接代码
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("D:\\JavaProject\\Hello\\src\\druid.properties"));
//4.创建一个指定参数的数据库连接池
DataSource dataSource =
DruidDataSourceFactory.createDataSource(properties);
//5.连接
Connection connection = dataSource.getConnection();
注:不管是哪个properties,里面的 driverClassName 必须写成 com.mysql.cj.jdbc.Driver (老版本是没有 cj 的)
基于Druid连接池的工具类
public class JDBCUtilsByDruid{
private static DataSource ds;
//在静态代码块完成ds初始化
static{
Properties properties = new Properties();
try {
properties.load(new FileInputStream("D:\\JavaProject\\Hello\\src\\druid.properties"));
ds = DruidDataSourceFactory.createDataSource(properties);
} catch (Exception e) {
e.printStackTrace();
}
}
//getConnection方法
public static Connection getConnection() throws SQLException {
return ds.getConnection();
}
//关闭连接方法 (注意在连接池技术中,close不是断掉连接,而是把Connection对象放回连接池)
public static void close(ResultSet set, Statement statement,Connection connection) throws SQLException {
if(set!=null){
set.close();
}
if(statement!=null){
statement.close();
}
if(connection!=null){
connection.close();
}
}
}
Apache-DBUtils
由于关闭connection后,resultSet结果集就无法使用了,因此不利于数据的管理。
但如果把表中的内容(一行)看作对象,把行放入一个ArrayList,就不用管resultSet能不能使用了
Select使用
DBUtils相关的jar下载地址:
DbUtils jar包下载_小猪的日常Java-CSDN博客_dbutils jar包
public class Person {
private String name;
private int age;
} //内容与表保持一致
public static void main(String[] args) throws Exception{
//1.得到连接
Connection connection = JDBCUtilsByDruid.getConnection();
//2.使用DBUtils类和接口,需要引入DBUtils相关的jar
//3.创建 QueryRunner
QueryRunner queryRunner = new QueryRunner();
String sql = "select * from t01 where name = ?";
//用相关方法返回ArrayList结果集
List<Person> list =
queryRunner.query(connection,sql,new BeanListHandler<>(Person.class),"张三");
for (Person person : list) {
System.out.println(person);
}
JDBCUtilsByDruid.close(null,null,connection);
}
注:1. query方法就是执行sql语句,得到resultSet,然后封装到 ArrayList集合中。
2. connection 连接,sql 执行的sql语句,new BeanListHandler<>(Person.class):底层使用反射机制去获取Person类的属性,将resultSet封装到ArrayList中(用于多行多列输出)。
3. 调用完方法后面的就是写入?的参数。
如果返回的是单个Person对象(不用使用集合)
Person person =
queryRunner.query(connection,sql,new BeanHandler<>(Person.class),"...");
这时使用的是 BeanHandler方法。
如果返回的是单行单列(返回一个Object)
Object obj = queryRunner.query(connection,sql,new ScalarHandler<>(),"...");
这时使用的是 ScalarHandler方法。
DML使用
public static void main(String[] args) throws Exception {
//1.得到连接
Connection connection = JDBCUtilsByDruid.getConnection();
//2.创建QueryRunner
QueryRunner queryRunner = new QueryRunner();
//4.组织sql
String sql = "update t01 set name = ? where age = ?";
//String sql = "insert into t01 values(?,?)";
//String sql = "delect from t01 where name = ?";
int affectRows = queryRunner.update(connection, sql, "王五", 22);
JDBCUtilsByDruid.close(null, null, connection);
}
注:执行dml操作的是 queryRunner.update(),返回的值是受影响的行数。