JDBC详细总结
JDBC原理
JDBC是什么
Java Database Connectivity: Java访问数据库的解决⽅案。
JDBC是Java应⽤程序访问数据库的⾥程碑式解决⽅案。Java研发者希望⽤相同的⽅式访问不同的数据库,以实现与具体数据库⽆关的Java 操作界⾯。
JDBC定义了⼀套标准接⼝,即访问数据库的通⽤API,不同的数据库⼚商根据各⾃数据库的特点去实现这些接⼝。
JDBC定义了⼀些接⼝
驱动管理 DriverManager
连接接⼝ Connection DatabasemetaData
语句对象接⼝ Statement PreparedStatement CallableStatement
结果集接⼝ ResultSet ResultMetaData
JDBC⼯作原理
JDBC只定义接⼝,具体实现由各个数据⼚商负责。程序使⽤时只需要调⽤接⼝,实际调⽤的是底层数据库⼚商的实现部分。
JDBC访问数据库的⼯作过程:
1. 加载驱动,建⽴连接
2. 创建语句对象
3. 执⾏SQL语句
4. 处理结果集
5. 关闭连接
Driver接⼝及驱动类加载
要使⽤JDBC接⼝,需要先将对应数据库的实现部分(驱动)加载进来
Class.forName("sql.jdbc.Driver");
这条语句的含义是:装载驱动类,驱动类通过static块实现在DriverManager中的⾃动注册
Connection接⼝
Connection接⼝负责应⽤程序对数据库的连接,在加载驱动之后,使⽤url、username、password三个参数,创建到具体数据库的连接。
Class.forName("sql.jdbc.Driver");
Connection conn = Connection("url","username","password");
Statement接⼝
Statement接⼝⽤来处理发送到数据库的SQL语句对象,通过Connection对象创建。主要有三个常⽤⽅法:
Statement stmt = ateStatement();
//execute⽅法,如果执⾏的sql是查询语句且有结果集则返回true,如果是⾮查询语句或者没有结果集,返回false
boolean flag = ute(sql);
//执⾏查询语句,返回结果集
ResultSet rs = uteQuery(sql);
//执⾏DML语句,返回影响的记录数
int flag = uteUpdate(sql);
ResultSet接⼝
执⾏查询SQL语句后返回的结果集,由ResultSet接⼝接收。
常⽤处理⽅式:遍历/判断是否由结果
String sql = "select * from table";
ResultSet rs = uteQuery(sql);
()){
System.out.Int("age")+rs.getString("name"));
}
查询的结果存放在ResultSet对象的⼀系列⾏中,指针的最初位置在⾏⾸,使⽤next()⽅法⽤来在⾏间移动,getXXX()⽅法⽤来取得字段的内容。
JDBC基础编程
连接管理
通过连接⼯具类获取连接
在⼯程中,通常编写⼀个访问数据库的⼯具类,此后所有访问数据库的操作,都从⼯具类中获取连接。
实现⼯具类的两种⽅式:
直接把数据配置写在⼯具类
把数据库配置写在⼀个properties属性⽂件⾥,⼯具类读⼊属性⽂件,逐⾏获取数据库参数。
通过属性⽂件维护连接属性:
#驱动类名
jdbc.driver = sql.jdbc.Driver
#连接字符串
jdbc.url = jdbc:mysql://localhost/test
jdbc.user = wz
jdbc.password = 12345
public class Demo {
static final String JDBC_DRIVER = "sql.jdbc.Driver";
static final String BD_URL = "jdbc:mysql://localhost/test";
static final String USER = "username";
static final String PASS = "password";
public static void main(String[] args){
Connection conn = null;
Statement stmt = null;
try{
Class.forName("sql.jdbc.Driver");
conn = Connection(DB_URL,USER,PASS);
stmt = ateStatement();
String sql;
sql = "select id,age from table";
ResultSet rs = uteQuery(sql);
()){
int id = rs.getInt("id");
int age = rs.getInt("age");
System.out.print("ID"+id);
System.out.print("Age"+age);
}
rs.close();
stmt.close();
conn.close();
} catch(SQLException e){
e.printStackTrace();
} catch(SQLException e2){
e2.printStackTrace();
} finally {
try{
if(stmt != null)
stmt.close();
} catch (SQLException e3){
}
try{
if(conn != null)
conn.close();
} catch(SQLException e4){
e4.printStackTrace();
}
}
}
}
连接池技术
为什么要使⽤连接池
数据库连接的建⽴及关闭资源消耗巨⼤。传统数据库访问⽅式:⼀次数据库访问对应⼀个物理连接,每次操作数据库都要打开、关闭该物理连接,系统性能严重损坏。这才出现了数据库连接池。
系统初始运⾏时,主动建⽴⾜够的连接,组成⼀个池,每次应⽤程序请求数据库连接时,⽆需重新打开连接,⽽是从池中取出已有的连接,使⽤完后,不再关闭,⽽是归还。
连接池中连接的释放与使⽤原则
应⽤启动时,创建初始化数⽬的连接当申请时⽆连接可⽤或者达到指定的最⼩连接数,按增量参数值
创建新的连接。
为确保连接池中最⼩的连接数的策略:
1. 动态检查:定时检查连接池,⼀旦发现数量⼩于最⼩连接数,则补充相应的新连接,保证连接池正常运转
2.
静态检查:空闲连接不⾜时,系统才检查是否达到最⼩连接数
通过DataSource 获取连接
先通过属性⽂件获取连接池参数,然后加载这些参数,获得连接:连接池参数初始连接数最⼤连接数
最⼩连接数每次增加的连接数超时时间最⼤空闲连接
最⼩空闲连接
JDBC 核⼼API
Statement
通过Connection对象创建Statement的⽅式
执⾏INSERT,UPDATE和DELETE等DML操作
执⾏SELECT private static BasicDataSource dataSource = new BasicDataSource();
dataSource .setDriverClassName (driveClassName);
dataSource .setUrl (url);
dataSource .setUsername (username);
dataSource .setPassword (password);
Connection conn = dataSource .getConnection ();
Connection .createStatement ();
Statement .executeUpdate ();
Statement .executeQuery ();
resultset 遍历
PreparedStatement 原理
Statement主要⽤于执⾏静态SQL语句,即内容固定不变的SQL语句。Statement每执⾏⼀次都要对传⼊的SQL语句编译⼀次,效率较差。
某些情况下,SQL语句只是其中的参数有所不同,其余⼦句完全相同,适⽤于PreparedStatement。
PreparedStatement的另外⼀个好处就是预防sql注⼊攻击。
PreparedStatement是接⼝,继承⾃Statement接⼝。
使⽤PreparedStatement时,SQL语句已提前编译,三种常⽤⽅法 execute、executeQuery和executeUpdate已被更改,以使之不再需
要参数。
PreparedStatement实例包含已事先编译的 SQL 语句,SQL 语句可有⼀个或多个 IN 参数,IN参数的值在 SQL 语句创建时未被指定。该语句为每个 IN 参数保留⼀个问号(“?”)作为占位符。
每个问号的值必须在该语句执⾏之前,通过适当的setInt或者setString等⽅法提供。
由于PreparedStatement对象已预编译过,所以其执⾏速度要快于 Statement 对象。因此,多次执⾏的 SQL 语句经常创建为
PreparedStatement对象,以提⾼效率。
通常批量处理时使⽤PreparedStatement。
SQL 注⼊
先看这样⼀段SQL
输⼊⽤户名和密码参数后,数据库接收到的完整sql语句是这样的:
如果⽤户输⼊的passwd参数是”or 1=1”,则数据库收到的语句是:
此SQL语句的where语句条件为true。即⽤户不需要输⼊正确的账号密码,也能登录。这种现象称为SQL注⼊。
通过PreparedStatement防⽌SQL Injection,对JDBC⽽⾔,SQL注⼊攻击只对Statement有效,对PreparedStatement⽆效,因为PreparedStatement不允许在插⼊参数时改变SQL语句的逻辑结构。String sql = "select  id,age from  table ";
Statement stmt = ateStatement();ResultSet rs = uteQuery(sql);
PreparedStatement pstmt = conn .prepareStatement ("update table set name=? where id = ?");
pstmt .setLong (1,"⼩明");
pstmt .setInt (2,1001);
pstmt .executeUpdate ();
String sql = "select  * from  t where  username ='" + name +"' and  password = '" + passwd + "'";
select  * from  t where  username = 'xiaoming' and  password = '123';
select  * from  t where  username = 'scott' and  password = '' or  '1'='1';

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。