<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<version>8.0.24version>
dependency>
driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/school?useSSL=true&useUnicode=true&characterEncoding=UTF-8
username=root
password=123456
public class JdbcUtils {
private static String driver = null;
private static String url = null;
private static String username = null;
private static String password = null;
//1.属性资源导入
static {
try {
InputStream in = JdbcUtils.class.getClassLoader().getResourceAsStream("db.properties"); //获取输入流
Properties properties = new Properties(); //创建空属性列表
properties.load(in); //加载流资源
//获取属性资源
driver = properties.getProperty("driver");
url = properties.getProperty("url");
username = properties.getProperty("username");
password = properties.getProperty("password");
//2.驱动只用加载一次
Class.forName(driver);
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
//3.获取连接
public static Connection getConnection() throws SQLException {
return DriverManager.getConnection(url, username, password);
}
//4.释放连接资源
public static void release(Connection connection, Statement statement, ResultSet resultSet){
if(resultSet != null){
try {
resultSet.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if(statement != null){
try {
statement.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if(connection != null){
try {
connection.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
}
public class JdbcTest01 {
public static void main(String[] args) {
//getUserById("'张三'"); //正常情况
getUserById("'' or 1=1"); //非正常情况,出现sql注入问题
}
//CRUD业务代码
public static void getUserByName(String name){
//5.提升作用域:为了能在finally中使用
Connection connection = null;
Statement statement = null;
ResultSet resultSet = null;
try {
connection = JdbcUtils.getConnection(); //1.获取数据库的连接
statement = connection.createStatement(); //2.获取SQL的执行对象(使用Statement类型对象,存在Sql注入问题)
//核心:sql语句
String sql = "SELECT * FROM student WHERE studentname = " + name ;
//3.获取结果(集)
resultSet = statement.executeQuery(sql);
while (resultSet.next()){
System.out.println(resultSet.getString("studentno"));
System.out.println(resultSet.getString("loginpwd"));
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}finally {
//4.释放资源
JdbcUtils.release(connection, statement, resultSet);
}
}
}
public class JdbcTest02 {
public static void main(String[] args) {
getUserById("张三"); //正常情况
//getUserById("'' or 1=1"); //没有返回值,预防sql注入问题
//prepareStatement防止sql注入的本质:把传递进来的参数当作字符,若其中存在转义字符,就会直接忽略(如'会被直接转义)
}
//CRUD业务代码
public static void getUserByName(String name){
//5.提升作用域:为了能在finally中使用
Connection connection = null;
PreparedStatement statement = null;
ResultSet resultSet = null;
try {
connection = JdbcUtils.getConnection();
//使用?占位符,来代替参数
String sql = "SELECT * FROM student WHERE studentname = ?";
statement = connection.prepareStatement(sql); //1.使用prepareStatement来预编译sql(先写sql但先不执行)
//2.手动给参数赋值
statement.setString(1,name); //index默认从1开始
//3.执行
resultSet = statement.executeQuery();
while (resultSet.next()){
System.out.println(resultSet.getString("studentno"));
System.out.println(resultSet.getString("loginpwd"));
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}finally {
//4.释放资源
JdbcUtils.release(connection, statement, resultSet);
}
}
}
数据库连接池的基本思想:
为什么需要数据库连接池?
多种开源的数据库连接池:
JDBC 的数据库连接池使用 javax.sql.DataSource 来表示,DataSource 只是一个接口,该接口通常由服务器(Weblogic, WebSphere, Tomcat)提供实现,也有一些开源组织提供实现:
DataSource 通常被称为数据源,它包含连接池和连接池管理两个部分,习惯上也经常把 DataSource 称为连接池。
DataSource用来取代DriverManager来获取Connection,获取速度快,同时可以大幅度提高数据库访问速度。
特别注意:
<dependency>
<groupId>org.apache.commonsgroupId>
<artifactId>commons-dbcp2artifactId>
<version>2.7.0version>
dependency>
<dependency>
<groupId>org.apache.commonsgroupId>
<artifactId>commons-pool2artifactId>
<version>2.9.0version>
dependency>
#连接设置(driverClassName是DBCP数据源中定义好的固定名字)
driverClassName=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/school?useUnicode=true&characterEncoding=utf8&useSSL=true
username=root
password=123456
#
initialSize=10
#最大连接数量
maxActive=50
#
maxIdle=20
#
minIdle=5
#
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
public class JdbcUtils_DBCP {
//4.提升作用域
private static BasicDataSource dataSource = null;
//1.获取数据源 dataSource
static {
try {
InputStream in = JdbcUtils_DBCP.class.getClassLoader().getResourceAsStream("dbcp-config.properties"); //获取输入流
Properties properties = new Properties(); //创建空属性列表
properties.load(in); //加载流资源
//创建数据源 工厂模式--->创建对象
//在java中,编写数据库连接池需实现java.sql.DataSource接口,每一种数据库连接池都是DataSource接口的实现,而DBCP连接池就是java.sql.DataSource接口的一个具体实现
dataSource = BasicDataSourceFactory.createDataSource(properties);
} catch (Exception e) {
e.printStackTrace();
}
}
//2.获取连接 (数据源dataSource自带连接)
public static Connection getConnection() throws SQLException {
return dataSource.getConnection();
}
//3.释放连接资源
public static void release(Connection connection, Statement statement, ResultSet resultSet){
if(resultSet != null){
try {
resultSet.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if(statement != null){
try {
statement.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if(connection != null){
try {
connection.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
}
public class JdbcTestDBCP {
public static void main(String[] args) {
getUserByName("张伟");
}
//CRUD业务代码
public static void getUserByName(String name){
//5.提升作用域:为了能在finally中使用
Connection connection = null;
PreparedStatement statement = null;
ResultSet resultSet = null;
try {
connection = JdbcUtils_DBCP.getConnection(); //利用数据源改变的地方一
//使用?占位符,来代替参数
String sql = "SELECT * FROM student WHERE studentname = ?";
statement = connection.prepareStatement(sql); //1.使用prepareStatement来预编译sql(先写sql但先不执行)
//2.手动给参数赋值
statement.setString(1,name); //index默认从1开始
//3.执行
resultSet = statement.executeQuery();
while (resultSet.next()){
System.out.println(resultSet.getString("studentno"));
System.out.println(resultSet.getString("loginpwd"));
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}finally {
//4.释放资源
JdbcUtils_DBCP.release(connection, statement, resultSet); //利用数据源改变的地方二
}
}
}
<dependency>
<groupId>com.mchangegroupId>
<artifactId>c3p0artifactId>
<version>0.9.5.5version>
dependency>
<dependency>
<groupId>com.mchangegroupId>
<artifactId>mchange-commons-javaartifactId>
<version>0.2.20version>
dependency>
<c3p0-config>
<default-config>
<property name="driverClass">com.mysql.cj.jdbc.Driverproperty>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/school?useUnicode=true&characterEncoding=utf8&useSSL=trueproperty>
<property name="user">rootproperty>
<property name="password">123456property>
<property name="acquireIncrement">5property>
<property name="initialPoolSize">10property>
<property name="minPoolSize">5property>
<property name="maxPoolSize">20property>
default-config>
<named-config name="MySQL">
<property name="driverClass">com.mysql.cj.jdbc.Driverproperty>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/school?useUnicode=true&characterEncoding=utf8&useSSL=trueproperty>
<property name="user">rootproperty>
<property name="password">123456property>
<property name="acquireIncrement">5property>
<property name="initialPoolSize">10property>
<property name="minPoolSize">5property>
<property name="maxPoolSize">20property>
named-config>
c3p0-config>
public class JdbcUtils_C3P0 {
//4.提升作用域
private static ComboPooledDataSource dataSource = null;
//1.获取数据源 dataSource
static {
try {
//创建数据源 (直接new一个ComboPooledDataSource()对象就可以获得数据源)
dataSource = new ComboPooledDataSource(); //C3P0的缺省(默认)配置
//ComboPooledDataSource dataSource = new ComboPooledDataSource("MySQL"); //C3P0的命名配置(配置文件写法)
} catch (Exception e) {
e.printStackTrace();
}
}
//2.获取连接 (数据源dataSource自带连接)
public static Connection getConnection() throws SQLException {
return dataSource.getConnection();
}
//3.释放连接资源
public static void release(Connection connection, Statement statement, ResultSet resultSet){
if(resultSet != null){
try {
resultSet.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if(statement != null){
try {
statement.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if(connection != null){
try {
connection.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
}
public class JdbcTestC3P0 {
public static void main(String[] args) {
getUserByName("张三"); //正常情况
}
//CRUD业务代码
public static void getUserByName(String name){
//5.提升作用域:为了能在finally中使用
Connection connection = null;
PreparedStatement statement = null;
ResultSet resultSet = null;
try {
connection = JdbcUtils_C3P0.getConnection();//利用数据源改变的地方一
//使用?占位符,来代替参数
String sql = "SELECT * FROM student WHERE studentname = ?";
statement = connection.prepareStatement(sql); //1.使用prepareStatement来预编译sql(先写sql但先不执行)
//2.手动给参数赋值
statement.setString(1,name); //index默认从1开始
//3.执行
resultSet = statement.executeQuery();
while (resultSet.next()){
System.out.println(resultSet.getString("studentno"));
System.out.println(resultSet.getString("loginpwd"));
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}finally {
//4.释放资源
JdbcUtils_C3P0.release(connection, statement, resultSet); //利用数据源改变的地方二
}
}
}