今天针对jdbc中的Blob类型,批处理,连接池进行了学习:
1.在MySQL中Blob这种数据类型可以操纵二进制对象,是一个可以存储大量数据的容器(图片、音乐、文件等)在MySQL中有四种Blob类型:
TinyBlob:最大能容纳255B的数据
Blob:最大能容纳65KB的数据;
MediumBlob:最大能容纳16MB的数据;
LongBlob:最大能容纳4GB的数据;
在安全性要求高的数据库中会选用Blob作为存储文件的载体
2.插入Blob数据:
java
public static void main(String[] args) throws Exception {
String sql = "insert into admin(name,photo)values(?,?)";
Class.forName("com.mysql.cj.jdbc.Driver");
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/jdbcdb?serverTimezone = Asia/Shanghai&useSSL=false", "root", "dzx123123");
PreparedStatement ps = conn.prepareStatement(sql);
ps.setString(1, "Sam");
FileInputStream fis =new FileInputStream("pp1.jpg");
ps.setBlob(2, fis);
ps.executeUpdate();
System.out.println("上传成功");
fis.close();
conn.close();
}
以输入流的形式传入
3.读取Blob文件:
java
public static void main(String[] args) throws Exception{
String url = "jdbc:mysql://localhost:3306/jdbcdb?serverTimezone=UTC&useSSL=false";
String username = "root";
String password = "dzx123123";
Class.forName("com.mysql.cj.jdbc.Driver");
Connection conn = DriverManager.getConnection(url, username, password);
PreparedStatement ps = conn.prepareStatement("select * from admin where id = 3");
ResultSet rs = ps.executeQuery();
if(rs.next()){
System.out.println(rs.getString(1));
System.out.println(rs.getString(2));
Blob blob= rs.getBlob(3);
try(InputStream is = blob.getBinaryStream(); FileOutputStream fos = new FileOutputStream("\\C:\\Users\\19184\\Desktop\\p1.jpg");){
byte[] buffer = new byte[1024];
int len;
while((len=is.read(buffer))!=-1){
fos.write(buffer,0,len);
}
fos.flush();
}
conn.close();
}
}
在结果集中以Blob形式读出来,然后把Blob转为流使用IO流进行操作;
4.jdbc批处理:
批处理:不是一个一个的处理要执行的语句,按批次去执行。当有十条sql语句要执行,一次向服务器发送一条sql去执行,效率是比较低的。处理的方案是使用批处理,一次向服务器发送多条sql语句,由服务器一次性处理。
既可以使用Statement也可以使用PreparedStatement进行批处理:
Statement在实现批处理时需要使用addBatch(String sql)方法传入sql语句,传入足够多了之后可以使用executeBatch()进行整体提交,中途还可以使用clearBatch()清空Batch中缓存的sql语句;
使用PreparedStatement在批处理的时候只需要设置好对应位置的参数然后使用addBatch()方法进行添加,再设置再添加...完成添加之后使用executeBatch进行提交,中途也可以使用clearBatch进行删除;
要注意mysql的jdbc驱动默认情况下,无视executeBatch()语句。希望使用批次执行,在url地址后面加入rewriteBatchedStatements=true设置;
必须将自动提交关闭,数据处理异常回滚时可保证提交前的操作处于同一事务,保证回滚成功;
5.数据库连接池:
是一个容器,持有多个数据库连接。当程序需要操作数据库的时候,直接可以从池中取出连接,使用完成之后,再放回到池中。
好处:
使用连接池可以节省系统资源,能够减少连接创建删除的开销,使响应更加高效;
统一管理数据库连接,避免因为业务膨胀,导致数据库连接过多;
对性能进行监控;
市面常见的连接池:
1.C3P0
2.DBCP(DataBase Connection Pool)
3.Druid(阿里开源)
4.HiKariCP
Druidd的使用:
java
public class TestDruid {
public static void main(String[] args) throws SQLException {
DruidDataSource dataSource=new DruidDataSource();
dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost:3306/test");
dataSource.setUsername("root");
dataSource.setPassword("root");
dataSource.setInitialSize(5);//连接池创建的时候,自动创建的数据库连接数量
dataSource.setMinIdle(10);//最小空闲连接
dataSource.setMaxActive(20);//最大同时激活的连接数量
dataSource.setMaxWait(6000);//最大等待时间。以毫秒为单位.-1表示无限等待
//dataSource.setMaxIdle();
Connection connection = dataSource.getConnection();
System.out.println(connection);
}
}
HiKariCP的使用:
java
public class TestHikariCP {
public static void main(String[] args) throws SQLException {
HikariDataSource dataSource=new HikariDataSource();
dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/test");
dataSource.setUsername("root");
dataSource.setPassword("root");
dataSource.setMinimumIdle(10);
Connection connection = dataSource.getConnection();
System.out.println(connection);
}
}