JDBC代表一组公共的接口,在 java.sql包或javax.sql包
JDBC中的这些公共接口和DBMS数据库厂商提供的实现类,是为了实现java代码可以连接DBMS,并且操作里面的数据而申明的
驱动:所有的数据库驱动都是以jar包的形式存在,jar包当中有很多.class文件,这些class文件就是对JDBC接口的实现。 驱动由各大数据库厂家提供,下载jar包需在数据库官网下载
JDBC程序编写步骤:
(1)注册驱动(告知java程序,即将连接什么数据库)
(2)获取连接(表示JVM进程和数据库进程之间的通道打开)
(3)获取数据库操作对象(专门执行SQL语句的对象)
(4)执行SQL语句(DQL,DML…)
(5)处理查询结果集(只有当第四步执行的是select语句时,才有这一步)
(6)释放资源(使用完之后一定要关闭)
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Connection;
import java.sql.Statement;
public class JDBCText{
public static void main(String[] args){
Connection conn=null;
Statement stmt=null;
try{
//注册驱动
java.sql.Driver driver=new com.mysql.jdbc.Driver(); //Driver driver=new oracle.jdbc.driver.OracleDriver();
DriverManager.registerDriver(driver);
//获取连接
//url:协议,IP地址,端口号,具体的数据库实例名
//Oracle的url: jdbc:oracle:thin@localhost:1521:orcl
String url="jdbc:mysql://localhost:3306/bjpowernode";
String user="root";
String password="填账户密码";
conn=DriverManager.getConnection(url,user,password);
//获取数据库操作对象
stmt=conn.createStatement();//Statement专门执行sql语句
//执行sql
String sql="insert into dept(deptno,dname,loc) values(50,'策划部',‘北京’)";
int count=stmt.executeUpdate(sql);//专门执行DML语句,返回值是“影响数据库中的记录条数”
}catch(SQLException e){
e.printStackTrace();
}finally{
//释放资源:遵循从小到大依次关闭,分别对其进行关闭
if(stmt!=null){
try{
stmt.close();
}catch(SQLException){
e.printStackTrace();
}
}
if(conn!=null){
try{
conn.close();
}catch(SQLException){
e.printStackTrace();
}
}
}
}
}
注册驱动的另一种方式(常用)
public class JDBCText{
public static void main(String[] args){
Connection conn=null;
Statement stmt=null;
try{
class.forName("com.mysql.jdbc.Driver");
conn=DriverManager.getConnection("jdbc:mysql://localhost:3306/bjpowernode","root","172");
stmt=conn.createStatement();
String sql="insert into dept(deptno,dname,loc) values(50,'策划部',‘北京’)";
int count=stmt.executeUpdate(sql);
}catch(SQLException e){
e.printStackTrace();
}catch(ClassNotFoundException e){
e.printStackTrace();
}
finally{
//释放资源:遵循从小到大依次关闭,分别对其进行关闭
if(stmt!=null){
try{
stmt.close();
}catch(SQLException){
e.printStackTrace();
}
}
if(conn!=null){
try{
conn.close();
}catch(SQLException){
e.printStackTrace();
}
}
}
}
}
配置文件:jdbc.properties
其中内容:
driver=conm.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/bjpowernode
user=root
password=333
//将连接数据库的所以信息配置到配置文件中
public class JDBCText{
public static void main(String[] args){
ResourceBundle bundle=ResourceBundle.getBundle("jdbc");
Stribng driver=bundle.getString("driver");
String url=bundle.getString("url");
String user=bundle.getString("user");
String password=bundle.getString("password");
Connection conn=null;
Statement stmt=null;
try{
class.forName(driver);
conn=DriverManager.getConnection(url,user,password);
stmt=conn.createStatement();
String sql="insert into dept(deptno,dname,loc) values(50,'策划部',‘北京’)";
int count=stmt.executeUpdate(sql);
}catch(SQLException e){
e.printStackTrace();
}catch(ClassNotFoundException e){
e.printStackTrace();
}
finally{
//释放资源:遵循从小到大依次关闭,分别对其进行关闭
if(stmt!=null){
try{
stmt.close();
}catch(SQLException){
e.printStackTrace();
}
}
if(conn!=null){
try{
conn.close();
}catch(SQLException){
e.printStackTrace();
}
}
}
}
}
处理查询结果集
public class JDBCText{
public static void main(String[] args){
ResourceBundle bundle=ResourceBundle.getBundle("jdbc");
Stribng driver=bundle.getString("driver");
String url=bundle.getString("url");
String user=bundle.getString("user");
String password=bundle.getString("password");
Connection conn=null;
Statement stmt=null;
ResultSet rs=null;
try{
class.forName(driver);
conn=DriverManager.getConnection(url,user,password);
stmt=conn.createStatement();
String sql="select empno as e,ename from emp";
rs=stmt.executeQuery(sql); //专门执行DQL语句
//处理查询语句
while(rs.next()){ //光标指向的行有数据
//getString()的特点:不管数据库中的数据类型是什么,都以String的形式取出来
String empno=rs.getString("e"); //JDBC中所有下标从1开始,不是从0开始
String ename=rs.getString("ename");
//int empno=rs.getInt("e");除了可以以String类型取出外,还可以特定的类型取出
System.out.println(empno+","+ename);
}
}catch(SQLException e){
e.printStackTrace();
}catch(ClassNotFoundException e){
e.printStackTrace();
}
finally{
//释放资源:遵循从小到大依次关闭,分别对其进行关闭
if(rs!=null){
try{
rs.close();
}catch(SQLException){
e.printStackTrace();
}
}
if(stmt!=null){
try{
stmt.close();
}catch(SQLException){
e.printStackTrace();
}
}
if(conn!=null){
try{
conn.close();
}catch(SQLException){
e.printStackTrace();
}
}
}
}
}
SQL注入:用户输入的信息中含有sql语句的关键字,并且这些关键字参与sql语句的编译过程,导致sql语句的原意被扭曲,进而达到sql注入
解决sql注入问题:即使用户提供的信息中含有SQL语句的关键字,但没有参与编译,就不起作用。
要想用户信息不参与SQL语句的编译,必须使用java.sql.PreparedStatement,它继承了java.sql.Statement
PreparedStatement属于预编译的数据库操作对象,其原理是:与西安对SQL语句的框架进行编译,然后再给SQL语句传“值”
Connection conn=null;
PreparedStatement ps=null;
ResultSet rs=null;
try{
Class.forName("com.mysql.jdbc.Driver");
conn=DriverManager.getConnection(url,user,password);
//获取预编译的数据库操作对象
//?表示占位符,一个?接收一个值,注意:占位符不能使用单引号括起来
String sql="select *from t_user where name=? and pwd=?";
ps=conn.prepareStatement(sql);
//给占位符传值
ps.setString(1,name);
ps.setString(2,pwd);
//执行sql
rs=ps.executeQuery();
//处理结果集
}catch(SQLException e){
.....
}....
Statement和PreparedStatement
Statement存在sql注入问题,PreparedStatement解决了sql注入问题
Statement编译一次执行一次,PreparedStatement是编译一次,可执行m次,效率更高
PreparedStatement会在编译阶段做类型的安全检查
Statement支持sql注入,凡是需要进行sql语句拼接的,必须使用Statement
JDBC事务机制:
1.JDBC中的事物是自动提交的,只要任意执行一条DML语句,则自动提交一次,这是JDBC默认的事务行为,但是在实际的业务中,通常都是N调DML语句共同才能完成的,必须保证这些DML语句在同一个事务中同时成功或同时失败
Connection conn=null;
PreparedStatement ps=null;
try{
Class.forName("com.mysql.jdbc.Driver");
conn=DriverManager.getConnection(url,user,password);
//将自动提交改为手动提交
conn.setAutoCommit(false);
String sql="update t_box set balance=? where actno=?";
ps=conn.prepareStatement(sql);
ps.setDouble(1,1000);
ps.setInt(2,111);
int count=ps.executeUpdate();
ps.setDouble(1,1000);
ps.setInt(2,222);
count+=ps.executeUpdate();
System.out,println(count=2?"转账成功":"转账失败");
//程序走到这里说明以上程序没有异常,事物结束,手动提交数据
conn.commit();
} catch(Exception e){
//回滚事务
if(conn!=null){
try{
conn.rollback();
}catch(SQLException e1){
e1.printStackTrace();
}
}
e.printStackTrace();
} finally{
//释放资源
......
}
JDBC工具类的封装
public class DBUtil{
static{
try{
Class.forName("com.mysql.jdbc.Driver");
}catch(ClassNotFoundException e){
e.printStackTrace();
}
}
public static Connection getConnection() throws SQLException{
return DriverManager.getConnection(url,user,password);
}
public static void close(Connection conn,Statement stmt,ResultSet rs){
if(rs!=null){
try{
rs.close();
}catch(SQLException e){
e.printStackTrace();
}
}
if(stmt!=null){
try{
stmt.close();
}catch(SQLException e){
e.printStackTrace();
}
}
if(conn!=null){
try{
conn.close();
}catch(SQLException e){
e.printStackTrace();
}
}
}
}
在另一个类中使用
public class DBText{
public static void main(String[] args){
Connection conn=null;
PreparedStatement ps=null;
ResultSet rs=null;
try{
conn=DBUtil.getConnection();
String sql="select ename from emp where ename like ?";
ps=conn.prepareStatement(sql);
ps.setString(1,"");
rs=ps.executeQuery();
while(rs.next()){
System.out.println(rs.getString("ename"));
}
}catch(Exception e){
e.printStackTrace();
}finally{
DBUtil,close(conn,ps,rs);
}
}
}