引言
JDBC
是一种用来在Java程序中执行SQL的API,它为java连接数据库提供了一组接口和类,可以为多种关系数据库提供统一访问。
SUN公司只是在JDBC当中定义了具体的接口
,而JDBC接口的具体的实现是由数据库提供厂商去写具体的实现, 比如说Connection对象,不同的数据库的实现方式是不同的。
I. 预备知识
1.1 JDBC
JDBC有一组应用程序的API,用来开发java连接数据库的应用程序;jdbc驱动api提供给数据库厂商,数据库厂商负责实现底层的编码。
1.2 对象关系映射(ORM)
使用传统的JDBC的项目已经越来越少了,曾经的model1和model2已经被MVC给代替了。如果用传统的JDBC写项目你不得不去管理你的数据连接、事物等。而用ORM框架一般程序员只用关心执行SQL和处理结果集就行了。比如Spring
的JdbcTemplate
、Hibernate
的HibernateTemplate
提供了一套对dao操作的模版,对JDBC进行了轻量级封装。开发人员只需配置好数据源
和事物
之后,开发仅需要提供SQL、处理SQL执行后的结果,其他的事情都交给框架去完成了。
ORM(
Object Relational Mapping
)框架采用元数据来描述对象与关系映射的细节,元数据一般采用XML格式,并且存放在专门的对象一映射文件中。 只要提供了持久化类与表的映射关系,ORM框架在运行时就能参照映射文件的信息,把对象持久化到数据库中。 当前ORM框架主要有五种:Hibernate(Nhibernate)
,iBatis
,mybatis
,EclipseLink
,JFinal
。
JPA全称Java Persistence API.JPA通过JDK 5.0注解或XML描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中,是一个ORM规范,Hibernate是JPA的具体实现。
1.3 Java对象持久化(Java Data Object)
JDO(Java Data Object )是Java对象持久化的规范,用于存取某种数据仓库中对象的标准化API。
JPA可以依靠JDBC对JDO进行对象持久化,而ORM只是JPA当中的一个规范,我们常见的Hibernate、Mybatis和TopLink都是ORM的具体实现。
1.4 传统的JDBC
完成一次查询操作,java和数据库的交互操作:
- 准备JDBC驱动
- 加载驱动
- 获取连接
- 预编译SQL
- 执行SQL
- 处理结果集
- 依次释放连接
II JDBC使用步骤
连接数据库的过程:JDBC Api ->driver;
2.1 准备连接数据库的相关数据
- 获得当前数据库连接的用户名和密码
- 获得数据库服务器的地址(ip)
- 获得数据库连接的端口号: oracle默认的是1521,mysql默认端口号是3306。
- 数据库的实例sid,即数据库名称。
- 获得连接字符串:
url=jdbc:oracle:thin:@ip:port:sid
、url=jdbc:mysql:@ip:port:sid
- 获得对应数据库的驱动:
classes12.jar或ojdbc14.jar
2.2 书写jdbc程序步骤
- 加载oracle驱动:导入oracle数据库的驱动
oracle.jdbc.OracleDriver
或者oracle.jdbc.driver.OracleDriver
class.forname("oracle.jdbc.OracleDriver");//通过反射加载驱动程序,在内存中创建oracleDriver的实例
- 通过驱动管理器获得连接对象
Connection conn=DriverManager.getConnection()url,user,password;;//通过驱动管理器获得连接对象
- 创建statement或preparestatement对象
代码语言:javascript复制生成statement实现类对象来编译sql,并将sql语句输送到数据库
// 方式一
Statement stmt=conn.createStatemenr();
//方式二
PreparedStatement pstmt=conn.prepareStatement(sql);//sql字符型不用加分号来结束
- 执行sql,接收返回结果
//方式一:
ResultSet rs=stmt.executeQuery(sql);;
//方式二:
ResultSet rs=pstmt.executeQuery();
- 循环遍历结果集
while(rs.next()){
int empno=rs.getInt(String columnName);
}
- 在finally中关闭资源
if(rs!=null){rs.close();}
if(pstmt!=null){pstmt.close();}
if(conn!=null){rconnclose();}
prepareCall(String sql);
用于调用存储过程conn.setAutoCommit(false);
设置当前jdbc的事物处理为手动
conn.rollback();
conn.commit();
2.3 代码示例
代码语言:javascript复制package com.iosre.jdbc;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class JDBCDemp {
public static void main(String[] args) {
jdbcTest(5438,"hello");
}
public static void jdbcTest(int id,String name){
String url="jdbc:oracle:thin:@localhost:1521:XE";
String user="hello";
String password="123456";
//String sql="delete from emp where empno=" id;
String sql = "insert into emp(empno,ename) values(" id ",'" name "')";
System.out.println(sql);
Connection conn=null;
PreparedStatement pstmt=null;
ResultSet rs =null;
//1.通过反射加载驱动程序,驱动程序的类名,在内存中创建驱动程序的对象
//oracle.jdbc.OracleDriver
//或者 oracle.jdbc.driver.OracleDriver
try {
Class.forName("oracle.jdbc.OracleDriver");
//new oracle.jdbc.OracleDriver();
conn = DriverManager.getConnection(url, user, password);
//生成statement对象编译SQL
//pstmt = conn.prepareStatement("select * from emp");
Statement stmt = conn.createStatement();
//执行SQL
//rs = stmt.executeQuery("select * from emp");
int num = stmt.executeUpdate(sql);
if(num>0){
System.out.println("删除成功");
}
/*while(rs.next()){
//int empno = rs.getInt("empno");
int empno = rs.getInt(1);
String ename = rs.getString(2);
System.out.println(ename);
}*/
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}finally{
try {
if(rs!=null){rs.close();}
if(pstmt!=null){pstmt.close();}
if(conn!=null){conn.close();}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
2.4 封装jdbc代码
代码语言:javascript复制package com.zhongx.jdbc;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
public class ConnectionUtil {
private static String url;
private static String user;
private static String password;
private static String driver;
private static Properties prop = new Properties();
//通过配置文件读取数据库 连接信息
//加载驱动创建对应驱动实例
static{
try {
InputStream is = new FileInputStream("src/com/zhongx/jdbc/db.properties");
prop.load(is);
url = prop.getProperty("url");
user = prop.getProperty("user");
password = prop.getProperty("password");
driver = prop.getProperty("driver");
Class.forName(driver);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} 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) throws SQLException{
if(rs!=null){rs.close();}
if(stmt!=null){stmt.close();}
if(conn!=null){conn.close();}
}
}
注释版本
代码语言:javascript复制//driverClass=com.mysql.jdbc.Driver
//1.获取Driver实现类的对象
// Class clazz = Class.forName("com.mysql.jdbc.Driver");
//1.读取配置文件信息
InputStream is = ConnectionTest.class.getClassLoader().getResourceAsStream("jdbc.properties");
Properties pros = new Properties();
pros.load(is);
String user = pros.getProperty("user");
String password = pros.getProperty("password");
String url = pros.getProperty("url");
String driverClass = pros.getProperty("driverClass");
//2.加载驱动
Class.forName(driverClass);
//3.获取连接
Connection conn = DriverManager.getConnection(url, user, password);
2.5 预编译sql
预编译sql会将sql语句预先编译号,执行的时候直接传递参数,不需要再次编译。
PreparedStatement是Statement的子接口,它与Statement的区别有:
- 程序的可读性和可维护性更好
- 更安全
- 执行效率高
PreparedStatement
允许数据库预编译sql语句,这样在随后的运行中可以节省时间,并增加了查询的可读性;Statement
每次执行sql语句相关的数据库都要执行sql语句的编译。
III JDBC涉及的类和接口
java.sql.Connection 接口
createStatement()
获得StatementprepareStatement(String sql)
获得preparedStatementprepareCall(String sql)
调用存储过程
java.sql.DriverManager 类
getConnection(String url, String user, String password)
java.sql.Statement 接口
executeQuery(String sql)
执行DQL语句executeUpdate(String sql)
执行DML语句executeBatch()
批处理执行SQL
java.sql.PreparedStatement 接口
setXXX
方法 :用来动态传参
java.sql.ResultSet 接口
next()
默认ResultSet对象指向记录的光标在第一条的前面getXXX(String/int)
获得对应字段的值getInt()
接收整数类型getDouble()
接收浮点数据getString()
接收字符串类型sql.Date getDate()
接收Date类型数据字段
see also
gzh: iOS逆向