一、JDBC
全称: Java database connectivity java连接数据库
使用 Java 代码去连接数据库,然后对数据库中的数据进行增删改查。
#加载驱动
首先导入mysql的jar包:
1.在 src 文件夹下面新建一个 lib 文件
2.将下载好的 jar 包复制到 lib 文件夹下面
3.鼠标点上这个 jar 包,右键 add as Libaray
二、封装文件(mysql.propertises)
#封装数据库的主机、用户名、密码和驱动
url=jdbc:mysql://localhost:****/test?useSSL=false
user=root
password=123456
driver=com.mysql.jdbc.Driver
三、封装JdbcUtil类,获取connection对象、关闭资源
import java.io.FileInputStream;
import java.sql.*;
import java.util.Properties;
public class JdbcUtil {
//私有的静态变量
private static String url = null;
private static String user =null;
private static String password = null;
//只要JdbcUtil类加载了,就会执行静态代码块中的代码
static {
try {
//读取配置文件中的信息:properties文件
Properties properties = new Properties();
//Properties可以保存到流中或从流中加载,属性列表中的键及其对应的值都是字符串。
//数据都在properties 对象中
properties.load(new FileInputStream("src/db.properties"));
url = properties.getProperty("url");
user = properties.getProperty("user");
password = properties.getProperty("password");
String diver = properties.getProperty("driver");
Class.forName(diver);
} catch (Exception e) {
e.printStackTrace();
}
}
//获取连接数据库的connection对象
public static Connection getConnection () {
//成员变量
Connection connection = null;
try {
//获取connection对象
connection = DriverManager.getConnection(url, user, password);
} catch (SQLException e) {
e.printStackTrace();
}
return connection;
}
//关闭资源
public static void close (Connection connection) {
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
public static void close (Statement statement, Connection connection) {
try {
statement.close();
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
public static void close (ResultSet resultSet, Statement statement, Connection connection) {
try {
resultSet.close();
statement.close();
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
四、预处理的搬运工对象
Connection对象下面的方法:
//创建一个PreparedStatement对象,用于将参数化的SQL语句发送到数据库。
//例如添加数据
String sql = "insert into work (name, age, info) values(?, ?, ?)";
PreparedStatement preparedStatement = connection.prepareStatement(sql);
五、封装BaseDao类,增删改查
这个类对数据库的数据进行增删改查的方法进行了封装
import entity.Work;
import org.apache.commons.beanutils.BeanUtils;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
public class BaseDao {
//增加、删除、修改数据的方法
public int update(String sql, Object[] objects){
//通过JdbcUtil获取连接数据库的connection对象
Connection connection = JdbcUtil.getConnection();
PreparedStatement preparedStatement = null;
try {
//获取预处理的搬运工对象
preparedStatement = connection.prepareStatement(sql);
//获取预处理的搬运工对象的元数据对象
ParameterMetaData parameterMetaData = preparedStatement.getParameterMetaData();
获取预处理的搬运工对象的元数据对象的个数(参数型sql的?个数)
int parameterCount = parameterMetaData.getParameterCount();
//通过循环将objects数组的数据赋值给sql的参数
//此时数据在preparedStatement中
if (objects != null && objects.length == parameterCount) {
for (int i = 1; i <= parameterCount; i++) {
preparedStatement.setObject(i, objects[i - 1]);
}
}
//使用preparedStatement调用executeUpdate()方法添加数据
int i = preparedStatement.executeUpdate();
return i;
} catch (SQLException e) {
e.printStackTrace();
}finally {
//关闭资源
JdbcUtil.close(preparedStatement, connection);
}
return 0;
}
//查找数据的方法
public <T> List<T> Query(String sql, Object[] objects, Class<T> cls){
//通过JdbcUtil获取连接数据库的connection对象
Connection connection = JdbcUtil.getConnection();
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
try {
//获取预处理的搬运工对象
preparedStatement = connection.prepareStatement(sql);
//获取预处理的搬运工对象的元数据对象的个数(参数型sql的?个数)
int columnCount1 = preparedStatement.getParameterMetaData().getParameterCount();
//通过循环将objects数组的数据赋值给sql的参数
//此时数据在preparedStatement中
if (objects != null && objects.length == columnCount1){
for (int i = 1; i <= columnCount1; i++) {
preparedStatement.setObject(i, objects[i - 1]);
}
}
//声明一个数组,后面用数组对象存储查询到的值,然后输出
List<T> list = new ArrayList<>();
//查询生成一个ResultSet对象,其中包含查询产生的数据
resultSet = preparedStatement.executeQuery();
//获取结果集元数据
ResultSetMetaData metaData = resultSet.getMetaData();
//获取结果集元数据的列的个数(下面就是结果集元数据)
/**
*id name age info
* 1 张三 18 喜欢玩游戏
* 2 李四 22 喜欢打篮球
* 3 王五 24 喜欢唱跳Rap
* 4 老六 26 喜欢偷袭
* 5 赵七 28 喜欢散步
*/
int columnCount2 = metaData.getColumnCount();
//用过双层循环获取数据
//resultSet.next()有点像迭代器,也有光标,会随着循环下移
while(resultSet.next()){
//通过Class文件反射声明一个对象,用于存放数据
T t = cls.getConstructor(null).newInstance(null);
for (int i = 1; i <= columnCount2 ; i++) {
//在元数据中获取列的名字
String columnName = metaData.getColumnName(i);
//通过列的名字,用结果集获取该列的值
Object value = resultSet.getObject(columnName);
//通过BeanUtils的jar包下的setProperty(数组, 属性名, 值)方法插入数据
//使用BeanUtils需要插入beanutils和logging两个jar包
BeanUtils.setProperty(t, columnName, value);
}
//添加数据
list.add(t);
}
return list.size() != 0 ? list : null;
} catch (Exception e) {
e.printStackTrace();
}finally {
//关闭资源
JdbcUtil.close(resultSet, preparedStatement, connection);
}
return null;
}
}
六、连接池(重点)
为什么使用连接池。因为想要对数据进行增删改查,首先第一步先连接数据库,获取Connection对象。
如果每次进行增删改查的时候,都要先连接数据库,然后再关闭数据库。数据库压力比较大。
采用一种连接池,创建Connection对象以后,用完以后不要关闭资源,放到连接池中再用的时候从池子中取即可。
连接池属性包括:
驱动 url user password 池子有初始化的容量 最大的容量 等待时间
常见连接池:
1.C3P0 2.DBCP 3.Druid(德鲁伊)
6.1、封装druid.properties配置文件
public class Demo {
public static void main(String[] args) throws Exception {
//1.读取druid.properties
Properties properties = new Properties();
//2.以流的形式进行操作
properties.load(new FileInputStream("src/druid.properties"));
//3.创建Druid的核心类
//durid数据源的工厂
//dataSource 数据源工厂获取配置文件的的数据并赋值给数据源
DataSource dataSource = DruidDataSourceFactory.createDataSource(properties);
//4.获取连接数据库的对象
Connection connection = dataSource.getConnection();
System.out.println(connection);
}
}
6.2、改写JdbcUtil类,换成连接池的写法(主要代码)
public class JdbcUtil {
private static DataSource dataSource = null;
//只要JdbcUtil类加载了,就会执行静态代码块中的代码
static {
try {
//读取配置文件中的信息:properties文件
Properties properties = new Properties();
//Properties可以保存到流中或从流中加载,属性列表中的键及其对应的值都是字符串。
properties.load(new FileInputStream("src/druid.properties"));
//dataSource 数据源工厂获取配置文件的的数据并赋值给数据源
dataSource = DruidDataSourceFactory.createDataSource(properties);
} catch (Exception e) {
e.printStackTrace();
}
}
public static Connection getConnection () {
Connection connection = null;
try {
connection = dataSource.getConnection();
} catch (SQLException e) {
e.printStackTrace();
}
return connection;
}
七、JDBC中的事务
事务代码结构:
set autocommit = 0;
sql语句1
sql语句2
sql语句3
rollback; 回滚命令 or commit;执行命令
案例:
public class Demo1 {
public static void main(String[] args) {
Connection connection = JdbcUtil.getConnection();
try {
//关闭自动提交
connection.setAutoCommit(false);
String sql = "update user set balance = balance - 100 where id =?";
PreparedStatement preparedStatement = connection.prepareStatement(sql);
preparedStatement.setObject(1, 2);
preparedStatement.executeUpdate();
String sql1 = "update user set balance = balance + 100 where id =?";
PreparedStatement preparedStatement1 = connection.prepareStatement(sql1);
preparedStatement1.setObject(1, 1);
preparedStatement1.executeUpdate();
preparedStatement1.close();
//提交方法
connection.commit();
} catch (Exception e) {
try {
//事务中出现异常就回滚
connection.rollback();
} catch (SQLException ex) {
ex.printStackTrace();
}
}
}
}
八、DBUtils框架
轻量级持久层框架,就是对数据库的数据增删改查(CURD)。类似于咱们自己封装的BaseDao
首先要导包,导 dbUtils 的 jar 包
//核心代码
//增删改数据
public class Demo {
public static void main(String[] args) throws SQLException {
//dbutils这个框架是专门处理增删改查的
//1.连接数据库
Connection connection = JdbcUtil.getConnection();
//2.DBUtils核心类: QueryRunner
QueryRunner queryRunner = new QueryRunner();
String sql = "insert into person (name, age, info) values(?, ?, ?)";
int update = queryRunner.update(connection, sql, "周八", 30, "喜欢旅游");
System.out.println(update);
}
}
//查数据
public class Demo {
public static void main(String[] args) throws SQLException {
Connection connection = JdbcUtil.getConnection();
QueryRunner queryRunner = new QueryRunner();
String sql = "select * from work where id = ?";
Work work = queryRunner.query(connection, sql, 7, new ResultSetHandler<Work>() {
Work work1 = null;
@Override
public Work handle(ResultSet resultSet) throws SQLException {
while (resultSet.next()) {
int id = resultSet.getInt("id");
String name = resultSet.getString("name");
int age = resultSet.getInt("age");
String info = resultSet.getString("info");
work1 = new Work(id, name, age, info);
}
return work1;
}
});
System.out.println(work);
}
}