JDBC常见应用
JDBC 规范定义接口,具体的实现由各大数据库厂商来实现。
下面说一下使用 JDBC 的好处:
-
程序员如果要开发访问数据库的程序,只需要会调用 JDBC 接口中的方法即可,不用关注类是如何实现的。
-
使用同一套 Java 代码,进行少量的修改就可以访问其他 JDBC 支持的数据库
1.最简单的jdbc使用
public void test01(){
//注册驱动
//Class.forName("com.mysql.jdbc.Driver");//高版本自动注册,这一步可以省略不写
//获取连接
Connection conn = null;
Statement stmt = null;
try {
conn = DriverManager.getConnection("jdbc:mysql:///yz","root","123456");
//编写sql
String sql = "insert into dept values(8,'销售部','光谷')";
//获取statement对象
stmt = conn.createStatement();
//执行sql
int i = stmt.executeUpdate(sql);
} catch (SQLException e) {
e.printStackTrace();
} finally {
//释放资源
try {
if (stmt != null){
stmt.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
try {
if (conn != null){
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
可以将上面的总结以下几步:
1.注册驱动(从JDBC3之后这一步不需要自己注册了,可以省略)
2.获取连接
3.Connection 获取 Statement 对象
4.使用 Statement 对象执行 SQL 语句
5.返回结果集
6.释放资源
注意:如果出现乱码,可以在URL后面加上参数?characterEncoding=utf8
即可解决(?后面接参数)
2.防止SQL注入的升级版JDBC
-
PreparedStatement
是Statement
接口的子接口,继承于父接口中所有的方法。它是一个预编译的 SQL 语句 -
什么是sql注入
请输入用户名: newboy 请输入密码: a' or '1'='1 select * from user where name='newboy' and password='a' or '1'='1' 登录成功,欢迎您:newboy select * from user where name='newboy' and password='a' or '1'='1' name='newboy' and password='a' 为假 '1'='1' 真 相当于 select * from user where true; 查询了所有记录
通过上面的例子就知道了我们让用户输入的密码和 SQL 语句进行字符串拼接。用户输入的内容作为了 SQL 语句语法的一部分,改变了原有 SQL 真正的意义,以上问题称为 SQL 注入。
-
解决sql注入
-
编写 SQL 语句,未知内容使用?占位:“SELECT * FROM user WHERE name=? AND password=?”;
-
获得 PreparedStatement 对象
-
设置实际参数:setXxx(占位符的位置, 真实的值)
-
执行参数化 SQL 语句
-
关闭资源
public void test04() throws Exception{ String sql = "select * from dept where did = ?"; PreparedStatement psmt = conn.prepareStatement(sql); psmt.setInt(1,1); ResultSet rs = psmt.executeQuery(); if (rs.next()){ int did = rs.getInt("did"); String dname = rs.getString("dname"); String location = rs.getString("location"); System.out.println(did+"---"+dname+"---"+location); } }
-
3.使用连接池的升级版JDBC
- 市面上有很多JDBC连接池,这里我知介绍德鲁伊(Druid)连接池,这个是阿里写的,目前世界上公认最好用的连接池之一,使我们国产的。
public void test02() throws Exception{
DruidDataSource ds = new DruidDataSource();
ds.setDriverClassName("com.mysql.jdbc.Driver");
ds.setUrl("jdbc:mysql:///yz");
ds.setUsername("root");
ds.setPassword("root");
//从连接池里获取连接对象
DruidPooledConnection conn = ds.getConnection();
}
使用很简单,像上面一样
-
关于jdbc的增删改查,这里介绍一下比较好用的一个查询结果,并返回结果集的方法
public void test02() throws SQLException { //获取数据源 DruidDataSource ds = new DruidDataSource(); ds.setUrl("jdbc:mysql:///yz"); ds.setUsername("root"); ds.setPassword("123456"); QueryRunner qr = new QueryRunner(ds); String sql = "select * from dept"; List<Dept> list = qr.query(sql, new BeanListHandler<Dept>(Dept.class)); for (Dept dept : list) { System.out.println(dept); } }
这个底层原理可以详细见源码,又兴趣可以自己手写一下。
2.下面附赠一个自己写的工具类(很好用)
druid.properties
:
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/db
username=root
password=root
initialSize=5
maxActive=10
maxWait=3000
JDBCUtils.java
:
package com.wang.util;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import javax.sql.DataSource;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
/**
* Druid连接数据库的工具类
*/
public class JDBCUtils {
private static DataSource ds;
static {
try {
//加载文件
Properties pro = new Properties();
InputStream is = JDBCUtils.class.getClassLoader().getResourceAsStream("druid.properties");
pro.load(is);
ds = DruidDataSourceFactory.createDataSource(pro);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 连接数据库发的方法
* @return
* @throws SQLException
*/
public static Connection getconnection() throws SQLException {
return ds.getConnection();
}
/**
* 释放资源的方法
* @param conn
* @param stmt
* @param rs
*/
public static void close(Connection conn, Statement stmt, ResultSet rs){
if (conn != null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (stmt != null){
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (rs != null){
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
/**
* 获取连接的方法
* @return
*/
public static DataSource getDataSource(){
return ds;
}
}