zoukankan      html  css  js  c++  java
  • JDBC

     

    重点:

    JDBC使用步骤:

    1.导入JDBC驱动jar

    2.注册JDBC驱动
    -Class.forname("驱动程序类名")
    3.获得Connection对象
    -需要3个参数:url,username,password
    -连接到数据库
    4.创建statment(语句)对象
    -conn.createStatment()方法创建对象
    -用于执行SQL语句
    -execute(ddl) 执行任何 SQL,常用执行DDL
    -executeUpdate(dml) 执行DML语句,如:insert,update,delete
    -executeQuery(dql) 执行DQL语句,如:select
    5.处理SQL执行结果
    -execute(ddl) 如果没有异常则创建成功
    -executeUpadte(dml) 返回数字,表示更新“行”数量,抛出异常则失败
    -executeQuery(dql) 返回ResultSet(结果集)对象,代表2维查询结果
    使用for遍历处理,如果查询失败则抛出异常
    6.关闭数据库链接
    -conn.close

    往下DAO层

    1. JDBC原理

    1.1.1. JDBC是什么

    Java Database Connectivity:Java访问数据库的解决方案。

    JDBC是Java应用程序访问数据库的里程碑式解决方案。Java研发者希望用相同的方式访问不同的数据库,以实现与具体数据库无关的Java操作界面。

    JDBC定义了一套标准接口,即访问数据库的通用API,不同的数据库厂商根据各自数据库的特点去实现这些接口。

    图-1应用、JDBC和数据库的关系

    1.1.2. JDBC接口及数据库厂商实现

    图-2 通过JDBC访问数据库的过程

    JDBC中定义了一些接口:

    1、驱动管理:

    • DriverManager

    2、连接接口

    • Connection
    • DatabasemetaData

    3、语句对象接口

    • Statement
    • PreparedStatement
    • CallableStatement

    4、结果集接口

    • ResultSet
    • ResultSetMetaData

    1.1.4. Driver接口及驱动类加载

    要使用JDBC接口,需要先将对应数据库的实现部分(驱动)加载进来。

    驱动类加载方式(Oracle):

     
    1. Class.forName("oracle.jdbc.driver.OracleDriver");

    这条语句的含义是:装载驱动类,驱动类通过static块实现在DriverManager中的“自动注册”。

    1.1.5. Connection接口

    Connection接口负责应用程序对数据库的连接,在加载驱动之后,使用url、username、password三个参数,创建到具体数据库的连接。

     
    1. Class.forName("oracle.jdbc.OracleDriver")
    2. //根据url连接参数,找到与之匹配的Driver对象,调用其方法获取连接
    3. Connection conn = DriverManager.getConnection(
    4. "jdbc:oracle:thin:@192.168.0.26:1521:tarena",
    5. "openlab","open123");

    需要注意的是:Connection只是接口,真正的实现是由数据库厂商提供的驱动包完成的。

    1.1.6. Statement接口

    Statement接口用来处理发送到数据库的SQL语句对象,通过Connection对象创建。主要有三个常用方法:

     
    1. Statement stmt=conn.createStatement();
    2. //1.execute方法,如果执行的sql是查询语句且有结果集则返回true,如果是非查询语句或者没有结果集,返回false
    3. boolean flag = stmt.execute(sql);
    4. //2.执行查询语句,返回结果集
    5. ResultSetrs = stmt.executeQuery(sql);
    6. //3.执行DML语句,返回影响的记录数
    7. int flag = stmt.executeUpdate(sql);

    1.1.7. ResultSet接口

    执行查询SQL语句后返回的结果集,由ResultSet接口接收。

    常用处理方式:遍历 / 判断是否有结果(登录)。

     
    1. String sql = "select * from emp";
    2. ResultSetrs = stmt.executeQuery(sql);
    3. while (rs.next()) {
    4.     System.out.println(rs.getInt("empno")+",“
    5. +rs.getString("ename") );
    6. }

    查询的结果存放在ResultSet对象的一系列行中,指针的最初位置在行首,使用next()方法用来在行间移动,getXXX()方法用来取得字段的内容。

    两种不同实现

    1.2.1. Oracle实现

    在Java程序中访问不同数据库,需要下载对应数据库的驱动。Oracle数据库提供的驱动为ojdbc6.jar或者ojdbc14.jar,在开发时需要将驱动类加载到项目中,通过设置MyEclipse的Build Path选项。

    使用时就可以如下方式加载驱动类了:

     
    1. Class.forName("oracle.jdbc.driver.OracleDriver");

    1.2.2. MySQL实现

    MySQL对应的数据库驱动名为mysql-connector-java-5.0.4-bin.jar(不同版本可能有不同名称),将驱动类加载到项目中同样通过设置MyEclipse的Build Path选项。

    加载驱动类的方式:

     
    1. Class.forName("com.mysql.jdbc.Driver");

    2.1. 连接管理

    2.1.1. 通过连接工具类获取连接

    在工程中,通常编写一个访问数据库的工具类,此后所有访问数据库的操作,都从工具类中获取连接。

    实现工具类的两种方式:

    • 直接把数据配置写在工具类。
    • 把数据库配置写在一个properties属性文件里,工具类读入属性文件,逐行获取数据库参数。

    建议使用第二种。

    2.1.2. 通过属性文件维护连接属性

    db.properties的内容:

     
    1. #驱动类名
    2. jdbc.driver=oracle.jdbc.driver.OracleDriver
    3. #连接字符串
    4. jdbc.url=jdbc:oracle:thin:@192.168.0.26:1521:tarena
    5. #访问数据库的用户名
    6. jdbc.user=openlab
    7. #访问数据库的密码
    8. jdbc.password=open123

    注意:在properties文件中,#符号表示注释。

    2.1.3. 从类路径中加载属性文件

    定义好db.properties之后,需要在Java程序中找到它,可以使用从类路径加载的方式:

     
    1. //属性文件所在的位置
    2. String path = "com/tarena/dms/daodemo/v2/db.properties";
    3. //获得当前类的路径,加载指定属性文件
    4. properties.load(DBUtility.class.getClassLoader()
    5. .getResourceAsStream(path));

    2.1.4. 连接的关闭

    在工具类中定义公共的关闭连接的方法,所有访问数据库的应用,共享此方法。当完成功能,关闭连接。

     
    1. protected static void closeConnection(Connection con) {
    2.         if (con != null) {
    3.             try {
    4.                 con.close();
    5.             } catch (SQLException e) {
    6. e.printStackTrace();
    7.             }
    8.         }
    9.     }

    JDBC技术优化连接池技术

    为什么要使用连接池(作用)

    数据库连接的建立及关闭资源消耗巨大。传统数据库访问方式:一次数据库访问对应一个物理连接,每次操作数据库都要打开、关闭该物理连接, 系统性能严重受损。

    解决方案:数据库连接池(Connection Pool)。

    系统初始运行时,主动建立足够的连接,组成一个池.每次应用程序请求数据库连接时,无需重新打开连接,而是从池中取出已有的连接,使用完后,不再关闭,而是归还。


    连接池中连接的释放与使用原则

    • 应用启动时,创建初始化数目的连接
    • 当申请时无连接可用或者达到指定的最小连接数,按增量参数值创建新的连接
    • 为确保连接池中最小的连接数的策略:
    1. 动态检查:定时检查连接池,一旦发现数量小于最小连接数,则补充相应的新连接,保证连接池正常运转
    2. 静态检查:空闲连接不足时,系统才检测是否达到最小连接数
    • 按需分配,用过归还,超时归还

    连接池也只是JDBC中定义的接口

    2.2.2. 使用Apache DBCP连接池

    DBCP(DataBase connection pool):数据库连接池,是Apache的一个 Java 连接池开源项目,同时也是 Tomcat 使用的连接池组件。相当于是Apache开发的针对连接池接口的一个实现方案。

    连接池是创建和管理连接的缓冲池技术,将连接准备好被任何需要它们的应用使用。

    图-4连接池在数据访问中的应用

    使用Apache DBCP需要两个jar包文件:

    • commons-dbcp-1.4.jar 连接池的实现
    • commons-pool-1.5.jar 连接池实现的依赖库

    将上述两个文件在MyEclipse的Build Path选项中导入到项目。

    2.2.3. 通过DataSource获取连接

    先通过属性文件获取连接池参数,然后加载这些参数,获得连接:

     
    1. //创建数据源对象
    2. private static BasicDataSourcedataSource = new BasicDataSource();
    3. //加载参数
    4. dataSource.setDriverClassName(driveClassName);
    5. dataSource.setUrl(url);
    6. dataSource.setUsername(username);
    7. dataSource.setPassword(password);
    8. //获得连接
    9. Connection conn = dataSource.getConnection();

    2.2.4. 连接池参数

    常用参数有:

    • 初始连接数
    • 最大连接数
    • 最小连接数
    • 每次增加的连接数
    • 超时时间
    • 最大空闲连接
    • 最小空闲连接

    根据应用需要,设置合适的值。

    2.3. 异常处理

    2.3.1. SQLException简介

    Java.sql.SQLException是在处理JDBC时常见的exception对象,用来表示JDBC操作过程中发生的具体错误;

    一般的SQLException都是因为操作数据库时出错 , 比如Sql语句写错,或者数据库中的表或数据出错。

    常见异常:

    • 登录被拒绝
    • 可能原因:程序里取键值对信息时的大小写和属性文件中不匹配
    • 列名无效
    • 可能原因:查找的表和查找的列不匹配
    • 无效字符
    • 可能原因:SQL语句语法有错 , 比如语句结尾时不能有分号
    • 无法转换为内部表示
    • 可能原因:结果集取数据时注意数据类型。
    • 表或者视图不存在
    • 检查SQL中的表名是否正确
    • 不能将空值插入
    • 检查执行insert操作时,是否表有NOT NULL约束,而没有给出数据
    • 缺少表达式
    • 检查SQL语句的语法
    • SQL 命令未正确结束
    • 检查SQL语句的语法
    • 无效数字:
    • 企图将字符串类型的值填入数字型而造成,检查SQL语句

    其他可能出现的异常

    • 文件找不到
    • 可能原因:db.properties文件路径不正确

    注意: 新增数据后务必要commit, 否则Java程序运行查询后找不到数据。

    2.3.2. 处理SQLException

    SQLException属于Checked Exception,必须使用try…catch或throws明确处理。

     
    1. public static synchronized Connection getConnection() throws SQLException {
    2. //语句,省略
    3. }

    或者:

     
    1. try {
    2.     //语句,省略    
    3. } catch (SQLException e) {
    4.     e.printStackTrace();//追踪处理
    5. //throw new RuntimeException(e);//或者抛出
    6. }

    DAO

    2.1. 什么是DAO

    2.1.1. DAO封装对数据的访问

    DAO (Data Access Object):数据访问对象,是建立在数据库和业务层之间,封装所有对数据库的访问。

    目的:数据访问逻辑和业务逻辑分开。

    图-3 DAO在多层结构中的位置

    为了建立一个健壮的Java应用,需将所有对数据源的访问操作抽象封装在一个公共API中,需要:

    • 建立一个接口,接口中定义了应用程序中将会用到的所有事务方法
    • 建立接口的实现类,实现接口对应的所有方法,和数据库直接交互

    在应用程序中,当需要和数据源交互时则使用DAO接口,不涉及任何数据库的具体操作。DAO通常包括:

    1. 一个DAO工厂类;

    2. 一个DAO接口;

    3. 一个实现DAO接口的具体类;

    4. 数据传递对象(实体对象(Entity)或值对象(Value Object,简称VO)).

    2.1.2. 实体对象

    DAO层需要定义对数据库中表的访问。

    对象关系映射(ORM:Object/Relation Mapping)描述对象和数据表之间的映射,将Java程序中的对象对应到关系数据库的表中:

    • 表和类对应
    • 表中的字段和类的属性对应
    • 记录和对象对应

    编写DAO

    2.2.1. 查询方法

     
    1.     public Account findById(Integer id) throws SQLException {
    2.         Connection conn = getConnection();
    3.         String sql = SELECT_BY_ID; //预先定义好的SQL查询语句
    4.         PreparedStatementps = conn.prepareStatement(sql);
    5.         ps.setInt(1, id);//传入参数
    6.         ResultSetrs = ps.executeQuery();
    7.         Account account = null;
    8.         while(rs.next()){//处理结果集
    9.             account = new Account();
    10.             account.setId(rs.getInt("ACCOUNT_ID"));
    11.             //设置account对象所有的属性,略        }
    12.         return account;
    13.     }

    2.2.2. 更新方法

     
    1.     publicboolean update(Account account) throws SQLException {
    2.         Connection conn = getConnection();
    3.         String sql = UPDATE_STATUS; //预先定义好的SQL语句
    4.         PreparedStatementps = conn.prepareStatement(sql);
    5.         ps.setInt(1,account.getId());//传入参数
    6. ps.setString(2, account.getStatus());
    7.         int flag= ps.executeUpdate();
    8.         return (flag>0 ? true : false);
    9.     }

    2.2.3. 异常处理机制

    多层系统的异常处理原则:

    • 谁抛出的异常,谁捕捉处理,因为只有异常抛出者,知道怎样捕捉处理异常;
    • 尽量在当前层中捕捉处理抛出的异常,尽量不要抛出到上层接口;
    • 尽量在每层中封装每层的异常类,这样可准确定位异常抛出的层;
    • 如异常无法捕捉处理,则向上层接口抛出,直至抛给JVM,尽量避免;
  • 相关阅读:
    MYBATIS 的parameter
    深入了解MyBatis参数
    js之onload事件的一点使用心得
    js中document.write的那点事
    MyBatis直接执行SQL查询及批量插入数据
    ng 服务
    ng json格式的序列化和反序列化
    ng 自定义过滤器的创建和使用
    ng 过滤器
    ng 双向数据绑定 实现 注册协议效果
  • 原文地址:https://www.cnblogs.com/mike-mei/p/7631725.html
Copyright © 2011-2022 走看看