- Java数据库连接,(Java Database Connectivity,简称JDBC)是Java语言中用来规范客户端程序如何来访问数据库的应用程序接口,提供了诸如查询和更新数据库中数据的方法。JDBC也是Sun Microsystems的商标。我们通常说的JDBC是面向关系型数据库的。
- 为了简化 开发人员的(对数据的统一)操作,提供了一个java操作数据库规范,对于开发人员来说,我们只需要掌握JDBC接口的操作即可;
- 导入数据库驱动mysql-connector-java-8.0.21.jar
注意:导入jar包后,需要add as library
- 加载驱动Class.forName
- 用户信息和url,username,password
- 连接成功,得到数据库对象Connection
- 获取执行sql对象 statement 用来执行sql
- 执行sql
- 获取结果集resultSet
- 释放连接
package com.jdbc;
import java.sql.*;
public class JdbcDemo {
public static void main(String[] args) throws ClassNotFoundException, SQLException, SQLException {
//1.加载驱动
Class.forName("com.mysql.cj.jdbc.Driver");
//2. 用户信息和url
/**
* test 数据库名
* useUnicode=true 支持中文
* characterEncoding=utf-8 使用utf-8
*useSSL=true 是否通过证书或者令牌进行安全验证
* serverTimezone=Asia/Shanghai 设置时区
*/
String url = "jdbc:mysql://localhost:3306/test?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&useSSL=true";
String user="root";
String password="cqmcx";
//3.获取连接 connection 相当于一个数据库对象
Connection connection = DriverManager.getConnection(url, user, password);
//4.获取执行sql对象 statement 用来执行sql
Statement statement = connection.createStatement();
//5.执行sql 可以现在数据库中写好sql
String sql="select * from demo where name='cx'";
//6.获取结果集
/**
* statement.executeQuery 执行查询
* statement.executeUpdate 执行 增删改
* statement.execute 怎删改查 都可以
*/
ResultSet resultSet = statement.executeQuery(sql);
//6.遍历结果
while (resultSet.next()){
//列名要与数据库中字段名一样
System.out.println("id="+resultSet.getInt("id"));
System.out.println("name="+resultSet.getString("name"));
}
//7.释放连接
resultSet.close();
statement.close();
connection.close();
}
}
//2. 加载驱动
DriverManager.registerDriver(new com.mysql.cj.jdbc.Driver());
//1.加载驱动
Class.forName("com.mysql.cj.jdbc.Driver");
1和2 两种方式都可以,推荐使用下面一种,因为Driver这个类:
// 静态代码块只在类加载的时候执行,且只执行一次
static {
try {
DriverManager.registerDriver(new Driver());
} catch (SQLException var1) {
throw new RuntimeException("Can't register driver!");
}
}
不明白反射的可以去 反射机制
- mysql :3306
协议://主机地址:端口号/数据库名?参数1&参数2&参数…- oralce:1521
jdbc:oracle:thin:@主机地址:1521:sid
//回滚事务
connection.rollback();
//提交事务
connection.commit();
//开启关闭事务的自动提交
connection.setAutoCommit();
//4.执行sql 可以现在数据库中写好sql
String sql="update demo set name='cxcx' where id=1";
try {
// 关闭事务自动提交
connection.setAutoCommit(false);
int i = statement.executeUpdate(sql);//更新操作
//提交事务
connection.commit();
int i2=10/0;//发生异常
//开启事务自动提交
connection.setAutoCommit(true);
} catch (SQLException e) {
connection.rollback();//发生异常回滚事务
e.printStackTrace();
} finally {
statement.close();
connection.close();
}
//4.执行sql 可以现在数据库中写好sql
String sql="update demo set name='cx' where id=1";
try {
// 关闭事务自动提交
connection.setAutoCommit(false);
int i = statement.executeUpdate(sql);//更新操作
int i2=10/0;//发生异常
//开启事务自动提交
connection.setAutoCommit(true);
//提交事务
connection.commit();
} catch (SQLException e) {
connection.rollback();//发生异常回滚事务
e.printStackTrace();
} finally {
statement.close();
connection.close();
}
因为是先发生了错误,此时数据还没有被提交,所以事务进行了回滚
Statement 会导致sql注入问题,一般使用PrepareStatement来执行sql对象
/**
* statement.executeQuery 执行查询
* statement.executeUpdate 执行 增删改,返回的是受影响的行数
* statement.execute 增删改查 都可以
*/
//2.获取连接 connection 相当于一个数据库对象
Connection connection = DriverManager.getConnection(url, user, password);
//3.获取执行sql对象 statement 用来执行sql
Statement statement = connection.createStatement();
//实际情况中,是我们传入一个变量
String name="'cdacdc' or 1=1";
//4.执行sql 可以现在数据库中写好sql
String sql="select * from demo where name="+name;
//5.获取结果集
ResultSet resultSet = statement.executeQuery(sql);
//6.遍历结果
while (resultSet.next()){
//列名要与数据库中字段名一样
System.out.println("id="+resultSet.getInt("id"));
System.out.println("name="+resultSet.getString("name"));
}
//2.获取连接 connection 相当于一个数据库对象
Connection connection = DriverManager.getConnection(url, user, password);
//实际情况中,是我们传入一个变量
String name="'cdacdc' or 1=1";
//3.使用? 占位符代替参数
String sql="select * from demo where name=?";
//4.进行预编译
PreparedStatement preparedStatement = connection.prepareStatement(sql);
//手动给参数赋值
preparedStatement.setString(1,name);
//5.获取结果集
ResultSet resultSet = preparedStatement.executeQuery(sql);
报错:
eption in thread "main" java.sql.SQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '?' at line 1
查询的结果集:封装了所有的查询结果
resultSet.beforeFirst();//移动到最前面
resultSet.afterLast();//移动到最后面
resultSet.next();//移动到下一个数据
resultSet.previous();//移动到前一行
resultSet.absolute(row);//移动到指定行
//如果知道列的类型就使用对应的类型获取
resultSet.getString("列名");
- 上述代码我们看到了,有一些东西是在很多地方都是不变的,例如反射加载类模板,建立连接,释放连接等…,所以我们可以创建一个工具类,这个类提供一个获取连接的方法和释放连接的方法即可!
JDBCUtil.java
package com.jdbc.utils;
import java.sql.*;
public class JDBCUtil {
static String url = "jdbc:mysql://localhost:3306/test?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&useSSL=true";
static String user="root";
static String password="cqmcx";
static {
//1.加载驱动
try {
Class.forName("com.mysql.cj.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
/*获取连接*/
public static Connection getConnection() throws SQLException {
return DriverManager.getConnection(url, user, password);
}
public static void colseConnection(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();
}
}
}
}
JdbcDemo.java
package com.jdbc;
import com.jdbc.utils.JDBCUtil;
import java.sql.*;
public class JdbcDemo {
public static void main(String[] args) throws ClassNotFoundException, SQLException, SQLException {
Connection connection=null;
PreparedStatement preparedStatement=null;
ResultSet resultSet=null;
try {
connection = JDBCUtil.getConnection();
String sql="select * from demo where name= ? ";
preparedStatement = connection.prepareStatement(sql);
preparedStatement.setString(1,"cxcx");
resultSet = preparedStatement.executeQuery();
while (resultSet.next()){
//列名要与数据库中字段名一样
System.out.println("id="+resultSet.getInt("id"));
System.out.println("name="+resultSet.getString("name"));
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
JDBCUtil.colseConnection(connection,preparedStatement,resultSet);
}
}
}
注意:
sql.Date 数据库 java.sql.Date()
util.Date java new java.sql.Date(new Date().getTime())
driver=com.mysql.cj.jdbc.Driver
url =jdbc:mysql://localhost:3306/test?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&useSSL=true
user=root
password=cqmcx
package com.jdbc.utils;
import java.io.IOException;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;
public class JDBCUtil {
static String driver = null;
static String url = null;
static String user=null;
static String password=null;
static {
//1.加载驱动
try {
/*
* 加载根目录下的资源文件
* */
InputStream resourceAsStream = JDBCUtil.class.getClassLoader().getResourceAsStream("jdbc.properties");
Properties properties = new Properties();
properties.load(resourceAsStream);
driver=properties.getProperty("driver");
url=properties.getProperty("url");
user=properties.getProperty("user");
password=properties.getProperty("password");
//加载驱动
Class.forName(driver);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
/*获取连接*/
public static Connection getConnection() throws SQLException {
return DriverManager.getConnection(url, user, password);
}
public static void colseConnection(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();
}
}
}
}
- 由于java连接数据库,要经历连接-释放-连接-释放,这样十分耗费资源,所以我们有没有可能提前准备一些资源,等程序需要使用的时候就可以直接使用,用完之后放在此处等待其他程序使用,** 池化技术**就此诞生了!
DBCP (Database Connection Pool)是一个依赖 Jakarta commons-pool 对象池机制的数据库连接池,Tomcat 的数据源使用的就是 DBCP。
#连接设置
#driverClassName 是dbcp设置好的名字
driverClassName=com.mysql.cj.jdbc.Driver
url =jdbc:mysql://localhost:3306/test?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&useSSL=true
username=root
password=cqmcx
#
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
package com.jdbc.utils;
import org.apache.commons.dbcp.BasicDataSourceFactory;
import javax.sql.DataSource;
import java.io.IOException;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;
public class JDBCUtil {
private static DataSource dataSource=null;
static {
//1.加载驱动
try {
/*
* 加载根目录下的资源文件
* */
InputStream resourceAsStream = JDBCUtil.class.getClassLoader().getResourceAsStream("jdbc_config.properties");
Properties properties = new Properties();
properties.load(resourceAsStream);
//创建数据源--工厂模式
dataSource = BasicDataSourceFactory.createDataSource(properties);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
/*获取连接*/
public static Connection getConnection() throws SQLException {
return dataSource.getConnection();
}
public static void colseConnection(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();
}
}
}
}
- C3P0是一个开源的JDBC连接池,它实现了数据源和JNDI绑定,支持JDBC3规范和JDBC2的标准扩展。使用它的开源项目有Hibernate、Spring等。
<?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/test?serverTimezone=Asia/Shanghai&characterEncoding=utf-8&useSSL=true&useUnicode=true</property>
<property name="user">root</property>
<property name="password">cqmcx</property>
<property name="acquireIncrement">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");"这样写就表示使用的是mysql的缺省(默认)
-->
<named-config name="MySQL">
<property name="driverClass">com.mysql.cj.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/test?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&useSSL=true</property>
<property name="user">root</property>
<property name="password">cqmcx</property>
<property name="acquireIncrement">5</property>
<property name="initialPoolSize">10</property>
<property name="minPoolSize">5</property>
<property name="maxPoolSize">20</property>
</named-config>
</c3p0-config>
package com.jdbc.utils;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.apache.commons.dbcp.BasicDataSourceFactory;
import javax.activation.DataSource;
import java.io.IOException;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;
public class JDBCUtil {
private static ComboPooledDataSource dataSource=null;
//2.private static ComboPooledDataSource dataSource=null;
static {
try {
//2.代码版配置
// dataSource= new ComboPooledDataSource();
// dataSource.setDriverClass();
// dataSource.setUser();
// dataSource.setPassword();
// dataSource.setJdbcUrl();
//1.配置文件写法
dataSource= new ComboPooledDataSource();
} catch (Exception e) {
e.printStackTrace();
}
}
/*获取连接*/
public static Connection getConnection() throws SQLException {
return dataSource.getConnection();
}
public static void colseConnection(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();
}
}
}
}
=============================================================================
JDBC 推荐狂神说