目录
一、JDBC数据库连接
1、简介
JDBC数据库连接是一个独立于特定数据库管理系统、通用的SQL数据库存取和操作的公共接口(一组API),定义了用来访问数据库的标准Java类库,(java.sql,javax.sql)使用这些类库可以以一种标准的方法、方便地访问数据库资源。
2、作用
JDBC为访问不同的数据库提供了一种统一的途径,为开发者屏蔽了一些细节问题。
3、JDBC驱动Driver接口介绍
1、概念
java.sql.Driver 接口是所有 JDBC 驱动程序需要实现的接口。这个接口是提供给数据库厂商使用的,不同数据库厂商提供不同的实现。
2、驱动
mySql的驱动: com.mysql.cj.jdbc.Driver
Oracle的驱动:oracle.jdbc.driver.OracleDriver
加载驱动:加载 JDBC 驱动需调用 Class 类的静态方法,forName(),Class.forName(“com.mysql.jdbc.Driver”);
注册驱动:DriverManager 类是驱动程序管理器类,负责管理驱动程序。
使用:DriverManager.registerDriver(com.mysql.jdbc.Driver)来注册驱动
4、JDBC URL
1、概念
URL 用于标识一个被注册的驱动程序,驱动程序管理器通过这个 URL 选择正确的驱动程序,从而建立到数据库的连接。
2、组成
jdbc:子协议:子名称;
协议:JDBC URL中的协议总是jdbc;
子协议:子协议用于标识一个数据库驱动程序;
子名称:一种标识数据库的方法。子名称可以依不同的子协议而变化,用子名称的目的是为了定位数据库;提供足够的信息。包含主机名(对应服务端的ip地址),端口号,数据库名
3、MySQL的连接URL编写方式
jdbc:mysql://localhost:3306/atguigu?[useUnicode=true&characterEncoding=utf8]serverTimezone=CTT
可以调用 DriverManager 类的 getConnection() 方法建立到数据库的连接
Connection conn = DriverManager.getConnection(url, user, password);
5、5.X与8.X的连接变化
driver驱动
变化前为:com.mysql.jdbc.Driver
变化后为:com.mysql.cj.jdbc.Driver
url
变化前为:jdbc:mysql://localhost:3306/namedatabase
变化后为:jdbc:mysql://localhost:3306/atguigu?[useUnicode=true&characterEncoding=utf8]serverTimezone=CTT
[]里面可以不写;utf8防止乱码;CTT代表时区中国台湾;GMT%2B8代表时区中国北京;
6、获取数据库连接
使用步骤:
(1)编写配置文件
(2)编写类加载配置文件
(3)读取配置信息
(4)加载驱动
(5)获取连接
连接方式一:
public class DriverText {
private static String url = "jdbc:mysql://localhost:3306/ss?serverTimezone=CTT";
private static String user = "root";
private static String password = "123";
static {
try {
Class.forName("com.mysql.cj.jdbc.Driver");
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Test
public void textConnection() {
try {
Connection con = DriverManager.getConnection(url, user, password);
System.out.println("数据库连接成功");
String sql = "select * from books";
PreparedStatement per = con.prepareStatement(sql);
ResultSet re = per.executeQuery();
while (re.next()) {
System.out.print(re.getString("bookname"));
System.out.print(" ");
System.out.print(re.getInt("price"));
System.out.println();
}
per.close();
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
连接方式二:
jdcb.properties配置文件
url=jdbc:mysql://localhost:3306/school?serverTimezone=CTT
user=root
password=123
driverClass=com.mysql.cj.jdbc.Driver
连接数据库工具类
public class JDBCUtils {
//创建数据库连接
public static Connection getConnection() throws Exception {
//1.读取配置信息
InputStream inputStream = JDBCUtils.class.getClassLoader().getResourceAsStream("jdcb.properties");
Properties pro = new Properties();
pro.load(inputStream);
String user=pro.getProperty("user");
String password=pro.getProperty("password");
String url=pro.getProperty("url");
String driverClass=pro.getProperty("driverClass");
//2.加载驱动
Class.forName(driverClass);
//3.获取连接
Connection con= DriverManager.getConnection(url,user,password);
return con;
}
//关闭数据库
public static void closeConnection(Connection con,Statement ps){
if (ps!=null){
try {
ps.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (con!=null){
try {
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
//关闭连接
public static void closeConnection(Connection con,Statement ps,ResultSet res){
if (res!=null){
try {
res.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (ps!=null){
try {
ps.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (con!=null){
try {
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
//关闭资源
public static void closeConnection(Connection con) {
if (con!=null){
try {
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
7、使用案例
public class JDBCUtilsTest {
@Test
public void jdbcTest() throws Exception {
Connection con = JDBCUtils.getConnection();
System.out.println("数据库连接成功:" + con);
JDBCUtils.closeConnection(con);
}
@Test
public void select() {
try {
Connection con = JDBCUtils.getConnection();
String sql = "select * from books where price>?";
PreparedStatement per = con.prepareStatement(sql);
per.setInt(1, 23);
ResultSet rs = per.executeQuery();
while (rs.next()) {
System.out.print(rs.getString("bookname"));
System.out.print(" ");
System.out.print(rs.getString("price"));
System.out.println();
}
per.close();
con.close();
} catch (Exception e) {
e.printStackTrace();
}
}
@Test
public void insert() {
try {
Connection con = JDBCUtils.getConnection();
String sql = "insert into books (bookname,price) values (?,?)";
PreparedStatement pre = con.prepareStatement(sql);
pre.setObject(1, "荀子");
pre.setObject(2, 65);
pre.execute();
pre.close();
con.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public void update() {
try {
Connection con = JDBCUtils.getConnection();
String sql = "update books set price=price+? where bookname=?";
PreparedStatement pre = con.prepareStatement(sql);
pre.setString(1, "88");
pre.setString(2, "老子");
//System.out.println("数据库插入数据成功");
pre.execute();
pre.close();
con.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
事物控制
public class JDBCDemo10 {
public static void main(String[] args) {
Connection conn = null;
PreparedStatement pstmt1 = null;
PreparedStatement pstmt2 = null;
try {
//1.获取连接
conn = JDBCUtils.getConnection();
//开启事务
conn.setAutoCommit(false);
//2.定义sql
//2.1 张三 - 500
String sql1 = "update account set balance = balance - ? where id = ?";
//2.2 李四 + 500
String sql2 = "update account set balance = balance + ? where id = ?";
//3.获取执行sql对象
pstmt1 = conn.prepareStatement(sql1);
pstmt2 = conn.prepareStatement(sql2);
//4. 设置参数
pstmt1.setDouble(1,500);
pstmt1.setInt(2,1);
pstmt2.setDouble(1,500);
pstmt2.setInt(2,2);
//5.执行sql
pstmt1.executeUpdate();
// 手动制造异常
int i = 3/0;
pstmt2.executeUpdate();
//提交事务
conn.commit();
} catch (Exception e) {
//事务回滚
try {
if(conn != null) {
conn.rollback();
}
} catch (SQLException e1) {
e1.printStackTrace();
}
e.printStackTrace();
}finally {
JDBCUtils.close(pstmt1,conn);
JDBCUtils.close(pstmt2,null);
}
}
}
二、数据库连接池
1、基本概念
数据库连接池负责分配、管理和释放数据库连接
,它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个;释放空闲时间超过最大空闲时间的数据库连接来避免因为没有释放数据库连接而引起的数据库连接遗漏。这项技术能明显提高对数据库操作的性能。即:就是一个容器(集合),存放数据库连接的容器。
2、用途
- 节约资源
- 用户访问快捷高效
3、实现过程
通过标准接口实现:DataSource Javax.sql包下的
- 获取连接:getConnection()
- 归还链接:Connection.close()
4、常用数据库连接池
- C3P0:数据库连接池技术
- Druid:数据库连接池实现技术,由阿里巴巴提供
5、C3P0
实现步骤
(1)导入jar包(两个)c3p0-0.9.5.2.jar mchange-commons-java-0.2.12.jar ,加数据据库驱动jar包
(2)定义配置文件
- 名称:c3p0.properties 或者 c3p0-config.xml
- 路径:直接将文件放在src目录下即可
(3)创建核心对象:数据库连接池对象ComboPooledDataSource
(4)获取连接: getConnection
配置文件
<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
<!-- 使用默认的配置读取连接池对象 -->
<default-config>
<!-- 连接参数 -->
<property name="driverClass">com.mysql.cj.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/shool?serverTimezone=CTT</property>
<property name="user">root</property>
<property name="password">123</property>c
<!-- 连接池参数 -->
<!--初始化申请的连接数量-->
<property name="initialPoolSize">5</property>
<!--最大的连接数量-->
<property name="maxPoolSize">10</property>
<!--超时时间-->
<property name="checkoutTimeout">3000</property>
</default-config>
<named-config name="otherc3p0">
<!-- 连接参数 -->
<property name="driverClass">com.mysql.cj.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/school?serverTimezone=CTT</property>
<property name="user">root</property>
<property name="password">123</property>
<!-- 连接池参数 -->
<property name="initialPoolSize">5</property>
<property name="maxPoolSize">8</property>
<property name="checkoutTimeout">1000</property>
</named-config>
</c3p0-config>
测试文件
public class C3P0_JDBCText {
public static void main(String[] args) throws SQLException {
//1.创建数据库连接池对
DataSource ds = new ComboPooledDataSource();
//2、获取连接对象
Connection connection = ds.getConnection();
//3、打印
System.out.println(connection);
for (int i = 0; i < 10; i++) {
Connection connection1 = ds.getConnection();
System.out.println(i + ":" + connection1);
}
}
}
6、Druid
实现步骤
(1)导入jar包 druid-1.0.9.jar
(2)定义配置文件
- 名称:是properties形式的
- 路径:可以叫任意名称,可以放在当前项目目录下
(3)加载配置文件:Properties
(4)获取数据库连接池对象:通过工厂来来获取 DruidDataSourceFactory
(5)获取连接:getConnection
配置文件
driverClassName=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/school?serverTimezone=CTT
username=root
password=123
#初始化数量
initialSize=5
#最大连接数
maxActive=10
#等待时间
maxWait=3000
连接类:
public class DruidJDBCText {
public static void main(String[] args) throws Exception {
//1、导入jar包
//2、定义配置文件
Properties pro=new Properties();
//3、加载配置文件
InputStream is=DruidJDBCText.class.getClassLoader().getResourceAsStream("druid.properties");
//
pro.load(is);
//4、获取连接池对象
DataSource ds= DruidDataSourceFactory.createDataSource(pro);
//获取连接
//Connection conn=ds.getConnection();
//System.out.println(conn);
for (int i = 0; i <8 ; i++) {
Connection conn=ds.getConnection();
System.out.println(i+":"+conn);
}
}
}
定义工具类
实现步骤
(1)定义一个类 JDBCUtils
(2)提供静态代码块加载配置文件,初始化连接池对象
(3)提供方法
- 获取连接方法:通过数据库连接池获取连接
- 获取连接池的方法
- 释放资源
工具类:
public class JDBCUtils1 {
private static DataSource ds;
static {
try {
Properties pro=new Properties();
InputStream is=JDBCUtils1.class.getClassLoader().getResourceAsStream("druid.properties");
pro.load(is);
ds = DruidDataSourceFactory.createDataSource(pro);
} catch (Exception e) {
e.printStackTrace();
}
}
//获取连接
public static Connection getConnection() throws SQLException {
return ds.getConnection();
}
//获取连接池方法
public static DataSource getDataSource(){
return ds;
}
//释放资源
public static void closeConnection(Statement stmt,Connection conn){
if (stmt!=null){
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (conn!=null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
//释放资源
public static void closeConnection(ResultSet rs,Statement stmt,Connection conn){
if (rs!=null){
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (stmt!=null){
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (conn!=null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
测试:
public class JDBCUtils1Test {
@Test
public void updateTest() throws SQLException {
Connection conn=JDBCUtils1.getConnection();
String sql="update bank set name='李' where id=2";
PreparedStatement ps=conn.prepareStatement(sql);
int i = ps.executeUpdate();
if (i==1){
System.out.println("修改数据成功!");
}
JDBCUtils1.closeConnection(ps,conn);
}
}
三、SpringJDBC
1、概念
Spring框架对JDBC的简单封装。提供了一个JDBCTemplate对象简化JDBC的开发。
2、实现数据库连接步骤
(1)导入jar包
(2)创建JdbcTemplate对象。依赖于数据源DataSource,即:在数据库连接池的工具类基础之上:
JdbcTemplate template = new JdbcTemplate(ds);
(3)调用JdbcTemplate的方法来完成CRUD的操作
* update():执行DML语句。增、删、改语句
* queryForMap():查询结果将结果集封装为map集合,将列名作为key,将值作为value 将这条记录封装为一个map集合
注意:这个方法查询的结果集长度只能是1
* queryForList():查询结果将结果集封装为list集合
注意:将每一条记录封装为一个Map集合,再将Map集合装载到List集合中
* query():查询结果,将结果封装为JavaBean对象
* query的参数:RowMapper
一般我们使用BeanPropertyRowMapper实现类。可以完成数据到JavaBean的自动封装
new BeanPropertyRowMapper<类型>(类型.class)
* queryForObject:查询结果,将结果封装为对象
一般用于聚合函数的查询
public class JDBCTemplateText {
//2.创建JDBCTemplate对象
private JdbcTemplate template=new JdbcTemplate(JDBCUtils1.getDataSource());
//修改数据
public void update() {
String sql="update stu set name=? where id=2";
//3、调用方法
int update = template.update(sql,"mm");
if (update==1){
System.out.println("数据修改成功");
}
}
//查询所有记录,将其封装为List;
@Test
public void query1(){
String sql="select * from teacher";
List<Map<String, Object>> list = template.queryForList(sql);
for (Map<String,Object> stringObjectMap:list){
System.out.println(stringObjectMap);
}
}
}