接上篇
一、数据库连接:
相关概念:
数据库连接池:
数据库连接池负责分配、管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个,释放空闲时间超过最大空闲时间的数据库连接来避免因为没有释放数据库连接而引起的数据库连接遗漏。
理解:数据库连接池是基于享元模式,可以重复使用资源,在初始化的时候就创建多个,每次使用完之后再还原,所有使用者共享资源,不用每次都创建资源,可以用于提高性能
获取Connection的方法:
- 通过DriverManager(驱动管理类)的静态方法获取
//加载jdbc驱动程序
Class.forName("com.mysql.jdbc.Driver");
//创建数据库连接
Connection connection = DriverManger.getConnection(url);
- 通过DataSource(数据源)对象获取,实际中会使用DataSource对象
DataSource ds = new MysqlDataSource();
((MysqlDataSource) ds).setUrl("jdbc:mysql://localhost:3306/test");
((MysqlDataSource) ds).setUser("root");
((MysqlDataSource) ds).setPassword("root");
Connection connection = ds.getConnection();
区别:
1.DriverManager类来获取的Connection连接,是无法重复利用的,每次使用完以后释放资源时,通过connection.close()都是关闭物理连接
2. DataSource提供连接池的支持。连接池在初始化时将创建一定数量的数据库连接,这些连接可以复用,每次使用完数据库连接,释放资源调用connection.close()都是将Conncetion连接对象回收,回收时将重置connection对象的属性—>效率较高
例:使用DataSource创建数据库连接(更改)
//不需要加载驱动了,直接new MysqlDataSource();
//Class.forName("com.mysql.jdbc.Driver");//类加载
//1.创建数据库连接
//URL:网址,连接自己Mysql,password为自己的密码
//数据库连接池 使用DataSource
MysqlDataSource ds = new MysqlDataSource();
ds.setUrl("jdbc:mysql://localhost:3306/test?user=root&password=102917&useUnicode=true&characterEncoding=UTF-8&useSSL=false");
connection = ds.getConnection();
System.out.println(connection);
//connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/test?user=root&password=102917&useUnicode=true&characterEncoding=UTF-8&useSSL=false");
//System.out.println(connection);
2.statement对象:主要是将SQL语句发送到数据库中。
使用Statement接口对象发送的sql语句需要在数据库中进行一次编译之后成为指令才能执行,每条sql语句都需要编译一次,这样很慢,可以使用PreparedStatement接口改善。
JDBC API中提供了三种Statement对象:
Statement:用于执行不带参数的简单sql
PreparedStatement:
(1)用于执行带或者不带参数的sql语句
(2)sql语句会预编译在数据系统
(3)执行速度快于StatementCallableStatement:用于执行数据库存储过程的调用
使用PreparedStatement:
PreparedStatement statement = null;
statement = connection.prepareStatement(sql);
//替换占位符:指定占位符的位置(从1开始),数据类型,
statement.setString(1, name);
resultSet = statement.executeQuery();
注意:使用PreparedStatement时
占位符 ? 下标从1开始且不能使用多值
可阻止常见的SQL注入攻击
预编译的操作命令对象PreparedStatement一定要使用无参的方法
插入、修改、删除都是executeUpdata()方法,返回值都是int
全部代码:
public static void main(String[] args) {
List<Student> list = query("许仙");
}
public static List<Student> query(String name) {
//先准备数据库驱动包,并添加到项目的依赖中
Connection connection = null;
PreparedStatement statement = null;
//com.mysql.jdbc.PreparedStatement statement = null;
ResultSet resultSet = null;
try {
// 加载JDBC驱动程序:反射,这样调用初始化com.mysql.jdbc.Driver类,即将该类加载到JVM方法
//区,并执行该类的静态方法块、静态属性。
//不需要加载驱动了,直接new MysqlDataSource();
//Class.forName("com.mysql.jdbc.Driver");//类加载
//1.创建数据库连接
//URL:网址,连接自己Mysql,password为自己的密码
//数据库连接池 使用DataSource
MysqlDataSource ds = new MysqlDataSource();
ds.setUrl("jdbc:mysql://localhost:3306/test?user=root&password=102917&useUnicode=true&characterEncoding=UTF-8&useSSL=false");
connection = ds.getConnection();
System.out.println(connection);
//connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/test?user=root&password=102917&useUnicode=true&characterEncoding=UTF-8&useSSL=false");
//System.out.println(connection);
//2.创建操作命令对象Statement
//statement = connection.createStatement();//创作简单的操作命令对象Statement
//3.执行sql
//占位符就是先占住一个固定的位置,等着再往里面添加内容的符号
String sql = "select id,sn,name,qq_mail,classes_id from student where name=?";//指定多个占位符,在执行sql的时候替换值
//PreparedStatement预编译操作命令对象 注意使用String sql传入参数
//发送sql,让数据库预编译:语法分析,执行顺序分析,执行优化
statement = connection.prepareStatement(sql);
//替换占位符:指定占位符的位置(从1开始),数据类型,
statement.setString(1, name);
resultSet = statement.executeQuery();
List<Student> studentList = new ArrayList<>();
//4.处理结果集(查询操作)
while (resultSet.next()) {
int id = resultSet.getInt("id");
int sn = resultSet.getInt("sn");
//String name = resultSet.getString("name");
String qq_mail = resultSet.getString("qq_mail");
int classes_id = resultSet.getInt("classes_id");
System.out.println(String.format("student: id=%d ,sn=%d, name=%s, qq_mail=%s, classes_id=%d", id, sn, name, qq_mail, classes_id));
Student student = new Student();
student.setId(id);
//student.id = id;
student.setSn(sn);
student.setName(name);
student.setQq_mail(qq_mail);
student.setClasses_id(classes_id);
studentList.add(student);
}
System.out.println(studentList);
return studentList;
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("出错", e);
} finally {
//5.释放资源
try {
//connection.close();
if (resultSet != null) {
resultSet.close();
}
if (statement != null) {
statement.close();
}
if (connection != null) {
connection.close();
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}