JDBC:Java DataBase Connectivity 可以为多种关系型数据库DBMS 提供统一的访问方式,用Java来操作数据库
5.1 JDBC分为三层:****
1、JDBC API :****
提供各种操作访问接口 Connection Statement PreparedStatement ResultSet
2、JDBC DriverManager
管理不同的数据库驱动
2、各种数据库驱动:*
相应的数据库厂商提供的(第三方公司提供),用来连接或直接操作数据库。
5.2 每层功能:*
5.2.1 JDBC API*
三件事,具体是通过以下类/接口实现:
DriverManager : 管理jdbc驱动
Connection: 连接(通过DriverManager产生)
Statement(PreparedStatement) :增删改查 (通过Connection产生 )
CallableStatement : 调用数据库中的 存储过程/存储函数 (通过Connection产生 )
Result :返回的结果集 (上面的Statement等产生 )
1、DriverManager*
Class.forName("com.mysql.jdbc.Driver");// 加载具体的驱动类
2、Connection*
connection = DriverManager.getConnection(URL, USERNAME, PWD);
Connection产生操作数据库的对象:
Connection产生Statement对象:createStatement()
Connection产生PreparedStatement对象:prepareStatement()
Connection产生CallableStatement对象:prepareCall();
3、Statement 和PreparedStatement
stmt = connection.createStatement();
(1)Statement操作数据库:
增删改:executeUpdate()
查询:executeQuery();
(2)PreparedStatement操作数据库:
public interface PreparedStatement extends Statement
因此
增删改:executeUpdate()
查询:executeQuery();
--此外
赋值操作 setXxx();
(3)PreparedStatement与Statement在使用时的区别:****
Statement | PreparedStatement | |
操作顺序 | ①先写sql语句②在使用修改语句executeUpdate(sql) | ①sql(可能存在占位符?)②在创建PreparedStatement 对象时,将sql预编译 prepareStatement(sql)③executeUpdate()setXxx()替换占位符? |
编码难度 | 需要拼接 | 使用setXXX()无需拼接 |
性能 | 低,一次一条语句 | 高,可循环多条语句 |
安全性 | 存在被sql注入的风险 | 有效防止sql注入 |
注:sql注入: 将客户输入的内容 和 开发人员的SQL语句 混为一体****
操作顺序及编码难度:
Statement:
String sql =" insert into student(stuno,stuname) values('"+name+"', "+age+" ) " ; stmt.executeUpdate(sql); 复制代码
PreparedStatement:****
String sql =" insert into student(stuno,stuname) values(?,?) " ; pstmt = connection.prepareStatement(sql);//预编译SQL pstmt.setString(1,name); pstmt.setInt(2,age); 复制代码
性能(效率):****
Statement:
String sql =" insert into student(stuno,stuname) values('"+name+"', "+age+" ) " ; for(100) stmt.executeUpdate(sql); PreparedStatement:(预编译只需执行一次) String sql =" insert into student(stuno,stuname) values(?,?) " ; pstmt = connection.prepareStatement(sql);//预编译SQL pstmt.setString(1,name); pstmt.setInt(2,age); for( 100){ pstmt.executeUpdate(); } 复制代码
4、CallableStatement:
(1)功能:调用 存储过程、存储函数
connection.prepareCall(参数:存储过程或存储函数名)
参数格式:
存储过程(无返回值return,用out参数替代):
{ call 存储过程名(参数列表) }
存储函数(有返回值return):
{ ? = call 存储函数名(参数列表) }
(2)储存函数过程
强调:
如果通过sqlplus 访问数据库,只需要开启:OracleServiceSID
通过其他程序访问数据(sqldevelop、navicate、JDBC),需要开启:OracleServiceSID、XxxListener
(3)JDBC调用存储过程的步骤:
a.产生 调用存储过程的对象(CallableStatement) cstmt = connection.prepareCall( "..." ) ;
b.通过setXxx()处理 输出参数值 cstmt.setInt(1, 30);
c.通过 registerOutParameter(...)处理输出参数类型
d.cstmt.execute()执行
e.接受 输出值(返回值)getXxx()
(4)示例:调存储函数:
JDBC调用存储函数:与调存储过程的区别:
在调用时,注意参数:"{? = call addTwoNumfunction (?,?) }"
5、ResultSet
rs = stmt.executeQuery(sql); if(rs.next()) { count = rs.getInt(1) ; } ResultSet:保存结果集 select * from xxx next():光标下移,判断是否有下一条数据;true/false previous(): true/false 与next()方向相反 getXxx(字段名或位置):获取具体的字段值 复制代码
5.2.2 各种数据库驱动****
驱动jar | 具体驱动类 | |
Oracle | ojdbc-x.jar | oracle.jdbc.OracleDriver |
MySQL | mysql-connector-java-x.jar | com.mysql.jdbc.Driver |
SqlServer | sqljdbc-x.jar | com.microsoft.sqlserver.jdbc.SQLServerDriver jdbc:microsoft:sqlserver:localhost:1433;databasename=数据库实例名 |
注:使用jdbc操作数据库时,如果对数据库进行了更换,只需要替换:驱动、具体驱动类、连接字符串、用户名、密码
5.3 JDBC访问数据库的具体步骤:****
a.导入驱动,加载具体的驱动类
b.与数据库建立连接
c.发送sql,执行
d.处理结果集 (查询)