JDBC核心技术
JDBC的理解:是Java厂商提供的一套API,使用这套API可以实现对具体数据库的操作(获取连接,关闭连接,DML,DDL,DCL等)。
获取数据库的连接
利用数据库连接池技术:
Druid(德鲁伊)是阿里提供的数据库连接池
1,导入jar包
2,填写配置文件(MySQL版本:8.0)
其他配置详解百度
3,获取连接
//创建用来处理配置文件的Properties
Properties pros=new Properties();
//利用类的加载器获取配置文件
InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream("druid.properties");
//利用Druid的工厂类创建连接池
DataSource source = DruidDataSourceFactory.createDataSource(pros);
//获取连接
Connection connection = source.getConnection();
//还有要关闭资源及处理异常
4,关闭连接
根据jar包的版本,提供相应的关闭方法
//直接调用工具类方法关闭连接
DbUtils.closeQuietly(conn,ps,rs);
//conn为连接,ps为预编译,rs为结果集
通用的增删改查操作
实现方式:
1,手写PreparedStatement实现
2,使用dbutils.jar中QueryRunner类
此处用2演示
①增删改,调用update方法
Connection connection = null;
try {
//创建QueryRunner类
QueryRunner runner = new QueryRunner();
//获取连接,此处用已封装的工具类实现
connection = JDBCUtils.getConnection();
//预编译sql语句
String sql="insert into customers(name,email,birth) values(?,?,?)";
//调用QueryRunner类的update方法实现数据的增删改操作
int insertCount = runner.update(connection, sql, "蔡徐坤", "caixukun@126.com", "1997-9-8");
System.out.println("添加了"+insertCount+"条记录");
} catch (SQLException throwables) {
throwables.printStackTrace();
} finally {
//关闭资源
Util.JDBCUtils.closeResource(connection,null);
}
②查询,调用query方法
查询分为查询一条与查询多条记录,还要特殊需求的查询,区别在于提供不同的实现类,返回内容不一样。
查询一条记录
//BeanHandler:是ResultSetHandler接口的实现类,用于封装表中的一条记录
@Test//查询一条记录
public void testQuery1(){
//获取连接
Connection connection = null;
try {
//创建QueryRunner
QueryRunner runner = new QueryRunner();
connection = JDBCUtils.getConnection();
// 预编译sql语句
String sql="select id,name,email,birth from customers where id=?";
//创建结果集的处理器,此处的泛型写该表对应的类
BeanHandler<Customer> handler = new BeanHandler<>(Customer.class);
//调用query方法,返回查询到的结果集,生成相应的对象
Customer customer = runner.query(connection, sql, handler, 14);
System.out.println(customer);
} catch (SQLException throwables) {
throwables.printStackTrace();
} finally {
Util.JDBCUtils.closeResource(connection,null);
}
}
查询多条记录
@Test//查询多条记录
public void testQuery2(){
Connection connection = null;
try {
QueryRunner runner = new QueryRunner();
connection = JDBCUtils.getConnection();
String sql="select id,name,email,birth from customers where id<=?";
BeanListHandler<Customer> handler = new BeanListHandler<>(Customer.class);
//返回一个集合
List<Customer> list = runner.query(connection, sql, handler, 15);
list.forEach(System.out::println);
} catch (SQLException throwables) {
throwables.printStackTrace();
} finally {
Util.JDBCUtils.closeResource(connection,null);
}
}
其他常用的结果集处理器还有MapHandler,MapListHandler,详见百度
特殊需求的查询
//ScalarHandler:针对特殊操作的查询
@Test//查表的总数
public void testQuery5(){
Connection connection = null;
try {
QueryRunner runner = new QueryRunner();
connection = JDBCUtils.getConnection();
String sql="select count(*) from customers";
ScalarHandler handler = new ScalarHandler();
Long count= (Long) runner.query(connection, sql, handler);
System.out.println(count);
} catch (SQLException throwables) {
throwables.printStackTrace();
} finally {
Util.JDBCUtils.closeResource(connection,null);
}
}
关闭资源
方式一:手动关闭资源
方式二:DbUtils类提供的关闭方法
补充
对于事务,需要取消数据的自动提交,一组逻辑操作单元共用一个数据库连接,所以需要自己提供连接
//1,取消数据的自动提交
connection.setAutoCommit(false);
一组逻辑操作单元结束后,提交数据
//2,提交数据
connection.commit();
如出现异常,需要回滚数据
//3,回滚数据
try {
connection.rollback();
} catch (SQLException e1) {
e1.printStackTrace();
}
对于数据库连接池,用完改连接后,需要将连接改回默认状态
try {
//修改自动提交为true,主要针对于数据库连接池
connection.setAutoCommit(true);
} catch (SQLException throwables) {
throwables.printStackTrace();
}
对于事物的隔离级别,可手动设置,详见百度
对于**Blob数据类型,**添加及获取需要用到流的操作,并且如需要改变Blob数据库默认最大容量的大小,修改之后需要重启数据库
添加
//向数据表customers中添加blob类型的字段
@Test
public void testInsert() throws Exception {
Connection conn = JDBCUtils.getConnection();
String sql="insert into customers(name,email,birth,photo) values(?,?,?,?)";
PreparedStatement ps = conn.prepareStatement(sql);
ps.setObject(1,"广西");
ps.setObject(2,"gx@163.com");
ps.setObject(3,"1900-3-8");
//以流的方式
FileInputStream is = new FileInputStream(new File("E:\\pictureVideo\\guangxi.jpg"));
ps.setBlob(4,is);
ps.execute();
is.close();
JDBCUtils.closeResource(conn,ps);
}
获取
//查询数据表customers中的blob类型的字段
@Test
public void testQuery() {
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
InputStream is=null;
FileOutputStream fos=null;
try {
conn = JDBCUtils.getConnection();
String sql="select id,name,email,birth,photo from customers where id=?";
ps = conn.prepareStatement(sql);
ps.setObject(1,15);
rs = ps.executeQuery();
if (rs.next()){
int id = rs.getInt("id");
String name = rs.getString("name");
String email = rs.getString("email");
Date birth = rs.getDate("birth");
Customer customer = new Customer(id, name, email, birth);
System.out.println(customer);
//将Blob类型的字段下载下来,以文件的方式保存在本地
Blob photo = rs.getBlob("photo");
is = photo.getBinaryStream();//获取二进制流
fos = new FileOutputStream("E:\\JDBCDemo\\src\\copyts.jpg");
byte[] buffer = new byte[1024];
int len;
while ((len=is.read(buffer))!=-1){
fos.write(buffer,0,len
);
}
}
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException throwables) {
throwables.printStackTrace();
} finally {
if (fos!=null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (is!=null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
JDBCUtils.closeResource(conn,ps,rs);
}
}
注:根据实际情况,异常处理需要选择相应的处理方式,MySQL8版本配置文件需要加入时区参数,详见百度,欢迎补充。