Oracle (08)JDBC

版权声明:cxyo.cn https://blog.csdn.net/weixin_44075537/article/details/85034267

JDBC

sum公司, 为了简化和统一Java语言对于数据库的操作, 与各大数据库厂商协同制订了一系列的 接口 , �由各大数据库厂商对这套接口进行实现.

jar文件:

一般使用Jar文件 , 使用在两个操作:

  1. 把写好的代码, 封装为jar应用程序, 可以双击使用 , 例如QQ等等桌面应用程序

  2. 封装一系列的class , 在编写代码时, 可以将这个jar文件引入到新的项目中 , 用来引用这一系列的类 !

引入jar文件的方式 *****

  1. 在项目中 右键新建文件夹 , 命名为lib (右击项目根目录, 点击new–>folder)
  2. 将要引入的jar文件粘贴到文件夹中
  3. 右击文件夹中的jar文件
    选择: build-path --> add to build path

使用jdbc 操作数据库的前提

确保windows中的oracleXETNSListener服务是开启的

如果服务关闭, 且无法启动:

原因: 
    -   防火墙未关闭
    -   杀毒软件未卸载 , (会报毒 / 优化开启启动项)
    -   更改过计算机名称
    -   自己手动关闭

终极解决方案:  

    先尝试重装数据库, 然后做系统!

数据库连接地址 *****

本机地址:

-   127.0.0.1
-   localhost

数据库默认侦听端口号: 1521

数据库连接的完整的地址:

格式: 

    主协议:子协议//主机地址:端口号/数据库名称

    例如: 

    -   oracle数据库的连接地址: 
        jdbc:oracle:thin:@127.0.0.1:1521/xe

    -   mysql数据库的连接地址:
        jdbc:mysql://127.0.0.1:3306/数据库名称

JDBC连接步骤 *****

  1. 加载数据库驱动
    驱动地址: oracle.jdbc.OracleDriver
    oracle.jdbc.driver.OracleDriver

    Class.forName(“oracle.jdbc.driver.OracleDriver”);

  2. 通过驱动管理器(DriverManager类) 获取连接数据库的连接对象(getConnection())

Connection conn = DriverManager.getConnection(“jdbc:oracle:thin:@localhost:1521/xe”,“system”,“123456”);

  1. 通过连接对象 , 获取SQL的执行环境(Statement)
    Statement state = conn.createStatement();

  2. 通过执行环境 执行SQL语句
    state.execute(“insert into dongfei values(dongfei_id_seq.nextval,‘董飞加长版’,88)”);

  3. 释放资源, 关闭连接(需要释放资源的有两个,1执行环境 2连接对象)
    state.close();
    conn.close();

DriverManager类

1.获取数据库连接

static Connection getConnection(url,username,password);

  • 参数1. 数据库的连接地址
  • 参数2. 数据库的帐号
  • 参数3. 数据库的密码

Connection类

创建一个SQL执行环境:

Statement createStatement()

Statement类

  1. boolean execute(String sql):
    用来执行一条SQL语句
    返回值为boolean类型, 返回true表示是查询语句

  2. int executeUpdate(String sql):
    用来执行DML语句 (update|insert|delete)
    返回值为int类型, 表示当前执行的SQL语句 , 对数据库表格的影响行数!

  3. ResultSet executeQuery(sql):
    用来执行SELECT语句 ,

    返回的是ResultSet类型的数据, 也就是结果集

使用executeUpdate操作数据库

Class.forName("oracle.jdbc.driver.OracleDriver");
Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521/xe","system","123456");
Statement state = conn.createStatement();
int count = state.executeUpdate("delete from dongfei");
System.out.println("共删除了:\t"+count+"\t条数据");
state.close();
conn.close();

DriverManager类

1.获取数据库连接

static Connection getConnection(url,username,password);

  • 参数1. 数据库的连接地址
  • 参数2. 数据库的帐号
  • 参数3. 数据库的密码

Connection类

创建一个SQL执行环境:

Statement createStatement()

Statement类

  1. boolean execute(String sql):
    用来执行一条SQL语句
    返回值为boolean类型, 返回true表示是查询语句

  2. int executeUpdate(String sql):
    用来执行DML语句 (update|insert|delete)
    返回值为int类型, 表示当前执行的SQL语句 , 对数据库表格的影响行数!

  3. ResultSet executeQuery(sql):
    用来执行SELECT语句 ,

    返回的是ResultSet类型的数据, 也就是结果集

ResultSet

结果集 !

常用方法:

游标滚动的方法: 

    1.  next(): 将游标下移,  移动成功返回true , 移动失败返回false , 下一行不存在会导致游标移动失败
    2.  privious(): 将游标上移,  移动成功返回true , 移动失败返回false , 上一行不存在会导致游标移动失败
    3.  absolute(int rownum) 移动到指定行
    4.  beforeFirst(): 移动到第一行
    5.  afterLast(): 移动到最后一行

因为next方法, 当下一行移动失败, 数据不存在时, 会返回false , 那么我们可以使用它循环遍历结果集:

while(resultSet.next()){
    resultSet.getXXX
    ...
}



获取当前游标所在行数据的方法:

    getXXX方法: 

    需要获取某一列的数据时, 使用getXXX方法 , 传入列名即可!

    int value = resultSet.getInt(列名);
    int value = resultSet.getInt(int 列的索引);


    String value = resultSet.getString(列名);
    String value = resultSet.getString(列的索引);

    Object value = resultSet.getObject(列名);
    Object value = resultSet.getObject(列的索引);

SQL注入

用户输入的内容, 在SQL语句拼接过程中, 完成了一条逻辑发生变化的新的SQL语句 !

例如:

原SQL语句拼接为:

String sql = "select id from user15 where username='"+user.getUserName()+"' and password='"+user.getPassWord()+"'";

用户输入的帐号密码分别为:

请输入您的帐号:
suibian
请输入您的密码:
suibian’ or ‘1’='1
组成的SQL语句:
select id from user15 where username=‘suibian’ and password=‘suibian’ or ‘1’=‘1’

解决SQL注入问题

使用预编译SQL语句 进行参数的传递

更改执行环境 Statement

使用新的环境: PreparedStatement

在通过连接对象 获取一个预编译的SQL环境(PreparedStatement)时, 需要传递 一个SQL语句 !
在这个语句中 可以出现? , ? 表示准备填充的参数值!

使用步骤:

1.  通过连接对象, 获得一个预编译的SQL执行环境

    PreparedStatement state conn.prepareStatement(sql);

    例如: 
        String sql = "select id from user15 where username=? and password=?";

        PreparedStatement state  = conn.prepareStatement(sql);



2.向预编译参数列表中 传递值: 

    预编译的SQL语句中可以包含0-n个问号, 每一个问号表示一个需要传递的值 
    我们通过PreparedStatement它的setXXX方法,来完成参数的传递
    在传递参数时, 需要指定问号的索引, 问号的索引从1开始            

    例如:
        state.setString(1,user.getUserName());
        state.setString(2,user.getPassWord());

3.  执行语句:
        ResultSet result = state.executeQuery();

PreparedStatement

常用方法:

填充预编译的参数: 

-   setXXX(问号索引,值)
    向预编译的SQL的?中传递值 
    参数1. 问号的索引 ,从1开始
    参数2. 填充到? 中的值

-   execute()
-   executeUpdate();
-   executeQuery();
    上面的三个方法 与 Statement中方法的含义一致, 只不过不存在参数!

Properties类与Properties文件

Properties是Java中的一个类, 是Map集合的子类, 可以存储和获取键值对!

在Java中它也对应一种文件格式,(xxx.properties)

可以很快速的将一个合理的properties文件 转换为内存中的对象

这个类 常用的地方:

1.  应用程序的配置文件
2.  程序国际化中

如何编写properties文件

在src目录下, 创建一个文件, 命名为xxx.properties

在文件中编写键值对:

一行表示一个键值对 , 键与值之间使用等号连接

例如:

username=xxxxx
password=xxxxx

如何将一个properties文件转换为properties对象

  1. 获取一个指向properties文件的输入流
    如果文件存储在src的根目录, 可以通过如下方式快速获取:
    InputStream is = class.getClassLoader().getResourceAsStream(“xxx.properties”);

  2. 创建一个Properties对象, 并调用load方法,传入流, 进行数据的读取
    Properties ppt = new Properties();
    ppt.load(is);

  3. 从对象中取出键值对

    String value = ppt.getProperty(key)

事务

在SQL> dml操作, 需要结束事务!

JDBC中 , 事务是自动提交的, 每一条dml语句的执行, 会立即提交事务!

但是我们在一些逻辑中, 也存在需求, 需要自己手动控制事务!

JDBC中事务操作的三个方法:

通过连接对象(Connection对象)操作这个三个方法:

-   setAutoCommit(boolean flag)
    设置事务的提交方式是否为自动.  默认为true 表示自动提交, false表示手动提交

    当设置false以后, 在jdbc中每一条的DML语句 不会再自动提交事务!

-   commit(): 提交事务

-   rollback(): 回滚事务!

银行转账的案例

董飞买高帆的肉, 付款的场景

create table test15_x(id number,name varchar2(30),rmb number);

未加入事务时, 错误的案例

Connection conn = DBUtil2.getConnection();
Statement state = conn.createStatement();

System.out.println("董飞高高兴兴的去买肉~ ");
System.out.println("董飞 共消费:大腰子3个 , 慈母手中线5个");

state.executeUpdate("update test15_x set rmb=250000 where id=1");

if(1==1) {
    throw new RuntimeException("停电了, 哈哈哈哈哈哈");
}



state.executeUpdate("update test15_x set rmb=750050 where id=2");

System.out.println("执行完毕");

事务手动提交 修复逻辑BUG

Connection conn = DBUtil2.getConnection();
//设置了事务的手动提交
conn.setAutoCommit(false);
Statement state = conn.createStatement();

System.out.println("董飞高高兴兴的去买肉~ ");
System.out.println("董飞 共消费:大腰子3个 , 慈母手中线5个");

state.executeUpdate("update test15_x set rmb=250000 where id=1");

if(2==1) {
    throw new RuntimeException("停电了, 哈哈哈哈哈哈");
}

state.executeUpdate("update test15_x set rmb=750050 where id=2");
conn.commit();

System.out.println("执行完毕");

批处理

把多条SQL语句 放到一组 一起执行!

对于多条的SQL语句, 采用批处理, 对于数据库的更改是一次!

通过Statement进行操作

addBatch(sql); 将SQL语句加入批处理

executeBatch():执行一批SQL语句!

批处理是不存在返回值 !

批处理与事务的区别:

批处理: 只是将多条SQL语句 放到一起一次执行, 多条SQL语句之间不存在任何的关系, 一个SQL语句发生错误, 不会影响其他的SQL语句的操作!

事务: 将多条SQL语句看作一个整体, 要么一起成功,要么一起失败 !

连接池

实现连接池

使用两个Jar文件来实现:

文件是apache提供的 : dbcp.jar(连接池) pool.jar(连接池实现的依赖库)
  1. 这个线程池会预读本地文件 , 进行数据库的连接配置:

    需要在src根目录, 创建一个properties文件:

    #驱动地址
    driverClassName=oracle.jdbc.OracleDriver
    #连接地址
    url=jdbc:oracle:thin:@localhost:1521
    #帐号
    username=system
    #密码
    password=123456
    
    #初始化的连接数量
    initialSize=10
    #最大的连接数量
    maxActive=200
    #最大空闲连接数量
    maxIdle=10
    #最小的空闲连接诶数量
    minIdle=1
    #超时时间(毫秒)
    maxWait=15000
    
  2. 在Java代码中, 将上面的配置文件, 变为Properties对象

    InputStream is = DBCPUtil.class.getClassLoader().getResourceAsStream(“dbcp.properties”);
    Properties ppt = new Properties();
    //加载一个流指向的文件
    ppt.load(is);

  3. 通过连接池工厂对象 获取一个连接池
    DataSource ds = BasicDataSourceFactory.createDataSource(ppt);

  4. 获取连接对象

    Connection conn = ds.getConnection();

  5. 使用完毕连接 , 正常关闭连接即可, 连接池会自动回收!

礼拜天复习:

  1. 网络编程+多线程 (TCP+多线程实现)
  2. 集合HashMap
  3. jdbc

<<学员考试管理系统>>

猜你喜欢

转载自blog.csdn.net/weixin_44075537/article/details/85034267
今日推荐