在创建连接的两种方式中,DriverManager方式是创建的短链接,使用完就关闭了,效率比较低,因此,我们此处主要说一下数据源(DataSource)方式的使用步骤。
1.DataSource方式操作步骤:
- 创建数据库连接Connection(长连接)
- 创建操作命令Statement(创建Statement对象来操作SQL)
- 使用操作命令来执行SQL(调用Statement对象中的方法来执行SQL语句)
- 处理结果集ResultSet(如果执行的是查询操作返回的就是ResultSet对象;其他三个更新操作(插入、删除、更新)都是返回int)
ResultSet对象里边保存的东西可以理解为键值对类型,也就是map的键就是表头的列名,值就是通过表头列名获取到的值 - 释放资源
2.使用单例模式封装mysql建立连接和关闭资源接口:
单例模式使用双重校验锁保证线程安全,具体的单例模式将在后面的博客写出
代码:
//获取数据库链接url===>包含数据库地址、名字等
private static final String URL="jdbc:mysql://localhost:3306/JAVA_IMAGE_SERVER?characterEncoding=utf-8";
private static final String USER="root";
private static final String PASSWORD="";
private static volatile DataSource DS;
//1.数据库连接的单例模式:调用该方法获取到唯一的连接池对象
private static DataSource getDataSource(){
if(DS==null)
{
synchronized (DBUtil.class)
{
if(DS==null)
{
//多态:new MySQL的对象,父类引用指向子类对象
DS=new MysqlDataSource();
//jdbc原生提供的DataSource没有设置url等方法,需要将其强制转换
((MysqlDataSource) DS).setUrl(URL);
((MysqlDataSource) DS).setUser(USERNAME);
((MysqlDataSource) DS).setPassword(PASSSWORD);
}
}
}
return DS;
}
//设计外部的方法来建立连接
public static java.sql.Connection getConnection(){
try {
return getDataSource().getConnection();
} catch (SQLException e) {
throw new SystemException("000","获取数据库连接失败",e);
}
}
//插入/修改/删除不需要ResultSet对象
public static void close(java.sql.Connection connection, Statement statement)
{
//调用下面close方法,第三个参数传null
close(connection,statement,null);
}
//释放资源属于MySQL服务请求(请求数据包,响应数据包),属于网络IO的部分---》网络IO都要释放资源
public static void close(java.sql.Connection connection, Statement statement, ResultSet resultSet)
{
//ResultSet在查询操作的时候才有该对象,插入和删除就没有
try {
//调用一些IO类都有可能抛出编译时异常,所以我们需要处理这些异常
if(resultSet!=null)
{
resultSet.close();
}
if(statement!=null)
{
statement.close();
}
if(connection!=null)
{
connection.close();
}
} catch (SQLException e) {
throw new SystemException("000","释放数据库资源失败",e);
}
}
3.以查询为例,来实现JDBC的操作步骤(5步):
public static List<Article> list() {
//1,创建连接
Connection c=DBUtil.getConnection();
//2,创建Stament对象:SQL语句操作对象
PreparedStatement p=null;
ResultSet resultSet=null; //创建查询结果集对象
String sql="select id,title,content,user_id,create_time from article";//SQL语句
try {
List<Article> articles=new ArrayList<>();
// 3. 使用操作命令来执行SQL
p=c.prepareStatement(sql);
//4. 处理结果集ResultSet
//主要是executeQuery,executeUpdate这两个方法
//如果p是Statement,sql要传入
//如果p是prepareStatement,sql不需要传入(无参构造)
resultSet=p.executeQuery();
//遍历结果集
while (resultSet.next())
{
Article article=new Article();
article.setId(resultSet.getInt("id"));
article.setTitle(resultSet.getString("title"));
article.setContent(resultSet.getString("content"));
article.setUserId(resultSet.getInt("user_id"));
//article文章类定义的是java.util.Data,从数据库中取的是java.sql.Data,所以需要类型转换
//Date只接受long类型的字段,所以.getTime()将从数据库查询出来的Data转为毫秒数传入java.util.Data类型就可以使用了
article.setCreateTime(new Date(resultSet.getTimestamp("create_time").getTime()));
articles.add(article);
}
return articles;
} catch (SQLException e) {
throw new SystemException("001","查询文章出错",e);
} finally {
//5. 释放资源
DBUtil.close(c,p,resultSet);
}
}