JDBC简介
JDBC:Java Database Connectivity–>Java和数据库的连接技术
是Sun公司推出的程序访问数据库的规范(接口),各个数据库厂商实现接口,提供数据驱动jar包,我们可以通过这套接口编程,但是真正执行的是驱动jar包中的类
环境准备
maven项目可以直接导入依赖:
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.21</version>
</dependency>
普通工程的步骤:
-
先下载MySQL的jar包点击下载
-
将jar包复制到项目的lib文件夹下(随便一个就行)
-
右键
lib
文件夹,点击Add as Library
快速入门
- 导入jar包(MySQL5版本之后的jar包可以省略这一步)
- 注册驱动
- 获取数据库连接对象 Connection
- 获取执行sql语句的对象 Statement
- 定义sql
- 执行sql,接受返回结果
- 处理结果并释放资源
public class JDBCTest {
public static void main(String[] args) throws Exception {
//注册驱动,MySQL5版本之后这句话可以不写了
Class.forName("mysql.mysql.jdbc.Driver");
//获取连接对象
String url = "jdbc:mysql://loaclhost:3306/dbname";
String username = "root";
String password = "123456";
Connection conn = DriverManager.getConnection(url,username,password);
//获取执行sql的对象,statement
Statement statement = conn.createStatement();
//定义sql,别忘了加分号
String sql = "update account set password=11111 where username=zhangsan;";
//执行sql
int count = statement.executeUpdate(sql);
//处理结果
System.out.println(count);
//释放资源
statement.close();
conn.close();
}
}
详解各个对象
DriverManager
驱动管理对象
- registerDriver()方法注册驱动,加载时静态代码块自动调用(MySQL5版本之后不用写了)
- getConnection()方法获取数据库连接,url、username、password
如果是本地的loaclhost还是3306端口号,这个url可以简化为jdbc:mysql:///dbname
Connection
数据库连接对象
- 获取执行sql的对象
Statement createStatement()
,执行静态sqlStatement prepareStatement(String sql)
,执行动态sql
- 管理事务
- 开启事务:
setAutoCommit(boolean autoCommit)
,设置参数为false即开启事务 - 提交事务:
commit()
- 回滚事务:
rollback()
- 开启事务:
Statement
执行sql的对象
-
boolean execute(String sql)
:可以执行任意sql,但是用的不多 -
int executeUpdate(String sql)
:执行DML(insert、update、delete)语句和DDL(库、表)语句- 返回值是受影响的行数,如果小于零则执行失败
-
ResultSet executeQuery(String sql)
:指定DQL(select)语句
ResultSet
结果集对象,封装查询的结果
- next():光标向下移动一行,有则获取下一行,没有则返回false
- getxxx(yyy):获取数据,xxx是数据类型,yyy是int时第几个(从1开始),yyy是String时是找某一列
ResultSet resultSet = statement.executeQuery(sql);
//和迭代器类似
while (resultSet.next()) {
int anInt = resultSet.getInt(1);
String id = resultSet.getString("id");
}
PreparedStatement
执行sql的对象,有时候使用字符串拼接会因为字段的特殊符号导致sql注入
用?
表示,作为占位符即可
String sql = "update account set password=? where username=?;";
PreparedStatement statement = conn.prepareStatement(sql);
statement.setString(0,"111");//表示第一个占位符
statement.setObject(1,2222);
statement.executeUpdate();
JDBC工具类
import java.sql.*;
public class JDBCUtils {
static Connection conn = null;
static String url;
static String username;
static String password;
//初始化
static {
//加载类
try {
Class.forName("mysql.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
//获取连接对象
try {
conn = DriverManager.getConnection(url,username,password);
} catch (SQLException e) {
e.printStackTrace();
}
}
public static Connection getConnection() throws Exception {
return conn;
};
public static void close() {
}
public static void close(ResultSet resultSet, Connection conn, Statement statement) throws Exception {
if (resultSet!=null) {
conn.close();
}
if (conn!=null) {
conn.close();
}
if (statement!=null) {
statement.close();
}
}
}
使用事务
我这个例子不是很合适了,因为只有一条sql,但是演示了使用事务的三个步骤
Connection conn = DriverManager.getConnection(url,username,password);
PreparedStatement statement = null;
//获取执行sql的对象,statement
try {
conn.setAutoCommit(false);
statement = conn.prepareStatement("update account set password=? where username=?;");
statement.setString(1,"xiaozhng");
statement.setString(1,"zhang");
//提交
conn.commit();
}catch (Exception e) {
//有问题回滚
conn.rollback();
} finally {
//释放资源
statement.close();
conn.close();
}
使用批处理
如果使用循环来做效率会很低
Connection conn = DriverManager.getConnection(url,username,password);
conn.setAutoCommit(false);
PreparedStatement statement = conn.prepareStatement("update account set password=? where username=?;");
for (int i = 0; i < 50000; i++) {
statement.setString(1,"xiaozhng");
statement.setString(1,"zhang");
statement.addBatch();//添加批处理
if (i%1000==0) {
statement.executeBatch();
statement.clearBatch();
}
}
二进制类型数据的读写
写入:
Connection conn = DriverManager.getConnection(url,username,password);
conn.setAutoCommit(false);
PreparedStatement statement = conn.prepareStatement("update user set photo=? where id=1;");
statement.setBlob(1,new FileInputStream("path"));
statement.executeUpdate();
读取:
ResultSet resultSet = statement.executeQuery();
while (resultSet.next()) {
InputStream inputStream = resultSet.getBinaryStream("photo");
FileOutputStream fos = new FileOutputStream("path");
int len;
byte[] bytes = new byte[1024];
while ((len=inputStream.read(bytes))!=-1) {
fos.write(bytes,0,len);
}
}
DBUtils的使用
是apache的开源框架,简化了JDBC的开发步骤,使得我们可以用更少量的代码实现连接数据库的功能,最厉害的是返回值可以直接指定,单个值,列表,Bean,BeanList…,maven页
- query可以增删查数据
- update可以修改数据
ResultSetHandler结果集处理类:
- ArrayHandler 将结果集中的第一条记录封装到一个Object[]数组中:new ArrayHandler()
- ArrayListHandler 将结果集中的每一条记录都封装到一个Object[]数组中:new ArrayListHandler()
- BeanHandler 将结果集中第一条记录封装到一个指定的类中:new BeanHandler(Sort.class)
- BeanListHandler 将结果集中每一条记录封装到指定的自定义类中,将这些类在封装到List集合中:new BeanListHandler<自定义类>(类名.class)
- ColumnListHandler 将结果集中指定的列的字段值,封装到一个List集合中:new ColumnListHandler(“字段名”)
- ScalarHandler 它是用于单数据。例如select count(*) from 表操作。:new ScalarHandler()
- MapHandler 将结果集第一行封装到Map<String,Object>集合中,Key 列名, Value 该列数据
- MapListHandler 将结果集每一行封装到List<Map<String,Object>>集合中,Key 列名, Value 该列数据,Map集合存储到List集合
public class DBUtilsTest {
public static void main(String[] args) throws Exception {
Connection connection = JDBCUtils.getConnection();
QueryRunner qr = new QueryRunner();
//查询单个值
Object query = qr.query(connection, "select count(*) from user;", new ScalarHandler<>());
//查询一个Bean,BeanListHandler<>()是Bean列表
Map query1 = qr.query(connection,"select * from admin where id=?", new BeanHandler<>(Map.class), 1);
//修改数据
int result = qr.update(connection,"update from user set password=? where id=?","123");
}
}
druid(德鲁伊)连接池技术
用户每次来不会向系统申请,而是去连接池中使用访问对象,用完再还回来,能节约时间还提高利用率
spring:
datasource:
url: jdbc:mysql://127.0.0.1:3306/test_go?characterEncoding=UTF-8&useSSL=false
username: xxx
password: xxxxxx
driver-class-name: com.mysql.jdbc.Driver
type: com.alibaba.druid.pool.DruidDataSource
druid:
initial-size: 5
min-idle: 5
max-active: 20
test-while-idle: true
test-on-borrow: false
test-on-return: false
pool-prepared-statements: true
max-pool-prepared-statement-per-connection-size: 20
max-wait: 60000
time-between-eviction-runs-millis: 60000
min-evictable-idle-time-millis: 30000
filters: stat
async-init: true
public ResultResponse testDruid() {
String sql = "SELECT mobile FROM user WHERE id = ?";
String mobile = jdbcTemplate.queryForObject(sql, new Object[]{
1}, String.class);
return new ResultResponse(201, "hey" + mobile);
}
唉就到这吧,,,等后面直接学Spring Boot整合得了