您的位置:首页 > 其它

JDBC基础

2016-07-18 21:29 197 查看
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的几个说明:

查询需要调用Prepared Statement 的 executeQuery() 方法,查询结果是一个 ResultSet实现类对象 2. 关于 ResultSet:代表结果集,ResultSet: 结果集封装了使用 JDBC 进行查询的结果. ResultSet 返回的实际上就是一张select 语句返回结果的数据库, 并且有一个指针指向数据表的第一条记录的前面。 3.可以调用 next() 方法检测下一行是否有效. 若有效该方法返回 true, 且指针下移. 相当于Iterator 对象的 hasNext() 和 next() 方法的结合体 4.当指针指向一行时, 可以通过调用 getXxx(int index) 或 getXxx(String columnName) 获取每一列的值. rs. getInt(1),//返回一条记录的第一位的数据

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");

......}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: