标签:
Driver接口
prepareStatment类
通用的增删改
通用的查询
JDBC的概述:
在Java中,数据库存取技术可分为如下几类: JDBC直接访问数据库 JDO技术 第三方O/R工具,如Hibernate, ibatis 等JDBC是java访问数据库的基石,JDO, Hibernate等只是更好的封装了JDBC。
JDBC(Java Database Connectivity)是一个独立于特定数据库管理系统、通用的SQL数据库存取和操作的公共接口(一组API),定义了用来访问数据库的标准Java类库,(java.sql,javax.sql)使用这个类库可以以一种标准的方法、方便地访问数据库资源 JDBC为访问不同的数据库提供了一种统一的途径,为开发者屏蔽了一些细节问题。 JDBC的目标是使Java程序员使用JDBC可以连接任何提供了JDBC驱动程序的数据库系统,这样就使得程序员无需对特定的数据库系统的特点有过多的了解,从而大大简化和加快了开发过程。
JDBC接口(API)包括两个层次: 面向应用的API:Java API,抽象接口,供应用程序开发人员使用(连接数据库,执行SQL语句,获得结果)。 面向数据库的API:Java Driver API,供开发商开发数据库驱动程序用。
编程思想之面向接口编程
JDBC是sun公司提供一套用于数据库操作的接口,java程序员只需要面向这套接口编程即可。不同的数据库厂商,需要针对这套接口,提供不同实现。不同的实现的集合,即为不同数据库的驱动。
Driver 接口
java.sql.Driver 接口是所有 JDBC 驱动程序需要实现的接口。这个接口是提供给数据库厂商使用的,不同数据库厂商提供不同的实现 在程序中不需要直接去访问实现了 Driver 接口的类,而是由驱动程序管理器类(java.sql.DriverManager)去调用这些Driver实现
加载和注册JDBC的驱动
方式一:加载 JDBC 驱动需调用 Class 类的静态方法 forName(),向其传递要加载的 JDBC 驱动的全类名Class.forName(“com.mysql.jdbc.Driver”);方式二:DriverManager 类是驱动程序管理器类,负责管理驱动程序DriverManager.registerDriver(com.mysql.jdbc.Driver);
通常不用显式调用 DriverManager 类的 registerDriver() 方法来注册驱动程序类的实例,因为 Driver 接口的驱动程序类都包含了静态代码块,在这个静态代码块中,会调用 DriverManager.registerDriver() 方法来注册自身的一个实例。建立连接:Connection
调用 DriverManager 类的 getConnection() 方法建立到数据库的连接User,password可以用“属性名=属性值”方式告诉数据库;
JDBC URL 用于标识一个被注册的驱动程序,驱动程序管理器通过这个 URL 选择正确的驱动程序,从而建立到数据库的连接。
JDBC URL的标准由三部分组成,各部分间用冒号分隔。
jdbc:子协议:子名称
协议:JDBC URL中的协议总是jdbc 子协议:子协议用于标识一个数据库驱动程序 子名称:一种标识数据库的方法。子名称可以依不同的子协议而变化,用子名称的目的是为了定位数据库提供足够的信息。包含主机名(对应服务端的ip地址),端口号,数据库名
常见的数据库的JDBC URL
对于 Oracle 数据库连接,采用如下形式: jdbc:oracle:thin:@localhost:1521:数据库标识
对于 SQLServer 数据库连接,采用如下形式: jdbc:microsoft:sqlserver//localhost:1433; DatabaseName=sid
对于 MYSQL 数据库连接,采用如下形式: jdbc:mysql://localhost:3306/数据库标识
PreparedStatement 对象
通过调用 Connection 对象的 prepareStatement() 方法获取 PreparedStatement 对象。
PreparedStatement 接口是 Statement 的子接口,它表示一条预编译过的 SQL 语句 PreparedStatement 对象所代表的 SQL 语句中的参数用占位符(?)来表示,调用 PreparedStatement 对象的 setXxx() 方法来设置这些参数【填充占位符】,一般使用 setObject(int index,Object obj) 方法有两个参数,第一个参数是要设置的 SQL 语句中的参数的索引(从 1 开始),第二个是设置的 SQL 语句中的参数的值。
PreparedStatement 和Statement 的比较:
1,代码的可读性和可维护性. 2,PreparedStatement 能最大可能提高性能: DBServer会对预编译语句提供性能优化。因为预编译语句有可能被重复调用,所以语句在被DBServer的编译器编译后的执行代码被缓存下来,那么下次调用时只要是相同的预编译语句就不需要编译,只要将参数直接传入编译过的语句执行代码中就会得到执行。 在statement语句中,即使是相同操作但因为数据内容不一样,所以整个语句本身不能匹配,没有缓存语句的意义.事实是没有数据库会对普通语句编译后的执行代码缓存.这样每执行一次都要对传入的语句编译一次, (语法检查,语义检查,翻译成二进制命令,缓存) PreparedStatement 可以防止 SQL 注入
ResultSet类
通过调用 PreparedStatement 对象的 excuteQuery() 方法创建该接口的实现类对象。 ResultSet 实现类对象以逻辑表格的形式封装了执行数据库操作的结果集,ResultSet 接口由数据库厂商实现。 ResultSet 对象维护了一个指向当前数据行的游标,初始的时候,游标在第一行之前,可以通过 ResultSet 对象的 next() 方法移动到下一行,对象没有下一行时,返回false。ResultSet 接口的常用方法:boolean next()getString()
first()
close()
关于ResultSet的几个说明:
rs. getString(“name”)//返回一条记录的列名为name的数据 5.ResultSet 当然也需要进行关闭.
ResultSetMetaData 结果集元数据
ResultSetMetaData 类可用于获取关于 ResultSet 对象中列的类型和属性信息的对象 ResultSetMetaData meta = rs.getMetaData(); getColumnName(int column):获取指定列的名称 getColumnLabel(int column):获取指定列的别名 getColumnCount():返回当前 ResultSet 对象中的列数。 getColumnTypeName(int column):检索指定列的数据库特定的类型名称。 getColumnDisplaySize(int column):指示指定列的最大标准宽度,以字符为单位。 isNullable(int column):指示指定列中的值是否可以为 null。 isAutoIncrement(int column):指示是否自动为指定列进行编号,这样这些列仍然是只读的。
一般性归纳:
通用:可以在select语句中给 结果集 的列 装配别名 ,别名与其相对应类的属性一致。
获取数据库的连接:
1.导入具体数据库的驱动。在当前工程下,新建文件夹:libs,将具体数据库的.jar文件拷贝过来,然后选中右键:build path
2.相关数据库的服务需要开启。
3.获取数据库连接4个基本的信息:driverClass、url 、 user 、 password
public static Connection connection(){
Connection connection = null;
try {
Properties pro = new Properties();
pro.load(JDBCUtil.class.getClassLoader().getResourceAsStream("jdbc.properties"));
String driverClass = pro.getProperty("driverClass");
String url = pro.getProperty("url");
String user = pro.getProperty("user");
String password = pro.getProperty("password");
Class.forName(driverClass);
connection = DriverManager.getConnection(url, user, password);
} catch (Exception e) {
e.printStackTrace();
}
return connection;
}
使用PreparedStatement实现数据库中表数据的 ①增、删、改;
public static void update(String sql, Object... obj) {
Connection conn = null;
PreparedStatement ps = null;
try {
//1获取数据库连接
conn = JDBCUtil.connection();
//2.预编译sql语句,返回一个PreparedStatement的实例
ps = conn.prepareStatement(sql);
//3,填充占位符?
for (int i = 0; i < obj.length; i++) {
ps.setObject(i + 1, obj[i]);
}
//4,执行sql语句
ps.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
} finally {
//5,关闭资源
JDBCUtil.close(conn, ps);
}
}
通用的查询表中一条记录
/**
通用的查询操作,返回表中的一条记录,封装为相应类的一个对象
@param clazz :返回的对象所属的类。比如:Customer
@param sql :包含占位符的查询语句
@param args :填充占位符的实参值
@return clazz所对应的运行时类的一个对象
*/
public <T> T queryForInstance(Class<T> clazz,String sql,Object ... args){
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
//1.获取数据库的连接
conn = JDBCUtils.getConnection();
//2.预编译sql语句,返回一个PreparedStatement的实例
ps = conn.prepareStatement(sql);
//3.填充占位符
for(int i = 0;i < args.length;i++){
ps.setObject(i + 1, args[i]);
}
//4.执行,返回一个结果集:ResultSet
rs = ps.executeQuery();
//5.处理结果集。(难点)
//结果集的元数据:ResultSetMetaData
ResultSetMetaData rsmd = rs.getMetaData();
int columnCount = rsmd.getColumnCount();//获取了结果集的列数
if(rs.next()){
//创建一个Class对应的运行时类的对象
T t = clazz.newInstance();
for(int i = 0;i < columnCount;i++){
Object columnVal = rs.getObject(i + 1);//获取的具体列的列值
String columnLabel = rsmd.getColumnLabel(i + 1);//获取列别名
//通过反射装配属性值给t对象
Field field = clazz.getDeclaredField(columnLabel);
field.setAccessible(true);
field.set(t, columnVal);
}
return t;
}
} catch (Exception e) {
e.printStackTrace();
}finally{
//7.关闭资源
JDBCUtils.close(rs, ps, conn);
}
return null;
}
通过结果集rs,获取每一条记录的数据。
if(rs.next()){//获取一行数据
//获取具体的每一列数据
//方式一:
// int id = rs.getInt(1);
// String name = rs.getString(2);
// String email = rs.getString(3);
// Date birth = rs.getDate(4);
//方式二:推荐
//形参是结果集中列的名字,即为表中列的别名。我们使用列的别名(columnLabel)获取相应的列
int id = rs.getInt("id");
String name = rs.getString("name");
String email = rs.getString("myemail");
Date birth = rs.getDate("birth");
......}
标签:
原文地址:http://blog.csdn.net/xiaozhaorui/article/details/51945773