目录
一、JDBC基本概念
1、概念
2、JDBC本质
二、JDBC快速入门
1、步骤
2、代码示例
三、JDBC各个对象详解
1、DriverManager驱动管理对象
作用:
2、Connection数据库连接对象
作用:
3、Statement数据库语句执行对象
作用:
4、ResultSet结果集对象
方法:
5、PreparedStatement执行sql的对象
①SQL注入问题:在拼接sql时,有一些sql的特殊关键字参与字符串拼接,会造成安全性问题;
四、JDBC事务管理
1、使用Connection管理事务
2、示例
五、数据库连接池
1、概述
2、实现
标准接口:
获取连接:
归还连接:
备注:
一些实现:
3、C3P0
①使用步骤:
②简单使用示例:
4、druid
使用步骤:
代码示例:
六、JDBCTemplate
1、介绍
2、使用步骤
第一步:
第二步:
第三步:
3、代码演示:
druid.properties见上面;
java代码:
一、JDBC基本概念
1、概念
Java DataBase Connectivity Java数据库连接,Java语言操作数据库;
2、JDBC本质
官方(SUN公司)定义的一套操作数据库的规则,即接口。各个数据库厂商实现了这套接口,提供了数据库驱动jar包,我们呢可以使用这套(JDBC)接口进行编程,真正执行的代码是jar包中的实现类;
二、JDBC快速入门
1、步骤
第一步:导入驱动jar包;(将所用jar包复制到libs目录,然后右键选择Add As Library)
第二步:注册驱动;
第三步:获取数据库连接对象;
第四步:定义sql;
第五步:获取执行sql语句的对象——Statement;
第六步:执行sql;
第七步:处理结果;
第八步:释放资源;
2、代码示例
package mysql;
import com.mysql.jdbc.Driver;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
public class Main {
public static void main(String[] args) throws Exception {
//第一步:导入驱动jar包;
//第二步:注册驱动;其实,在mysql5之后,可以省略这句话,但不建议省略
Class.forName("com.mysql.cj.jdbc.Driver");
//第三步:获取数据库连接对象;
Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/zibo?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC","root","root");
//第四步:定义sql;
String sql = "update stu set name = '二哥哥' where name = '二哥'";
//第五步:获取执行sql语句的对象——Statement;
Statement statement = connection.createStatement();
//第六步:执行sql;
long l = statement.executeLargeUpdate(sql);
//第七步:处理结果;
System.out.println(l);//1 执行成功了
//第八步:释放资源;
statement.close();
connection.close();
}
}
三、JDBC各个对象详解
1、DriverManager驱动管理对象
作用:
①注册驱动;
static void registerDriver(Driver driver)向DriverManager 注册给定驱动程序。
在我们的程序中使用的
//第二步:注册驱动;其实,在mysql5之后,可以省略这句话,但不建议省略
Class.forName("com.mysql.cj.jdbc.Driver");
实际上其内部静态代码块自动执行了registerDriver方法;
②获取数据库连接;
方法:
static Connection getConnection(String url, String user, String password)试图建立到给定数据库 URL 的连接。
参数说明:
url:指定连接数据库的路径;
语法:jdbc:mysql://ip地址(域名):端口号/数据库名称,后面要加上“?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC”,即为:
jdbc:mysql://ip地址(域名):端口号/数据库名称?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC
可以简写,将ip地址(域名):端口号省略,因为默认是localhost:3306;
user:用户名;
password:密码;
2、Connection数据库连接对象
作用:
①获取执行sql的对象;
Statement createStatement()创建一个 Statement 对象来将 SQL 语句发送到数据库。
PreparedStatement prepareStatement(String sql)创建一个 PreparedStatement 对象来将参数化的 SQL 语句发送到数据库。
②管理事务
开启事务:void setAutoCommit(boolean autoCommit)设置为false为开始事务;
提交事务:void commit();
回滚事务:void rollback()
3、Statement数据库语句执行对象
作用:
①执行sql
boolean execute(String sql):可以执行任意sql(了解即可);
int executeUpdate(String sql):执行DML(增删改)语句-常用、DDL(create、alter、drop)语句-不常用,返回值是影响的行数,可以通过行数判断是否执行成功,即大于0则成功;
ResultSet executeQuery(String sql):执行DQL(查询)语句,返回结果集对象;
示例代码:
package mysql;
import com.mysql.jdbc.Driver;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
public class Main {
public static void main(String[] args) throws Exception {
//第一步:导入驱动jar包;
//第二步:注册驱动;其实,在mysql5之后,可以省略这句话,但不建议省略
Class.forName("com.mysql.cj.jdbc.Driver");
//第三步:获取数据库连接对象;
Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/zibo?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC","root","root");
//第四步:定义sql;
//添加一条数据
String sql_add = "insert into stu(name,ranking,dep_id) values('訾博1',191,1)";
//修改一条数据
String sql_change = "update stu set name = '二哥' where name = '二哥哥'";
//删除一条数据
String sql_delete = "delete from stu where name = '二姐'";
//第五步:获取执行sql语句的对象——Statement;
Statement statement = connection.createStatement();
//第六步:执行sql;
long l1 = statement.executeLargeUpdate(sql_add);
long l2 = statement.executeLargeUpdate(sql_change);
long l3 = statement.executeLargeUpdate(sql_delete);
//第七步:处理结果;
if(l1>0){
System.out.println("添加成功!");
}else {
System.out.println("添加失败!");
}
if(l2>0){
System.out.println("修改成功!");
}else {
System.out.println("修改失败!");
}
if(l3>0){
System.out.println("删除成功!");
}else {
System.out.println("删除失败!");
}
//第八步:释放资源;
statement.close();
connection.close();
}
}
4、ResultSet结果集对象
方法:
boolean next():将光标从当前位置向下移一个位置(并不是一次移动一行,而是一列(当前行的一列))。
getXxx():获取数据,Xxx代表数据类型;
getXxx()参数:
int:代表列的编号;
String:代表列的名称;
使用步骤:
第一步:游标向下移动一行;
第二步:判断是否有数据;
第三步:如果有,则获取数据,否则结束;
代码示例:
package mysql;
import com.mysql.jdbc.Driver;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
public class Main {
public static void main(String[] args) throws Exception {
//第一步:导入驱动jar包;
//第二步:注册驱动;其实,在mysql5之后,可以省略这句话,但不建议省略
Class.forName("com.mysql.cj.jdbc.Driver");
//第三步:获取数据库连接对象;
Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/zibo?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC","root","root");
//第四步:定义sql;
String sql = "select * from stu";
//第五步:获取执行sql语句的对象——Statement;
Statement statement = connection.createStatement();
//第六步:执行sql;
ResultSet set = statement.executeQuery(sql);
//第七步:处理结果;
while (true){
boolean yes = set.next();
if(!yes){
break;
}else {
System.out.println("id:"+set.getInt("id"));
System.out.println("姓名:"+set.getString("name"));
System.out.println("排名:"+set.getInt("ranking"));
System.out.println("信息id:"+set.getInt("dep_id"));
System.out.println("------------------------------");
}
}
//第八步:释放资源;
statement.close();
connection.close();
}
}
5、PreparedStatement执行sql的对象
①SQL注入问题:在拼接sql时,有一些sql的特殊关键字参与字符串拼接,会造成安全性问题;
当随便输入用户名,输入这个密码:a' or 'a' = 'a;
最终拼接成的sql语句是:select * from stu where username = 'fsagfsdgsjsd' and password = 'a' or 'a' = 'a'
发现由于or,这个sql语句的结果永远为True,那么数据库则会登录成功!多么危险!
解决SQL注入问题:使用PreparedStatement对象解决
预编译的SQL:参数使用?作为占位符;
步骤:
第一步:导入驱动jar包;(将所用jar包复制到libs目录,然后右键选择Add As Library)
第二步:注册驱动;
第三步:获取数据库连接对象;
第四步:定义sql;
SQL的参数使用?作为占位符,例如:
select * from user where username = ? and password = ?;
第五步:获取执行sql语句的对象——PreparedStatement,connection.prepareStatement(String sql)将sql语句传入;
第六步:给占位符?赋值;
方法:setXxx(参数1,参数2),参数1是第i个?代表的数据的索引,参数2是第i个?代表的数据的值,以此类推;
第七步:执行sql,这里就不需要传递sql语句了,前面已经传了,并处理结果;
第八步:释放资源;
四、JDBC事务管理
1、使用Connection管理事务
开启事务:void setAutoCommit(boolean autoCommit)设置为false为开始事务;
提交事务:void commit();
回滚事务:void rollback()
2、示例
package mysql;
import com.mysql.jdbc.Driver;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
public class Main {
public static void main(String[] args) throws Exception {
//第一步:导入驱动jar包;
//第二步:注册驱动;其实,在mysql5之后,可以省略这句话,但不建议省略
Class.forName("com.mysql.cj.jdbc.Driver");
//第三步:获取数据库连接对象;
Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/zibo?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC","root","root");
try {
//第四步:定义sql;
String name = "name";
String sql = "update stu set name = '四哥',ranking = 100 where name = '大神'";
//第五步:获取执行sql语句的对象——Statement;
Statement statement = connection.createStatement();
//执行sql之前开启事务
connection.setAutoCommit(false);
//第六步:执行sql;
int i = statement.executeUpdate(sql);
//第七步:处理结果;
System.out.println(i);
//提交事务
connection.commit();
//第八步:释放资源;
statement.close();
connection.close();
} catch (Exception e) {
e.printStackTrace();
//一旦出现任何异常都进行回滚操作
if (connection!=null){
connection.rollback();
}
}
}
}
五、数据库连接池
1、概述
本质上与线程池一样,这里不再做过多叙述;
2、实现
标准接口:
DataSource;
获取连接:
getConnection();
归还连接:
如果连接是从连接池中获取的,那么调用Connection.close()方法,则不会再关闭连接,而是归还连接;
备注:
我们呢一般不去实现这个接口,由数据库厂商实现;
一些实现:
C3P0:数据库连接池技术;
Druid:数据库连接池实现技术,由阿里巴巴提供;
3、C3P0
①使用步骤:
第一步:
导入jar包(c3p0-0.9.2.1.jar和mchange-commons-java-0.2.3.4.jar);
第二步:
定义配置文件(自动加载):
名称是c3p0.properties或者c3p0-config.xml;
路径:直接将文件放在src目录下即可;
第三步:
创建核心对象,数据库连接池对象,ComboPooledDataSource
第四步:
获取连接,getConnection
②简单使用示例:
xml配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
<!-- 默认配置,如果没有指定则使用这个配置 -->
<default-config>
<property name="user">root</property>
<property name="password">root</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/zibo?useUnicode=true;useJDBCCompliantTimezoneShift=true;useLegacyDatetimeCode=false;serverTimezone=UTC</property>
<property name="driverClass">com.mysql.cj.jdbc.Driver</property>
<property name="checkoutTimeout">30000</property>
<property name="idleConnectionTestPeriod">30</property>
<property name="initialPoolSize">3</property>
<property name="maxIdleTime">30</property>
<property name="maxPoolSize">100</property>
<property name="minPoolSize">2</property>
<property name="maxStatements">200</property>
</default-config>
<!-- 命名的配置,可以通过方法调用实现 -->
<named-config name="mysql">
<property name="user">root</property>
<property name="password">root</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/zibo?useUnicode=true;useJDBCCompliantTimezoneShift=true;useLegacyDatetimeCode=false;serverTimezone=UTC</property>
<property name="driverClass">com.mysql.cj.jdbc.Driver</property>
<!-- 如果池中数据连接不够时一次增长多少个 -->
<property name="acquireIncrement">5</property>
<!-- 初始化数据库连接池时连接的数量 -->
<property name="initialPoolSize">20</property>
<!-- 数据库连接池中的最大的数据库连接数 -->
<property name="maxPoolSize">25</property>
<!-- 数据库连接池中的最小的数据库连接数 -->
<property name="minPoolSize">5</property>
</named-config>
</c3p0-config>
Java代码:
package mysql;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
public class TestMySql {
public static void main(String[] args) throws SQLException {
//获取DataSource,使用默认配置(一般情况使用默认配置即可,使用其他配置,只需要将名字作为参数传入)
DataSource ds = new ComboPooledDataSource();
//获取连接
Connection connection = ds.getConnection();
System.out.println(connection);
}
}
4、druid
使用步骤:
第一步:
导包druid-1.1.9.jar;
第二步:
定义配置文件(手动加载):
说明:
是properties形式的,可以取任意名称、放在任意位置;
第三步:
获取数据库连接池——通过工厂类获取DruidDataSourceFactory
第四步:
获取连接;
代码示例:
druid.properties
driverClassName=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/zibo?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC
username=root
password=root
# 初始化连接数量
initialSize=5
# 最大连接数
maxActive=10
# 最大等待时间
maxWait=3000
java代码:
package mysql;
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.SQLException;
import java.util.Properties;
public class TestMySql {
public static void main(String[] args) throws Exception {
//第一步:导包druid-1.1.9.jar;
//第二步:定义配置文件(手动加载):
//第三步:获取数据库连接池——通过工厂类获取DruidDataSourceFactory
//先加载配置文件
Properties pro = new Properties();
InputStream resourceAsStream = TestMySql.class.getClassLoader().getResourceAsStream("druid.properties");
assert resourceAsStream != null;
pro.load(resourceAsStream);
DataSource dataSource = DruidDataSourceFactory.createDataSource(pro);
//第四步:获取连接;
Connection connection = dataSource.getConnection();
System.out.println(connection);
}
}
六、JDBCTemplate
1、介绍
是Spring框架对JDBC的简单封装;
提供了JDBCTemplate简化了JDBC的开发;
好处:
不需要我们管理连接了。
不需要我们设置参数了。
查询时候可以直接返回对应的实体类。
2、使用步骤
第一步:
导入Jar包;
第二步:
创建JDBCTemplate对象,依赖于数据源DataSource
JdbcTemplate template = new JdbcTemplate(ds);
第三步:
调用JdbcTemplate的方法来完成CRUD的操作
execute:没有返回值,可以执行所有的SQL语句,一般用于执行DDL语句。
update():执行DML语句,增、删、改语句;
queryForMap():查询结果将结果集封装为map集合;
queryForList():查询结果将结果集封装为list集合;
query():查询结果,将结果封装为JavaBean对象;
queryForObject():查询结果,将结果封装为对象;
3、代码演示:
druid.properties见上面;
java代码:
package mysql;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import org.springframework.jdbc.core.JdbcTemplate;
import javax.sql.DataSource;
import java.io.InputStream;
import java.util.List;
import java.util.Map;
import java.util.Properties;
public class Test2 {
public static void main(String[] args) throws Exception {
//1、导包
//2、创建JDBCTemplate对象,依赖于数据源DataSource
//从配置文件加载数据源
Properties pro = new Properties();
InputStream resourceAsStream = TestMySql.class.getClassLoader().getResourceAsStream("druid.properties");
assert resourceAsStream != null;
pro.load(resourceAsStream);
DataSource dataSource = DruidDataSourceFactory.createDataSource(pro);
//创建JDBCTemplate对象
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
String sql = "select * from stu";
List<Map<String, Object>> list = jdbcTemplate.queryForList(sql);
for (Map<String, Object> map : list) {
for (String s : map.keySet()) {
System.out.println(map.get(s));
}
System.out.println("====================");
}
}
}