文章目录
JDBC概念
什么是jdbc
(1)Java Database Connectivity,java数据库连接
(2)java里面针对操作数据库,提供一套规范,好比是一些接口,比如操作mysql数据库,mysql提供这些接口实现类
(3)jdbc是java操作数据库一套规范(接口),由具体数据库提供这些规范实现,以jar包形式提供

基础操作 增删改查和连接
public class JDBCDemo1 {
@Test
//遍历数据库中的数据
public void testSelect(){
Connection connection=null;
Statement statement=null;
ResultSet resultSet=null;
try {
Class.forName("com.mysql.jdbc.Driver");
connection= DriverManager.getConnection("jdbc:mysql://localhost:3306/db1","root","root");
String sql="select id,name from worker";
statement=connection.createStatement();
resultSet = statement.executeQuery(sql);
while (resultSet.next()){
int id=resultSet.getInt("id");
String name = resultSet.getString("name");
System.out.println(id+" "+name);
}
} catch (Exception e) {
e.printStackTrace();
}finally {
try {
resultSet.close();
statement.close();
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
@Test
//添加数据进入数据库
public void testadd(){
try {
Class.forName("com.mysql.jdbc.Driver");
Connection conn=DriverManager.getConnection("jdbc:mysql:///db1","root","root");
String sql="INSERT INTO worker VALUES(NULL,'梁昕','女',500,NULL,3)";
Statement statement=conn.createStatement();
int i = statement.executeUpdate(sql);
System.out.println(i);
} catch (Exception e) {
e.printStackTrace();
}
}
@Test
//删除数据库中的数据
public void testdelete(){
try {
Class.forName("com.mysql.jdbc.Driver");
Connection conn=DriverManager.getConnection("jdbc:mysql:///db1","root","root");
Statement statement = conn.createStatement();
String sql="delete from worker where name='达到'";
int i = statement.executeUpdate(sql);
System.out.println(i);
} catch (Exception e) {
e.printStackTrace();
}
}
@Test
//修改数据库中的数据
public void testupdate(){
//其实反射来进行驱动,也可以不进行,因为在connection里面的静态代码块中 会有初始化
try {
Connection connection=DriverManager.getConnection("jdbc:mysql:///db1","root","root");
Statement statement = connection.createStatement();
String sql="update worker set id=6 where name='刘嘉明'";//UPDATE worker SET id=7 WHERE NAME='刘嘉明'
int i = statement.executeUpdate(sql);
System.out.println(i);
} catch (SQLException e) {
e.printStackTrace();
}
}
}
Statement对象
Statement对象主要作用执行sql语句的
Statement对象缺点
- sql语句拼接
String dname = "安保部";
String sql1 = "select * from dept where dname='安保部'";
String sql = "select * from dept where dname='"+dname+"'";
- sql注入问题:把输入值作为sql语句关键字执行了
- 不能处理Blob类型数据:Blob类型是二进制类型,使用Statement不能操作二进制类型数据
preparedstatement
为了解决上面statement的缺点,然后引入了preparedstatement
@Test //验证是否有这条信息的存在,并输出
public void test1(){
try {
Class.forName("com.mysql.jdbc.Driver");
Connection conn= DriverManager.getConnection("jdbc:mysql:///db1","root","root");
String sql="select *from worker where id=? and name=?";
PreparedStatement preparedStatement = conn.prepareStatement(sql);
preparedStatement.setInt(1,2);
preparedStatement.setString(2,"杨帆");
ResultSet resultSet = preparedStatement.executeQuery();
while (resultSet.next()){
int id=resultSet.getInt("id");
String name=resultSet.getString("name");
System.out.println(id+" "+name);
}
} catch (Exception e) {
e.printStackTrace();
}
}
String sql = "insert into dept values(?,?)";
//创建预编译对象
preparedStatement = conn.prepareStatement(sql);
//设置值
preparedStatement.setInt(1,100);
preparedStatement.setString(2,"互动部");
//执行sql
int row = preparedStatement.executeUpdate();
PreparedStatement获取自动增长的值
创建表,表id是主键,自动增长
//获取自动增长id值
@Test
public void test01() {
Connection conn = null;
PreparedStatement preparedStatement = null;
try {
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection("jdbc:mysql:///db2", "root", "root");
//编写sql语句
String sql = "insert into book values(null,?,?)";
//创建预编译对象
preparedStatement = conn.prepareStatement(sql,Statement.RETURN_GENERATED_KEYS);
//设置值
preparedStatement.setString(1,"上下五千年");
preparedStatement.setString(2,"无名氏");
//执行
preparedStatement.executeUpdate();
//获取添加之后自动增长id值
ResultSet rs = preparedStatement.getGeneratedKeys();
while(rs.next()) {
Object id = rs.getObject(1);
System.out.println(id);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
preparedStatement.close();
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
批处理操作
//批处理向表添加10条记录
@Test
public void test03() {
Connection conn = null;
PreparedStatement preparedStatement = null;
try {
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection("jdbc:mysql:///db2", "root", "root");
//编写sql语句
String sql = "insert into book values(null,?,?)";
//创建预编译对象
preparedStatement = conn.prepareStatement(sql);
//循环10次
for (int i = 1; i <=10; i++) {
preparedStatement.setString(1,"上下五千年2"+i);
preparedStatement.setString(2,"无名氏2"+i);
//把每次添加数据放到批处理对象
preparedStatement.addBatch();
}
//把批处理数据执行添加
preparedStatement.executeBatch();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
preparedStatement.close();
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
事务操作
//事务操作
@Test
public void test04() {
Connection conn = null;
PreparedStatement preparedStatement = null;
try {
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection("jdbc:mysql:///db2", "root", "root");
//1 开启事务(让事务不是自动提交)
conn.setAutoCommit(false);
//2 具体操作
//编写sql语句
String sql = "insert into book values(null,?,?)";
//创建预编译对象
preparedStatement = conn.prepareStatement(sql);
preparedStatement.setString(1,"世界旅游");
preparedStatement.setString(2,"无名氏");
preparedStatement.executeUpdate();
//3 事务结束 回滚和提交
conn.commit();
} catch (Exception e) {
e.printStackTrace();
//事务回滚
try {
conn.rollback();
} catch (SQLException e1) {
e1.printStackTrace();
}
} finally {
try {
preparedStatement.close();
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
数据库连接池

使用连接池,可以自己创建连接池,实现DataSource接口就可以了,但是实际操作中,一般不去自己实现,使用开源连接池进行使用,常用开源连接池:DBCP、C3P0、Druid(德鲁伊)
Druid连接池配置
将压缩包导入lib文件夹后,创建properties类型配置文件,设置数据库连接池信息
url=jdbc:mysql://localhost:3306/db2
username=root
password=root
driverClassName=com.mysql.jdbc.Driver
initialSize=10
maxActive=20
public static void main(String[] args) throws Exception {
Properties properties=new Properties();
// 通过类加载器读取路径内容
properties.load(DruidDemo1.class.getClassLoader().getResourceAsStream("db.properties"));
DataSource dataSource= DruidDataSourceFactory.createDataSource(properties);
Connection connection=dataSource.getConnection();
System.out.println(connection);
}
ThreadLocal
JDK 1.2的版本中提供java.lang.ThreadLocal,为解决多线程程序的并发问题提供了一种新的思路。使用这个工具类可以很简洁地编写出优美的多线程程序。
ThreadLocal用于保存某个线程共享变量,原因是在Java中,每一个线程对象中都有一个ThreadLocalMap<ThreadLocal, Object>,其key就是一个ThreadLocal,而Object即为该线程的共享变量。而这个map是通过ThreadLocal的set和get方法操作的。对于同一个static ThreadLocal,不同线程只能从中get,set,remove自己的变量,而不会影响其他线程的变量。
1、ThreadLocal.get: 获取ThreadLocal中当前线程共享变量的值。
2、ThreadLocal.set: 设置ThreadLocal中当前线程共享变量的值。
3、ThreadLocal.remove: 移除ThreadLocal中当前线程共享变量的值。
数据库连接池工具类
import com.alibaba.druid.pool.DruidDataSourceFactory;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;
public class JdbcUtils {
//定义成员变量
private static DataSource dataSource;
private static ThreadLocal<Connection> threadLocal;
//静态代码块
static {
try {
Properties properties=new Properties();
properties.load(JdbcUtils.class.getClassLoader().getResourceAsStream("db.properties"));
dataSource = DruidDataSourceFactory.createDataSource(properties);
//初始化threadLocal对象
threadLocal=new ThreadLocal<>();
} catch (Exception e) {
e.printStackTrace();
}
}
//获取数据库连接池连接
public static Connection getConneciton(){
Connection connection =threadLocal.get();
if(connection==null){
try {
connection=dataSource.getConnection();
threadLocal.set(connection);
} catch (SQLException e) {
e.printStackTrace();
}
}
return connection;
}
public static void closeResource(){
Connection connection=threadLocal.get();
if(connection!=null){
try {
connection.close();
threadLocal.remove();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
使用封装工具类
public class TestUtils {
public static void main(String[] args) {
PreparedStatement preparedStatement = null;
ResultSet rs = null;
try {
//获取数据库连接
Connection connection = JdbcUtils.getConnection();
String sql = "select * from dept";
preparedStatement = connection.prepareStatement(sql);
rs = preparedStatement.executeQuery();
while(rs.next()) {
System.out.println(rs.getString("dname"));
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
rs.close();
preparedStatement.close();
JdbcUtils.closeResource();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
DBUtils使用
Apache-DBUtils是针对jdbc封装的工具类,使用DBUtils简化jdbc开发代码,没有改变jdbc效率
导入DBUtils的jar包
增加、修改和删除
//删除操作
@Test
public void test03() throws Exception {
//创建QueryRunner对象
QueryRunner queryRunner = new QueryRunner();
// 编写sql语句
String sql = "delete from dept where did=?";
//调用方法执行sql
queryRunner.update(JdbcUtils.getConnection(),sql,200);
//释放资源
JdbcUtils.closeResource();
}
//修改操作
@Test
public void test02() throws Exception {
//创建QueryRunner对象
QueryRunner queryRunner = new QueryRunner();
// 编写sql语句
String sql = "update dept set dname=? where did=?";
//调用方法执行sql
queryRunner.update(JdbcUtils.getConnection(),sql,"研发测试部",200);
//释放资源
JdbcUtils.closeResource();
}
//添加操作
@Test
public void test01() throws Exception {
//创建QueryRunner对象
QueryRunner queryRunner = new QueryRunner();
// 编写sql语句
String sql = "insert into dept values(?,?)";
//调用方法执行sql
queryRunner.update(JdbcUtils.getConnection(),sql,200,"测试部");
//释放资源
JdbcUtils.closeResource();
}
查询操作
/查询操作-返回一条记录
@Test
public void test01() throws Exception {
//创建QueryRunner对象
QueryRunner runner = new QueryRunner();
//编写sql
String sql = "select * from dept where did=?";
//调用方法执行sql语句
Dept dept =
runner.query(JdbcUtils.getConnection(),sql,new BeanHandler<Dept>(Dept.class),1);
System.out.println(dept);
//释放资源
JdbcUtils.closeResource();
}
//查询操作-返回多条记录
@Test
public void test02() throws Exception {
QueryRunner runner = new QueryRunner();
String sql = "select * from dept";
List<Dept> list =
runner.query(JdbcUtils.getConnection(), sql, new BeanListHandler<Dept>(Dept.class));
System.out.println(list);
JdbcUtils.closeResource();
}