MySQL数据库学习3

MySQL 补充


  • 同时成功或同时失败

  • 将一组 sql 放在同一个批次中

  • MySQL 是默认开启事务自动提交的,可以通过以下代码关闭

    SET autocommit=0       -- 关闭
    SET autocommit=1       -- 开启(默认的)
    

事务原则(ACID)


原子性(Atomicity)

  • 一起成功,或一起失败,不能只发生其中一个动作

一致性(Consistency)

  • 事务操作前和操作后的状态一致

持久性(Durability)

  • 表示事务结束后的数据不随外界原因导致数据丢失

    事务没有提交,恢复到原状

    事务已经提交,持久化到数据库

    事务一旦提交就不可逆

隔离性(Isolation)

  • 针对多个用户同时操作,为每个用户开启事务,排除其他事务对本次事务的影响
事务的隔离级别
脏读
  • 一个事务读取到另一个事务未提交的数据
不可重复读
  • 一个事务在读取表中某一行的数据时,多次读取结果不同
幻读(虚读)
  • 一个事务内读取到了别的事务插入的数据,导致前后读取不一致

手动处理事务


  • 事务开启:START TRANSACTION
  • 提交(成功):持久化:COMMIT
  • 回滚(失败):回到原来的样子:ROLLBACK
  • 创建保存点:SAVEPOINT 保存点名
  • 删除保存点:RELEASE SAVEPOINT 保存点名

手动处理事务的全过程

在这里插入图片描述

CREATE DATABASE `yh` CHARACTER SET utf8mb4 COLLATE utf8mb4_bin
CREATE TABLE `account`(
`id` INT NOT NULL AUTO_INCREMENT,
`name` VARCHAR(50) NOT NULL,
`money` DECIMAL(7,2) NOT NULL,
PRIMARY KEY (`id`)
)ENGINE=INNODB DEFAULT CHARSET=utf8mb4
INSERT INTO `account`(`name`,`money`) VALUES('小明',1200.00),('小白',20000.00)
SET autocommit=0       -- 关闭自动提交
START TRANSACTION       -- 开启一个事务
UPDATE `account` SET money=money+2000 WHERE `name`='小明'
UPDATE `account` SET money=money-2000 WHERE `name`='小白'
COMMIT       -- 提交
ROLLBACK       -- 回滚
SET autocommit=1       -- 开启自动提交

索引


  • 是帮助 MySQL 高效获取数据的数据结构

索引分类

主键索引
  • PRIMARY KEY
  • 唯一标识,主键不可重复,只能有一列作为主键
唯一索引
  • UNIQUE KEY
  • 标记的列具有唯一性,可有多个
常规索引
  • KEY/INDEX
  • 默认的
全文索引
  • FULLTEXT
  • 快速定位数据

相关操作

显示所有的索引信息
SHOW INDEX FROM `表名`
SHOW INDEX FROM `student`
增加一个索引
ALTER TABLE `表名` ADD 索引 INDEX `索引名`(`字段名`)
CREATE 索引 索引名 ON `表名`(`字段名`)
ALTER TABLE `student` ADD FULLTEXT INDEX `studentname`(`studentname`)
CREATE INDEX id_user_name ON `user`(`name`)
分析 sql 语句执行的状况
EXPLAIN sql语句
EXPLAIN SELECT * FROM `user` WHERE `name`='用户99999号'

测试索引

CREATE TABLE `user`(
`id` BIGINT NOT NULL AUTO_INCREMENT COMMENT 'id',
`name` VARCHAR(50) NOT NULL DEFAULT '' COMMENT '用户名',
`email` VARCHAR(20) NOT NULL COMMENT '邮箱',
`phone` INT NOT NULL COMMENT '电话',
`sex` INT NOT NULL DEFAULT '0' COMMENT '0:男,1:女',
`password` VARCHAR(50) NOT NULL COMMENT '电话',
`age` INT NOT NULL COMMENT '年龄',
`create_time` DATETIME DEFAULT CURRENT_TIMESTAMP,
`update_time` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY(`id`)  
)ENGINE=INNODB DEFAULT CHARSET=utf8mb4 COMMENT='用户信息表'
-- 创建一个函数给表中添加数据
DELIMITER $$
CREATE FUNCTION xw()
RETURNS INT
DETERMINISTIC
BEGIN
DECLARE num INT DEFAULT 1000000;
DECLARE i INT DEFAULT 0;
WHILE i<num DO
INSERT INTO `user`(`name`,`email`,`phone`,`sex`,`password`,`age`)VALUES(CONCAT('用户',i,'号'),(CONCAT(FLOOR(RAND()*1000000000),'@qq.com')),(CONCAT('18',FLOOR(RAND()*100000000))),FLOOR(RAND()*2),UUID(),FLOOR(RAND()*100));
SET i=i+1;
END WHILE;
RETURN i;
END;
SELECT xw();       -- 调用函数
SELECT * FROM `user` WHERE `name`='用户99999号'
EXPLAIN SELECT * FROM `user` WHERE `name`='用户99999号'       -- 不加索引查询
CREATE INDEX id_user_name ON `user`(`name`)
SELECT * FROM `user` WHERE `name`='用户99999号'
EXPLAIN SELECT * FROM `user` WHERE `name`='用户99999号'       -- 加索引查询

不加索引查询的结果:

在这里插入图片描述

加索引查询的结果:

在这里插入图片描述

索引在小数据量的时候用处不大,但在大数据量的时候,效果十分明显

索引原则

  • 索引不是越多越好
  • 不要对经常变动的数据加索引
  • 小数据量的表不需要加索引
  • 索引一般加在常用来查询的字段上

权限管理和备份


  • 用户(权限)管理本质:对用户表 mysql.user 进行增删改查操作

备份

  • 保证重要的数据不丢失
  • 可以数据转移
备份方式
  • 直接拷贝物理文件

  • 在可视化工具中手动拷贝

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 使用命令行导出

    导出多个表时中间用逗号隔开,也可以直接导出数据库

    mysqldump -h主机 -u用户名 -p密码 库名 表名 >物理磁盘位置/文件名
    mysqldump -hlocalhost -uroot -p123456 school student >D:/1.sql
    

规范数据库设计


数据库设计步骤

  1. 收集信息,分析需求
    • 用户表(用户登录注册,用户个人信息)
    • 分类表
    • 内容表
    • 友链表
    • 自定义表(系统信息,某些关键字或一些主字段)
  2. 标识实体(把需求落实到每一个字段)
  3. 标识实体之间的关系

三大范式

  • 为了避免信息重复,更新异常,插入异常,删除异常,所以需要数据规范化
  • 关联查询的表不得超过三张表
  • 考虑商业化的需求和目标时,数据库的性能更加重要
  • 在规范性能问题时,需要适当考虑一下规范性
第一范式(1NF)
  • 原子性,保证每列不可再分
第二范式(2NF)
  • 前提:满足第一范式
  • 每张表只描述一件事情
  • 完全依赖(非部分依赖)
第三范式(3NF)
  • 前提:满足第一范式和第二范式
  • 确保数据表中每一列的数据都和主键直接相关
  • 直接依赖(非间接依赖)

JDBC


  • 为数据库的统一操作而提出的 java 操作数据库的规范

JDBC 示例

  • 创建数据库
CREATE DATABASE `sjdbc` CHARSET utf8mb4 COLLATE utf8mb4_bin
USE `sjdbc`
CREATE TABLE `users`(
`id` INT NOT NULL,
`name` VARCHAR(50) NOT NULL,
`password` VARCHAR(20) NOT NULL,
`email` VARCHAR(20) NOT NULL,
PRIMARY KEY (`id`)
)ENGINE=INNODB CHARSET=utf8mb4
ALTER TABLE `users` ADD `birthday` DATE
INSERT INTO `users`(`id`,`name`,`password`,`email`,`birthday`)
VALUES(1,'小王','123456','1442395@qq.com','1998-2-10'),
(2,'小李','123456','16635984@qq.com','2000-8-10'),
(3,'小高','123456','25289895@qq.com','1999-10-25')
  • 连接数据库
    1. 加载驱动
    2. 连接数据库
    3. 获取执行 sql 的对象
    4. 获得返回的结果集
    5. 释放连接
package com.xh.text01;

import java.sql.*;

public class Text01 {
    public static void main(String[] args) throws ClassNotFoundException, SQLException {
        //1.加载驱动
        Class.forName("com.mysql.cj.jdbc.Driver");       //加载驱动,固定写法
        //2.用户信息和url
        //固定useUnicode=true&characterEncoding=utf8&useSSL=true
        String url="jdbc:mysql://localhost:3306/sjdbc?useUnicode=true&characterEncoding=utf8&useSSL=true";
        String username="root";
        String password="123456";
        //3.连接成功,数据库对象:Connection
        Connection connection = DriverManager.getConnection(url, username, password);
        //4.连接执行sql的对象:Statement
        Statement statement=connection.createStatement();
        //5.执行sql语句
        String sql="select * from `users`";
        ResultSet resultSet = statement.executeQuery(sql);       //返回的结果集,结果集中封装了我们查询出的全部结果
        //打印数据
        while(resultSet.next()){
            System.out.println("id="+resultSet.getObject("id"));
            System.out.println("name="+resultSet.getObject("name"));
            System.out.println("password="+resultSet.getObject("password"));
            System.out.println("email="+resultSet.getObject("email"));
            System.out.println("birthday="+resultSet.getObject("birthday"));
        }
        //6.释放连接
        resultSet.close();
        statement.close();
        connection.close();       //非常好资源,用完关掉
    }
}

DriverManager

package com.mysql.cj.jdbc;

import java.sql.DriverManager;
import java.sql.SQLException;

public class Driver extends NonRegisteringDriver implements java.sql.Driver {
    public Driver() throws SQLException {
    }

    static {
        try {
            DriverManager.registerDriver(new Driver());       //调用时内部已经执行了一次
        } catch (SQLException var1) {
            throw new RuntimeException("Can't register driver!");
        }
    }
}
DriverManager.registerDriver(new com.mysql.cj.jdbc.Driver());       //原来写法,重复注册了,一般用下面的方法
Class.forName("com.mysql.cj.jdbc.Driver");       //加载驱动,固定写法

JDBC 4.0 之后,每个驱动 jar 包中,在 META-INF/services 目录下提供了一个名为 java.sql.Driver 的文件;不需要再显示的去加载驱动,程序会自动扫描 jar 包下是否有这个文件,有的话会自动连接,但是为了考虑兼容性,一般显示加载

Connection connection = DriverManager.getConnection(url, username, password);
//connection代表数据库,可以进行数据库的事物操作
connection.commit();       //事物提交
connection.rollback();       //事物回滚
connection.setAutoCommit();       //事物自动提交

url

//mysql默认端口号3306
String url="协议://主机:端口号/数据库名?参数1&参数2&参数三";
//oralce默认端口号1521
String url="jdbc:mysql:thin:@localhost:1521:sid
String url="jdbc:mysql://localhost:3306/sjdbc?useUnicode=true&characterEncoding=utf8&useSSL=true";

Statement

  • 执行 sql 的对象
  • 用于向数据库发送 sql 语句,完成对数据库的增删改查
statement.executeQuery();       //查询操作,返回ResultSet
statement.execute();       //可以执行任何sql语句
statement.executeUpdate();       //更新,插入,删除都用这个方法
executeUpdate()方法
  • 完成数据库的增加,删除,修改操作
  • 返回的是一个整数(增删改语句导致数据库数据变化的行数)
//增加操作
Statement statement=connection.createStatement();
String sql="insert into `表名`(`字段名1`,...) VALUES('数据1',...)";
int num=statement.executeUpdate(sql);
if(num>0){
    System.out.println("数据插入成功");
}
//删除操作
Statement statement=connection.createStatement();
String sql="delect from `表名` where 条件";
int num=statement.executeUpdate(sql);
if(num>0){
    System.out.println("数据删除成功");
}
//修改操作
Statement statement=connection.createStatement();
String sql="update `表名` set `字段名`='数据' where 条件";
int num=statement.executeUpdate(sql);
if(num>0){
    System.out.println("数据修改成功");
}
//增加操作
Statement statement=connection.createStatement();
String sql="insert into `users` VALUES(1,'小王','123456','1442395@qq.com','1998-2-10')";
int num=statement.executeUpdate(sql);
if(num>0){
    System.out.println("数据插入成功");
}
//删除操作
Statement statement=connection.createStatement();
String sql="delect from `users` where `id`=1";
int num=statement.executeUpdate(sql);
if(num>0){
    System.out.println("数据删除成功");
}
//修改操作
Statement statement=connection.createStatement();
String sql="update `users` set `name`='小为' where `name`='小王'";
int num=statement.executeUpdate(sql);
if(num>0){
    System.out.println("数据修改成功");
}
executeQuery()方法;
  • 完成数据库的查询操作
Statement statement=connection.createStatement();
String sql="select * from `表名` where 条件;
ResultSet resultset=statement.executeUpdate(sql);
if(resultset.next()){
    //根据获取的的列的数据类型,分别调用resultset的相应方法以实现查找
}
Statement statement=connection.createStatement();
String sql="select * from `users` where `id`=1";
ResultSet resultset=statement.executeUpdate(sql);
if(resultset.next()){
    //根据获取的的列的数据类型,分别调用resultset的相应方法以实现查找
}

PreparedStatement

  • 执行 sql 的对象
  • 用于向数据库发送 sql 语句,完成对数据库的增删改查
  • 可以防止 sql 注入,本质(把传递进来的参数当做字符,假设其中存在转义字符(比如 ’ )就直接忽略)
  • PreparedStatement 是 Statement 的子类,相对于 Statement ,效率更高,且可以防止 sql 注入,一般使用 PreparedStatement
executeUpdate()方法
  • 完成数据库的增加,删除,修改操作
  • 返回的是一个整数(增删改语句导致数据库数据变化的行数)
//增加操作
String sql="insert into users values(?,?,?,?,?)";       //使用占位符代替参数
statement=connection.prepareStatement(sql);       //预编译sql,先写sql,但不执行
//手动给参数赋值
statement.setInt(1,6);
statement.setString(2,"xyg");
statement.setString(3,"123456");
statement.setString(4,"16625487@qq.com");
statement.setDate(5,new java.sql.Date(new Date().getTime()));       //插入当前时间,new Date().getTime()获得时间戳
int i=statement.executeUpdate();       //执行
if (i>0){
    System.out.println("插入成功");
}
//删除操作
String sql="delete from users where id=?";      
statement=connection.prepareStatement(sql);      
statement.setInt(1,6);
int i=statement.executeUpdate();
if (i>0){
    System.out.println("删除成功");
}
//修改操作
String sql="update users set name=? where id=?";
statement=connection.prepareStatement(sql);     
statement.setString(1,"994");
statement.setInt(2,5);
int i=statement.executeUpdate();
if (i>0){
    System.out.println("修改成功");
}
executeQuery()方法;
  • 完成数据库的查询操作
String sql="select * from users where id=?";       
statement=connection.prepareStatement(sql);       
statement.setInt(1,1);
resultSet=statement.executeQuery();
while (resultSet.next()){
    System.out.println(resultSet.getString("name"));
}

ResultSet

  • 查询的结果集,封装了所有的查询结果

获得指定的数据类型

resultSet.getObject();       //不知道具体类型就用Object,直到就用具体类型

遍历

resultSet.beforeFirst();       //移动到最前面
resultSet.afterLast();       //移动到最后面
resultSet.next();       //移动到下一个
resultSet.previous();       //移动到前一行
resultSet.absolute();       //移动到指定行

sql注入

sql 注入即是指 web 应用程序对用户输入数据的合法性没有判断或过滤不严,攻击者可以在 web 应用程序中事先定义好的查询语句的结尾上添加额外的,在管理员不知情的情况下实现非法操作,以此来实现欺骗执行非授权的任意查询,从而进一步得到相应的数据信息。

package com.xh.text02;

import com.xh.text02.utils.JdbcUtils;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class Text02 {
    public static void main(String[] args) {
        login("'or'1=1","'or'1=1");       //sql注入,通过拼接sql
    }
    public static void login(String username,String password){
        Connection connection=null;
        Statement statement=null;
        ResultSet resultSet=null;
        try {
            connection = JdbcUtils.getConnection();
            statement=connection.createStatement();
            String sql="select * from users where name='"+username+"'and password='"+password+"'";
            resultSet=statement.executeQuery(sql);
            while (resultSet.next()){
                System.out.println(resultSet.getString("name"));
                System.out.println(resultSet.getString("password"));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            JdbcUtils.release(connection,statement,resultSet);
        }
    }
}

代码优化

提取工具类
配置文件
driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/sjdbc?useUnicode=true&characterEncoding=utf8&useSSL=true
username=root
password=123456
工具类
package com.xh.text02.utils;

import java.io.InputStream;
import java.sql.*;
import java.util.Properties;

public class JdbcUtils {
    private static String driver=null;
    private static String url=null;
    private static String username=null;
    private static String password=null;

    static {
        try{
            //通过类获取反射对象,然后获取反射对象的类加载器,调用类加载器的获取资源的方法,获得配置文件
            InputStream ras = JdbcUtils.class.getClassLoader().getResourceAsStream("db.properties");
            Properties properties = new Properties();
            properties.load(ras);
            driver = properties.getProperty("driver");
            url=properties.getProperty("url");
            username=properties.getProperty("username");
            password=properties.getProperty("password");
            Class.forName(driver);       //加载驱动
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    //获取连接
    public static Connection getConnection() throws SQLException {
        return DriverManager.getConnection(url, username, password);
    }
    //释放连接资源
    public static void release(Connection connection, Statement statement, ResultSet resultSet){
        if (resultSet!=null){
            try {
                resultSet.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if(statement!=null){
            try {
                statement.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (connection!=null){
            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}
实现类
增删改
//增加操作
package com.xh.text02;

import com.xh.text02.utils.JdbcUtils;
import java.sql.*;
import java.util.Date;

public class Text01 {
    public static void main(String[] args) {
        Connection connection=null;
        PreparedStatement statement=null;
        ResultSet resultSet=null;
        try {
            connection = JdbcUtils.getConnection();       //获取数据库连接
            String sql="insert into users values(?,?,?,?,?)";       //使用占位符代替参数
            statement=connection.prepareStatement(sql);       //预编译sql,先写sql,但不执行
            //手动给参数赋值
            statement.setInt(1,6);
            statement.setString(2,"xyg");
            statement.setString(3,"123456");
            statement.setString(4,"16625487@qq.com");
            statement.setDate(5,new java.sql.Date(new Date().getTime()));       //插入当前时间,new Date().getTime()获得时间戳
            //执行
            int i=statement.executeUpdate();
            if (i>0){
                System.out.println("插入成功");
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            JdbcUtils.release(connection,statement,resultSet);
        }
    }
}
//删除操作
package com.xh.text02;

import com.xh.text02.utils.JdbcUtils;
import java.sql.*;
import java.util.Date;

public class Text01 {
    public static void main(String[] args) {
        Connection connection=null;
        PreparedStatement statement=null;
        ResultSet resultSet=null;
        try {
            connection = JdbcUtils.getConnection();       //获取数据库连接
            String sql="delete from users where id=?";       //使用占位符代替参数
            statement=connection.prepareStatement(sql);       //预编译sql,先写sql,但不执行
            //手动给参数赋值
            statement.setInt(1,6);
            //执行
            int i=statement.executeUpdate();
            if (i>0){
                System.out.println("删除成功");
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            JdbcUtils.release(connection,statement,resultSet);
        }
    }
}
//修改操作
package com.xh.text02;

import com.xh.text02.utils.JdbcUtils;
import java.sql.*;
import java.util.Date;

public class Text01 {
    public static void main(String[] args) {
        Connection connection=null;
        PreparedStatement statement=null;
        ResultSet resultSet=null;
        try {
            connection = JdbcUtils.getConnection();       //获取数据库连接
            String sql="update users set name=? where id=?";       //使用占位符代替参数
            statement=connection.prepareStatement(sql);       //预编译sql,先写sql,但不执行
            //手动给参数赋值
            statement.setString(1,"994");
            statement.setInt(2,5);
            //执行
            int i=statement.executeUpdate();
            if (i>0){
                System.out.println("修改成功");
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            JdbcUtils.release(connection,statement,resultSet);
        }
    }
}
package com.xh.text02;

import com.xh.text02.utils.JdbcUtils;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class Text01 {
    public static void main(String[] args) {
        Connection connection=null;
        PreparedStatement statement=null;
        ResultSet resultSet=null;
        try {
            connection = JdbcUtils.getConnection();       //获取数据库连接
            String sql="select * from users where id=?";       
            statement=connection.prepareStatement(sql);       
            statement.setInt(1,1);
            resultSet=statement.executeQuery();
            while (resultSet.next()){
                System.out.println(resultSet.getString("name"));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            JdbcUtils.release(connection,statement,resultSet);
        }
    }
}

事务

package com.xh.text02;

import com.xh.text02.utils.JdbcUtils;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class Text03 {
    public static void main(String[] args) {
        Connection connection=null;
        PreparedStatement statement=null;
        try {
            connection=JdbcUtils.getConnection();
            connection.setAutoCommit(false);       //关闭数据库自动提交,会自动开启事务
            String sql1="update t1 set money=money-100 where name=?";
            statement=connection.prepareStatement(sql1);
            statement.setString(1,"A");
            statement.executeUpdate();
            String sql2="update t1 set money=money+100 where name=?";
            statement=connection.prepareStatement(sql2);
            statement.setString(1,"B");
            statement.executeUpdate();
            connection.commit();       //业务完毕,提交事务
            System.out.println("事务执行成功");
        } catch (SQLException e) {
            //显示定义,失败默认会回滚
//            try {
//                connection.rollback();
//            } catch (SQLException ex) {
//                ex.printStackTrace();
//            }
            e.printStackTrace();
        }finally {
            JdbcUtils.release(connection,statement,null);
        }
    }
}

数据库连接池

  • 数据库连接和释放十分浪费资源
  • 池化技术:准备一些预先的资源,过来就连接预先准备好的资源
  • 最小连接数:按照常用连接数来设置最小连接数
  • 最大连接数
  • 等待超时
  • 编写连接池,实现一个接口 DataSource
  • 使用数据库连接池后,我们在项目开发中就不需要编写连接数据库的代码
DBCP 连接池
  • 需要导入 jar 包

    commons-dbcp2-2.9.0,commons-pool2-2.11.1,commons-logging-1.2

配置文件

#连接设置
driverClassName=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/sjdbc?useUnicode=true&characterEncoding=utf8&useSSL=true
username=root
password=123456

#!-- 初始化连接 --
initialSize=10

#最大连接数量
maxActive=50

#!-- 最大空闲连接 --
maxIdle=20

#!-- 最小空闲连接 --
minIdle=5

#!-- 超时等待时间以毫秒为单位 6000毫秒/1000等于60秒 --
maxWait=60000
#JDBC驱动建立连接时附带的连接属性属性的格式必须为这样:【属性名=property;】
#注意:user 与 password 两个属性会被明确地传递,因此这里不需要包含他们。
connectionProperties=useUnicode=true;characterEncoding=UTF8

#指定由连接池所创建的连接的自动提交(auto-commit)状态。
defaultAutoCommit=true

#driver default 指定由连接池所创建的连接的只读(read-only)状态。
#如果没有设置该值,则“setReadOnly”方法将不被调用。(某些驱动并不支持只读模式,如:Informix)
defaultReadOnly=

#driver default 指定由连接池所创建的连接的事务级别(TransactionIsolation)。
#可用值为下列之一:(详情可见javadoc。)NONE,READ_UNCOMMITTED, READ_COMMITTED, REPEATABLE_READ, SERIALIZABLE
defaultTransactionIsolation=READ_UNCOMMITTED

工具类

package com.xh.text02.utils2;

import org.apache.commons.dbcp2.BasicDataSourceFactory;
import javax.sql.DataSource;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;

public class JdbcUtils_dbcp {
    private static DataSource dataSource=null;
    static {
        try{
            InputStream ras = JdbcUtils_dbcp.class.getClassLoader().getResourceAsStream("dbcpconfig.properties");
            Properties properties = new Properties();
            properties.load(ras);
            dataSource = BasicDataSourceFactory.createDataSource(properties);       //创建数据源
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    //获取连接
    public static Connection getConnection() throws SQLException {
        return dataSource.getConnection();       //从数据源中获取连接
    }
    //释放连接资源
    public static void release(Connection connection, Statement statement, ResultSet resultSet){
        if (resultSet!=null){
            try {
                resultSet.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if(statement!=null){
            try {
                statement.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (connection!=null){
            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

实现类

package com.xh.text02;

import com.xh.text02.utils2.JdbcUtils_dbcp;
import java.sql.*;
import java.util.Date;

public class Text01 {
    public static void main(String[] args) {
        Connection connection=null;
        PreparedStatement statement=null;
        ResultSet resultSet=null;
        try {
            connection = JdbcUtils_dbcp.getConnection();
            String sql="insert into users values(?,?,?,?,?)";       
            statement=connection.prepareStatement(sql);      
            statement.setInt(1,6);
            statement.setString(2,"xyg");
            statement.setString(3,"123456");
            statement.setString(4,"16625487@qq.com");
            statement.setDate(5,new java.sql.Date(new Date().getTime()));      
            int i=statement.executeUpdate();
            if (i>0){
                System.out.println("插入成功");
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            JdbcUtils_dbcp.release(connection,statement,null);
        }
    }
}
C3P0 连接池
  • 需要导入 jar 包

    c3p0-0.9.5.5,mchange-commons-java-0.2.20

配置文件(文件名必须是:c3p0-config.xml)

<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
    <!--c3p0的缺省(默认)配置
    如果在代码中ComboPooledDataSource ds=new ComboPooledDataSource();这样写就表示使用的是c3p0的缺省(默认)
    -->
    <default-config>
        <property name="driverClass">com.mysql.cj.jdbc.Driver</property>
        <property name="jdbcUrl">jdbc:mysql://localhost:3306/sjdbc?useUnicode=true&amp;characterEncoding=utf8&amp;useSSL=true</property>
        <property name="user">root</property>
        <property name="password">123456</property>

        <property name="acquiredIncrement">5</property>
        <property name="initialPoolSize">10</property>
        <property name="minPoolSize">5</property>
        <property name="maxPoolSize">20</property>
    </default-config>
    <!--c3p0的缺省(默认)配置
    如果在代码中ComboPooledDataSource ds=new ComboPooledDataSource("MySQL");这样写就表示使用的是name是MySQL的数据源
    -->
    <named-config name="MySQL">
        <property name="driverClass">com.mysql.cj.jdbc.Driver</property>
        <property name="jdbcUrl">jdbc:mysql://localhost:3306/sjdbc?userUnicode=true&amp;characterEncoding=utf8&amp;uesSSL=true</property>
        <property name="user">root</property>
        <property name="password">123456</property>

        <property name="acquiredIncrement">5</property>
        <property name="initialPoolSize">10</property>
        <property name="minPoolSize">5</property>
        <property name="maxPoolSize">20</property>
    </named-config>
</c3p0-config>

工具类

package com.xh.text02.utils3;

import com.mchange.v2.c3p0.ComboPooledDataSource;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class c3p0text {
    private static ComboPooledDataSource dataSource=null;
    static {
        try{
            dataSource = new ComboPooledDataSource();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    //获取连接
    public static Connection getConnection() throws SQLException {
        return dataSource.getConnection();       //从数据源中获取连接
    }
    //释放连接资源
    public static void release(Connection connection, Statement statement, ResultSet resultSet){
        if (resultSet!=null){
            try {
                resultSet.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if(statement!=null){
            try {
                statement.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (connection!=null){
            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

实现类

package com.xh.text02;

import com.xh.text02.utils3.c3p0text;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Date;

public class Text04 {
    public static void main(String[] args) {
        Connection connection=null;
        PreparedStatement statement=null;
        try {
            connection = c3p0text.getConnection();
            String sql="insert into users values(?,?,?,?,?)";      
            statement=connection.prepareStatement(sql);       
            statement.setInt(1,7);
            statement.setString(2,"xyg");
            statement.setString(3,"123456");
            statement.setString(4,"16625487@qq.com");
            statement.setDate(5,new java.sql.Date(new Date().getTime()));      
            int i=statement.executeUpdate();
            if (i>0){
                System.out.println("插入成功");
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            c3p0text.release(connection,statement,null);
        }
    }
}
  • 无论使用什么数据源,本质都是一样的,DataSource 接口不变,方法就不会变
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值