一、JDBC快速入门
1、jdbc的概念
JDBC(Java DataBase Connectivity,java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系型数据库提供统一访问,它是由一组用Java语言编写的类和接口组成的。
2、jdbc的本质
其实就是java官方提供的一套规范(接口)。用于帮助开发人员快速实现不同关系型数据库的连接!
3、jdbc的入门程序
1、导入jar包
(MySQL :: Download MySQL Connector/J (Archived Versions))选择与你mysql版本一致的win+r 输入mysql -V查看mysql版本
2、注册驱动
//5以上的jar加上cj
Class.forName("com.mysql.cj.jdbc.Driver");
3、获取连接
//获取数据库路径ip端口数据库名称
String url = "jdbc:mysql://127.0.0.1:3306/wu";
String name = "root";
String password = "root";
//3、获取连接 DriverManager:驱动管理对象 Connection:数据库连接对象
Connection connection = DriverManager.getConnection(url, name, password);
4、获取执行者对象
//4、获取执行者对象 获取普通执行者对象:createStatement();
// 获取预编译执行者对象: prepareStatement(String sql);
Statement stat = connection.createStatement();
5、执行sql语句并接收返回结果
//5、执行sql语句 (添加)
//String sql = "insert into user values (null,'张小凡','男',19,3)";
//删除
//String sql = "delete from user where sid = 3";
//修改
//String sql = "update stu set name='碧瑶' where id=3";
//6、获取影响的行数 executeUpdate()修改添加删除
//int i = stat.executeUpdate(sql);
//5、执行sql语句
String sql = "select * from user";
//返回结果集 executeQuery()查询
ResultSet resultSet = stat.executeQuery(sql);
6、处理结果
//6、处理结果 判断有没有下一行数据
while (resultSet.next()){
System.out.println(resultSet.getInt("id")+"\t"+
resultSet.getString("name")+"\t"+
resultSet.getString("sex")+"\t"+
resultSet.getInt("age")+"\t"+
resultSet.getInt("sid"));
}
7、关闭资源
//7、释放资源
connection.close();
stat.close();
resultSet.close();
二、JDBC功能类详解
1、DriverManager
DriverManager:驱动管理对象
-
注册驱动(告诉程序该使用哪一个数据库驱动)
-
static void registerDriver(Driver driver):注册与给定的驱动程序 DriverManager
-
写代码使用:Class.forName("com.mysql.jdbc.Driver");
-
通过查看源码发现:在com.mysql.jdbc.Driver类中存在静态代码块
-
注意:mysql5之后的驱动jar包可以省略注册驱动的步骤。在jar包中,存在一个java.sql.Driver配置文件,文件中指定了com.mysql.jdbc.Driver
-
2、getConnection()
getConnection() :获取数据库连接(获取到数据库的连接并返回连接对象
Connection数据库连接对象
参数:url:指定连接的路径。语法:jdbc:mysql://ip地址(域名):端口号/数据库名称 ,user:用户名,password:密码
3、Connection
Connection:数据库连接对象
获取执行者对象 :1、获取普通执行者对象:Statement createStatement();
2、获取预编译执行者对象:PreparedStatement prepareStatement(String sql);
4、 管理事务:
1、开启事务:setAutoCommit(boolean autoCommit); 参数为false,则开启事务。 2、提交事务:commit(); 3、回滚事务:rollback();
释放资源:立即将数据库连接对象释放:void close();
5、Statement:
Statement():执行sql语句的对象
1、执行DML语句:int executeUpdate(String sql);
1、返回值int:返回影响的行数。
2、参数sql:可以执行insert、update、delete语句。
2、执行DQL语句:ResultSet executeQuery(String sql);
1、返回值ResultSet:封装查询的结果 。
2、参数sql:可以执行select语句。
3、释放资源 :立即将执行者对象释放:void close();
6、ResultSet()
ResultSet:结果集对象
1、判断结果集中是否还有数据:boolean next();
1、有数据返回true,并将索引向下移动一行
2、没有数据返回false
2、获取结果集中的数据:XXX getXxx("列名");
1、XXX代表数据类型(要获取某列数据,这一列的数据类型)
3、释放资源
1、立即将结果集对象释放:void close();
三、完整JDBC代码
package com.jdbc;
import java.sql.*;
/**
* @author 86136
*/
public class Test01 {
public static void main(String[] args) throws Exception {
//1、导入jar包
//2、注册驱动
Class.forName("com.mysql.cj.jdbc.Driver");
//3、获取连接
//获取数据ip和数据库端口,数据库名称
String url = "jdbc:mysql://127.0.0.1:3306/wu";
//数据库用户
String name = "root";
//数据库密码
String password = "root";
Connection connection = DriverManager.getConnection(url, name, password);
//4、获取执行者对象
Statement statement = connection.createStatement();
//5、执行sql语句
String sql = "select * from user";
//返回结果集 executeQuery()查询
ResultSet resultSet = statement.executeQuery(sql);
//executeUpdate()修改,删除,添加
//int i = statement.executeUpdate(sql);
//6、处理结果 判断有没有下一行数据
while (resultSet.next()){
System.out.println(resultSet.getInt("id")+"\t"+
resultSet.getString("name")+"\t"+
resultSet.getString("sex")+"\t"+
resultSet.getInt("age")+"\t"+
resultSet.getInt("sid"));
}
//7、释放资源
connection.close();
statement.close();
resultSet.close();
}
}
四、JDBC工具类
1、工具类的配置文件
//在src下创建文件.properties driverClass=com.mysql.cj.jdbc.Driver url=jdbc:mysql://127.0.0.1:3306/wu username=root password=root
2、JDBC工具类
package com.utils;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;
/**
* @author 86136
*/
public class JdbcUtils {
//1、构建私有方法
private JdbcUtils() {};
//2、声明配置信息变量
private static String driverClass;
private static String url;
private static String username;
private static String password;
private static Connection con;
//3、静态代码块中实现加载配置文件和注册驱动
static {
try {
//1、通过类加载器返回配置文件的字节流
InputStream input = JdbcUtils.class.getClassLoader().getResourceAsStream("config.properties");
//2、创建properties集合,加载流对象的信息
Properties proper = new Properties();
proper.load(input);
//3、获取信息为变量赋值
driverClass = proper.getProperty("driverClass");
url = proper.getProperty("url");
username = proper.getProperty("username");
password = proper.getProperty("password");
//4、注册驱动
Class.forName(driverClass);
} catch (Exception e) {
e.printStackTrace();
}
}
//5、获取数据库连接的方法
public static Connection getConnection() {
try {
con = DriverManager.getConnection(url, username, password);
} catch (SQLException e) {
e.printStackTrace();
}
return con;
}
//6、释放资源的方法
public static void close(Connection con, Statement stat, ResultSet rs){
if (con != null) {
try {
con.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if (stat != null) {
try {
stat.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if (rs != null) {
try {
rs.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
public static void close(Connection con,Statement stat) {
close(con,stat, null);
}
}
五、JDBC的简化代码
package com.jdbc;
import com.utils.JdbcUtils;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
/**
* @author 86136
*/
public class Test03 {
public static void main(String[] args) throws SQLException {
//工具类获取连接
Connection connection = JdbcUtils.getConnection();
//获取执行者对象
Statement stat = connection.createStatement();
//执行sql
String sql = "insert into user values (null,'桐人','男',15,4)";
int i = stat.executeUpdate(sql);
//返回影响的行数
System.out.println("i = " + i);
//关闭资源
JdbcUtils.close(connection,stat);
}
}
六、转账
package com.jdbc;
import com.utlis.JdbcUtils;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
/**
* @author 86136
*/
public class Money {
public static void main(String[] args) throws SQLException {
Connection conn = JdbcUtils.getConnection();
//在转钱前开启事务(关闭自动提交)
conn.setAutoCommit(false);
try {
String sql = "update moeny set money = money-500 where name=?";
PreparedStatement statement = conn.prepareStatement(sql);
statement.setString(1,"叶修");
statement.executeUpdate();
statement.close();
//假如转账出现错误
int a = 1/0;
String sql2 = "update moeny set money = money+500 where name=?";
PreparedStatement statement2 = conn.prepareStatement(sql2);
statement2.setString(1,"叶秋");
statement2.executeUpdate();
statement2.close();
//能执行到这里就代表正常执行,就提交到数据库
conn.commit();
} catch (SQLException throwables) {
//执行到这里就说明出现问题了,就回滚到开启事务点
conn.rollback();
throwables.printStackTrace();
}
conn.close();
}
}
七、数据库连接池
1、概念:
概念:其实就是一个容器(集合),存放数据库连接的容器。
当系统初始化好后,容器被创建,容器中会申请一些连接对象,当用户来访问数据库时,从容器中获取连接对象,用户访问完之后,会将连接对象归还给容器。
2、好处
1. 节约资源
2. 用户访问高效
3、实现
1. 标准接口:DataSource javax.sql包下的
1. 方法:
* 获取连接:getConnection()
* 归还连接:Connection.close()。如果连接对象Connection是从连接池中获取的,那么调用Connection.close()方法,则不会再关闭连接了。而是归还连接
4、数据库连接池有:
1、C3P0:数据库连接池技术 2、Druid:数据库连接池实现技术,由阿里巴巴提供的
5、C3P0:数据库连接池技术
5.1、步骤
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
5.2、代码:
//1.创建数据库连接池对象
DataSource ds = new ComboPooledDataSource();
//2. 获取连接对象
Connection conn = ds.getConnection();
6、Druid:数据库连接池实现技术,由阿里巴巴提供的
6.1、步骤:
1、导入jar包 druid-1.2.20.jar(和你的mysql版本不要相差太大不然会报错的,我亲自试过)
2、定义配置文件:是properties形式的
3、加载配置文件。后缀名为:properties
driverClass=com.mysql.cj.jdbc.Driver url=jdbc:mysql://127.0.0.1:3306/wu username=root password=root # 连接池的最大初始连接量 maxSize=5 # 最大连接数 maxActive=10 # 最大等待时间 maxWait=3000
4、获取数据库连接池对象:通过工厂来来获取 DruidDataSourceFactory
5、获取连接:getConnection
6.2、定义一个工具类
1、定义一个类 JDBCUtils
2、提供静态代码块加载配置文件,初始化连接池对象
3、提供方法:1、获取连接方法:通过数据库连接池获取连接 2、释放资源 3、获取连接池的方法
6.3、代码:
package com.utlis;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import javax.sql.DataSource;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
/**
* @author 86136
*/
//读取配置文件,初始化连接池,从连接池中获取连接
public class JdbcUtils2 {
//数据源/连接池
private static DataSource ds;
static {
try {
//读取配置文件
InputStream stream = JdbcUtils2.class.getClassLoader().getResourceAsStream("jdbc.properties");
//加载读取流
Properties pro = new Properties();
pro.load(stream);
//根据Properties创建数据源
ds = DruidDataSourceFactory.createDataSource(pro);
} catch (Exception e) {
e.printStackTrace();
}
}
public static DataSource getDataSource() {
return ds;
}
public static Connection getConnection(){
try {
return ds.getConnection();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
return null;
}
public static void close(Connection conn, Statement stmt) {
if (conn != null) {
try {
conn.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if (stmt != null) {
try {
stmt.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
public static void close(Connection conn, Statement stmt, ResultSet rs) {
close(conn,stmt);
if (rs != null) {
try {
rs.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
}
八、测试
package com.jdbc;
import com.pojo.Stu;
import com.utlis.JdbcUtils2;
import org.junit.jupiter.api.Test;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import java.util.List;
import java.util.Map;
/**
* @author 86136
*/
public class Test02 {
//创建JdbcTemplate
private JdbcTemplate jdbcTemplate = new JdbcTemplate(JdbcUtils2.getDataSource());
//添加数据
@Test
public void addTest() {
//编写SQL语句
String sql = "insert into stu values (null,?,?,?)";
//执行sql。传入参数
int i = jdbcTemplate.update(sql, "毛利兰", 18, "女孩");
System.out.println("i = " + i);
}
//删除
@Test
public void deleteTest() {
String sql = "delete from stu where id = ?";
int i = jdbcTemplate.update(sql, 5);
System.out.println("i = " + i);
}
//修改
@Test
public void updateTest() {
String sql = "update stu set name=? where id=?";
int i = jdbcTemplate.update(sql, "陆雪琪", 3);
System.out.println("i = " + i);
}
//查询多条数据,将查询到的数据封装进对象,存入list集合
@Test
public void listTest(){
String sql = "select * from stu where age=?";
List<Stu> query = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(Stu.class), 19);
for (Stu stu : query) {
System.out.println(stu);
}
}
//查询单条数据,以map集合形式返回 --结果只能是1条,0条或多条会报错
@Test
public void mapTest() {
String sql = "select * from stu where name = ?";
Map<String, Object> map = jdbcTemplate.queryForMap(sql, "苏沐橙");
System.out.println("map = " + map);
}
//查询多条数据,以list嵌套map集合形式返回
@Test
public void mapListTest(){
String sql ="select * from stu where sex = ?";
List<Map<String, Object>> maps = jdbcTemplate.queryForList(sql, "女孩");
for (Map<String, Object> map : maps) {
System.out.println(maps);
}
}
//用于聚合函数或者单值的查询
@Test
public void test04() {
String sql = "select avg(age) from stu";
Double aDouble = jdbcTemplate.queryForObject(sql, Double.class);
System.out.println("aDouble = " + aDouble);
}
//用于查询单个字段,但是多值
@Test
public void test05(){
String sql = "select name from stu";
List<String> strings = jdbcTemplate.queryForList(sql, String.class);
System.out.println("strings = " + strings);
}
}