JDBC:Java数据库连接技术(Java DataBase Connectivity),能实现Java程序对各种数据库的访问。
JDBC访问数据库步骤:
- Class.forName()加载驱动。
- DriverManager获取Connection连接。
- 创建Statement执行SQL语句。
- 返回ResultSet查询结果。
- 释放资源。
- 代码示例:
public static void main(String[] args) {
Connection connection = null;
PreparedStatement statement = null;
try {
// 1.加载驱动
Class.forName("com.mysql.jdbc.Driver");
// 2.获取连接(DriverManager:管理各种不同的JDBC驱动)
connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/kgcnews", "root", "root");
// 3.预编译SQL
statement = connection.prepareStatement("INSERT INTO news_category VALUES(?,?,?)");
// 为 ? 号占位符设置值
statement.setInt(1 , 8);
statement.setString(2 , "张三");
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String format = dateFormat.format(new Date());
statement.setString(3 , format);
// 4.执行SQL
statement.executeUpdate();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException throwables) {
throwables.printStackTrace();
}finally {
try {
// 5.关闭资源
statement.close();
connection.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
Statement与PreparedStatement区别
- Statement由方法createStatement()创建,该对象用于发送简单的SQL语句。
- PreparedStatement由方法prepareStatement()创建,该对象用于发送带有一个或者多个输入参数的SQL语句。
- SQL语句使用“?”作为数据占位符。
- 使用setXxx()方法设置数据。
- PreparedStatement:预编译SQL语句
- 效率、性能、开销
- 安全性
- 代码可读性
JDBC工作原理及内容
- JDBC优点
- 不必为不同的数据库专门编写不同的程序,而只需要加载不同的数据库驱动即可。
- JDBC API
- 定义了一系列的接口和类,集成在java.sql和javax.sql包中。
- DriverManager
- 管理各种不同的JDBC驱动。
- JDBC 驱动
- 负责连接不同类型的数据库。
druid连接池、监控组件
- 通过阿里巴巴的druid . jar包可以配置数据库连接池、监控组件。
- 连接池代码示例:
- .properties配置文件代码
#mysql数据库地址
url=jdbc:mysql://localhost:数据库端口号/数据库名称
#这个可以缺省的,会根据url自动识别
driverClassName=com.mysql.jdbc.Driver
username=root
password=root
##初始连接数,默认0
initialSize=10
#最大连接数,默认8
maxActive=30
#最小闲置数
minIdle=10
#获取连接的最大等待时间,单位毫秒
maxWait=2000
#配置监控
druid.filters=stat
#缓存PreparedStatement,默认false
poolPreparedStatements=true
#缓存PreparedStatement的最大数量,默认-1(不缓存)。大于0时会自动开启缓存PreparedStatement,所以可以省略上一句设置
maxOpenPreparedStatements=20
工具类代码封装,通过druid jar包创建连接池, JDBC:
/**
* 读取配置文件
* @return 返回数据库连接
*/
public static Connection getProperties() {
// 数据源配置
Properties properties = new Properties();
// 通过当前类的class对象获取资源文件
//InputStream resourceAsStream = Jdbc.class.getClassLoader().getResourceAsStream("file.properties");
InputStream resourceAsStream = Jdbc.class.getResourceAsStream("/file.properties");
Connection connection = null;
try {
properties.load(resourceAsStream);
// 数据库连接池
DataSource dataSource = DruidDataSourceFactory.createDataSource(properties);
// 获取连接(尝试与数据源建立连接)
connection = dataSource.getConnection();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return connection;
}
/**
* 实现增删改封装
* @return 返回影响的行数
*/
public static int insUpdate(String sql, Object[] obj) {
Connection connection = Jdbc.getProperties();
PreparedStatement statement = null;
int num = 0;
try {
statement = connection.prepareStatement(sql);
for (int i = 1; i <= obj.length; i++) {
statement.setObject(i, obj[i-1]);
}
num = statement.executeUpdate();
} catch (SQLException throwables) {
throwables.printStackTrace();
} finally {
Jdbc.close(null , connection , statement);
}
return num;
}
/**
* 查询全部
* @param sql 通过SQL语句查询
* @return 返回ResultSet 对象,通过ResultSet 对象获取具体的值
*/
public static ResultSet selectAll(String sql) {
Connection connection = Jdbc.getProperties();
ResultSet resultSet = null;
try {
resultSet = connection.createStatement().executeQuery(sql);
} catch (SQLException throwables) {
throwables.printStackTrace();
}
return resultSet;
}
- 查询的代码:
public List<User> selectUser() {
ResultSet resultSet = Jdbc.selectAll("SELECT * FROM news_category");
ArrayList<User> userList = new ArrayList<>();
try {
while (resultSet.next()) {
userList.add(new User(resultSet.getInt("id") , resultSet.getString("name") , resultSet.getString("createDate")));
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}
return userList;
}
- class.getResourceAsStream(String name)和class.getClassLoader().getResourceAsStream(String name)的区别
// 通过当前类的class对象获取资源文件
//InputStream resourceAsStream = Jdbc.class.getClassLoader().getResourceAsStream("file.properties");
InputStream resourceAsStream = Jdbc.class.getResourceAsStream("/file.properties");
- class.getClassLoader().getResourceAsStream(String name) 默认从classpath中找文件(文件放在resources目录下),name不能带“/”,否则会抛空指针。
- class.getResourceAsStream(String name) 通过给定名称查找资源,查询资源的规则由给定的类的class load来实现,这个方法由类的loader来执行;如果这个类由bootstrap加载,那么方法由ClassLoader.getSystemResourceAsStream代理执行。 代理之前,绝对的资源名称通过传入的name参数以下算法进行构造: 如果name以"/"开头,那么绝对路径是/后边跟的名字。