JDBC相关介绍、操作访问数据库_South.return的博客
目录
JDBC相关介绍
数据的持久化
数据库存储技术
数据访问
体系结构
编写步骤
获取数据库连接
要素一:Driver接口实现类
要素二:URL
要素三:用户名和密码
具体实现
操作和访问数据库
图解
数据库的调用方式
ResultSet
ResultSetMetaData
资源的释放
代码实现:通用的增删改操作
代码实现:通用的查询操作
总结
两种思想
两种技术
JDBC相关介绍
概述:JDBC(Java Database Connectivity)是一个独立于特定数据库管理系统、通用的SQL数据库的公共接口(一组API)。
数据的持久化
持久化(persistence):把数据保存到可掉电式存储设备中以供之后使用,持久化的实现过程大多通过各种关系数据库来完成
数据库存储技术
在Java中,数据库存取技术可分为如下几类:
1. JDBC直接访问数据库
2. JDO(Java Data Object )技术
3. 第三方O/R工具,如Hibernate, Mybatis等JDBC是java访问数据库的基石,JDO、Hibernate、MyBatis等只是更好的封装了JDBC。
数据访问
没有JDBC,java程序访问数据库 有了JDBC,java程序访问数据库 总结
体系结构
JDBC接口(API)包括两个层次:
1. 面向应用的API:Java API,抽象接口,供应用程序开发人员使用(连接数据库,执行SQL语句,获得结果
2. 面向数据库的API:Java Driver API,供开发商开发数据库驱动程序用JDBC是sun公司提供一套用于数据库操作的接口,java程序员只需要面向这套接口编程即可。
不同的数据库厂商,需要针对这套接口,提供不同实现。不同的实现的集合,即为不同数据库的驱动。(面向接口编程)
编写步骤
说明:ODBC(Open Database Connectivity,开放式数据库连接)
获取数据库连接
要素一:Driver接口实现类
Driver接口 java.sql.Driver接口是所有JDBC驱动程序需要实现的接口
这个接口是提供给数据库厂商使用的,不同数据库厂商提供不同的实现
在程序中不需要直接去访问实现了Driver接口的类
而是由驱动程序管理器类(java.sql.DriverManager)去调用这些Driver实现
Oracle的驱动:oracle.jdbc.driver.OracleDriver
mySql的驱动:com.mysql.jdbc.Driver加载驱动 加载JDBC驱动需调用Class类的静态方法forName(),向其传递要加载的JDBC驱动的类名
Class.forName(“com.mysql.jdbc.Driver”)注册驱动 DriverManager类是驱动程序管理器类,负责管理驱动程序 使用DriverManager.registerDriver(com.mysql.jdbc.Driver)来注册驱动 通常不用显式调用DriverManager类的registerDriver()方法来注册驱动程序类的实例
因为Driver接口的驱动程序类都包含了静态代码块,在这个静态代码块中,会调用
DriverManager.registerDriver()方法来注册自身的一个实例
要素二:URL
要素三:用户名和密码
- user,password可以用"属性名=属性值"方式告诉数据库
- 可以调用DriverManager类的getConnection()方法建立到数据库的连接
具体实现
使用配置文件的方式保存配置信息,在代码中加载配置文件 使用配置文件的好处 实现了代码和数据的分离,如果需要修改配置信息,直接在配置文件中修改,不需要深入代码 如果修改了配置信息,省去重新编译的过程 配置文件设计 因为操作数据库时会多次获取连接,所以就把获取连接和关闭资源的功能代码放在工具类中。
package util; //导包 import java.io.InputStream; import java.sql.*; import java.util.Properties; //操作数据库的工具类 public class JDBCUtils { //获取数据库的连接 public static Connection getConnection() throws Exception { //1.读取配置文件中的4个基本信息 InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream("jdbc.properties"); //文件内容读到集合 Properties prop = new Properties(); prop.load(is); //获取对应的值 String user = prop.getProperty("user"); String password = prop.getProperty("password"); String url = prop.getProperty("url"); String driverClass = prop.getProperty("driverClass"); //2.加载驱动 Class.forName(driverClass); //3.获取连接 Connection conn = DriverManager.getConnection(url, user, password); return conn; } //关闭资源 public static void closeResource(Connection conn, Statement ps){ try { if (ps != null) ps.close(); } catch (SQLException throwables) { throwables.printStackTrace(); } try { if (conn != null) conn.close(); } catch (SQLException throwables) { throwables.printStackTrace(); } } //关闭资源 public static void closeResource(Connection conn, Statement ps,ResultSet rs){ try { if (ps != null) ps.close(); } catch (SQLException throwables) { throwables.printStackTrace(); } try { if (conn != null) conn.close(); } catch (SQLException throwables) { throwables.printStackTrace(); }try { if (rs != null) rs.close(); } catch (SQLException throwables) { throwables.printStackTrace(); } } }
操作和访问数据库
概述:数据库连接被用于向数据库服务器发送命令和SQL语句,并接受数据库服务器返回的结果。其实一个数据库连接就是一个Socket连接
图解
数据库的调用方式
ResultSet
ResultSetMetaData
资源的释放
释放ResultSet,、Statement、Connection 数据库连接(Connection)是非常稀有的资源,用完后必须马上释放,如果Connection不能及时正确的关闭将导致系统宕机
Connection的使用原则是尽量晚创建,尽量早的释放
可以在finally中关闭,保证及时其他代码出现异常,资源也一定能被关闭
代码实现:通用的增删改操作
说明:获取数据库连接和资源关闭使用的是之前创建的工具类中的方法。
//通用的增删改操作 //sql中占位符的个数与可变形参的长度相同! public void update(String sql,Object ...args) { Connection conn = null; PreparedStatement ps = 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.执行 ps.execute(); }catch (Exception e){ e.printStackTrace(); }finally { //5.资源关闭 JDBCUtils.closeResource(conn, ps); } }
代码实现:通用的查询操作
说明:查询操作有返回值,我们一般使用创建对象,再给对象赋值的方式输出结果。
//结果集的输出方式 //方式一: //System.out.println("id="+id+" name="+name+" email="+email+" Date:"+birth); //方式二: //Object[] date = new Object[]{id,name,email,birth}; //方式三:将数据封装为一个对象(推荐)查询一条记录:
//针对于不同表的通用查询操作,返回表中一条记录 public <T> T getInstance(Class<T> clazz,String sql,Object ...args){ Connection conn = null; PreparedStatement ps = null; ResultSet rs = null; try { //获取连接 conn = JDBCUtils.getConnection(); //预编译sql语句,返回PreparedStatement实例 ps = conn.prepareStatement(sql); //填充占位符 for (int i = 0; i < args.length; i++) { ps.setObject(i+1,args[i]); } //执行:捕获结果集 rs = ps.executeQuery(); //获取结果集的元数据 ResultSetMetaData rsmd = rs.getMetaData(); //获取列数 int columnCount = rsmd.getColumnCount(); if (rs.next()){ //创建此Class对象所表示类的实例 T t = clazz.newInstance(); //处理结果集一行数据中的每一个列 for (int i = 0; i < columnCount; i++) { //获取每个列的列值:通过ResultSet Object columnValue = rs.getObject(i + 1); //获取每个列的列名:通过ResultSetMetaData String columnLabel = rsmd.getColumnLabel(i + 1); //通过反射,将对象指定名columnName的属性赋值为指定的值columnValue Field field = clazz.getDeclaredField(columnLabel); field.setAccessible(true); field.set(t,columnValue); } return t; } }catch (Exception e){ e.printStackTrace(); }finally { //释放资源 JDBCUtils.closeResource(conn,ps,rs); } return null; }查询多条记录:
//针对于不同表的通用查询操作,查询多条记录 public <T> List<T> getForList(Class<T> clazz,String sql,Object ...args){ Connection conn = null; PreparedStatement ps = null; ResultSet rs = null; try { //获取连接 conn = JDBCUtils.getConnection(); //预编译sql语句,返回PreparedStatement实例 ps = conn.prepareStatement(sql); //填充占位符 for (int i = 0; i < args.length; i++) { ps.setObject(i+1,args[i]); } //执行:捕获结果集 rs = ps.executeQuery(); //获取结果集的元数据 ResultSetMetaData rsmd = rs.getMetaData(); //获取列数 int columnCount = rsmd.getColumnCount(); //创建集合对象 ArrayList<T> list = new ArrayList<>(); while (rs.next()){ //创建此Class对象所表示类的实例 T t = clazz.newInstance(); //处理结果集一行数据中的每一个列:给t对象指定的属性赋值 for (int i = 0; i < columnCount; i++) { //获取每个列的列值:通过ResultSet Object columnValue = rs.getObject(i + 1); //获取每个列的列名:通过ResultSetMetaData String columnLabel = rsmd.getColumnLabel(i + 1); //通过反射,将对象指定名columnName的属性赋值为指定的值columnValue Field field = clazz.getDeclaredField(columnLabel); field.setAccessible(true); field.set(t,columnValue); } //添加对象到集合 list.add(t); } return list; }catch (Exception e){ e.printStackTrace(); }finally { //释放资源 JDBCUtils.closeResource(conn,ps,rs); } return null; }
总结
两种思想
- 面向接口编程的思想
- ORM思想(object relational mapping)
一个数据表对应一个java类
表中的一条记录对应java类的一个对象
表中的一个字段对应java类的一个属性两种技术
- JDBC结果集的元数据:ResultSetMetaData
获取列数:getColumnCount()
获取列的别名:getColumnLabel()- 通过反射,创建指定类的对象,获取指定的属性并赋值














登录后可发表评论
点击登录