`

day13 JDBC 基础 事务控制 大数据 批处理

 
阅读更多

JDBC : Java Database Connectivity
什么是JDBC? 为什么学习JDBC? Java程序中操作数据库数据,必须通过JDBC接口

JDBC就像一座桥,连接Java程序与数据库

进行JDBC开发
1、学习JDBC接口规范 java.sql javax.sql 接口如何使用
2、在工程中导入 相应数据库驱动(JDBC实现)

核心JDBC接口规范
DriverManager 驱动管理器
Connection 连接
Statement 操作状态 (子接口 PreparedStatement、CallableStatement)
ResultSet 结果集

第一个JDBC程序
1、搭建数据库环境
启动mysql服务,连接mysql
创建数据库 create database day13;
切换数据库 use day13;
创建数据表
create table users(
   id int primary key not null ,
   name varchar(40),
   pwd varchar(40),
   email varchar(100)
);

向数据表插入几条数据
insert into users values(1,'aaa','111','aaa@itcast.cn');
insert into users values(2,'bbb','111','bbb@itcast.cn');
insert into users values(3,'ccc','111','ccc@itcast.cn');
insert into users values(4,'ddd','111','ddd@itcast.cn');

2、创建web工程 day13, 导入数据库驱动
将jar包复制 WEB-INF/lib

3、新建java程序 使用JDBC接口规范连接数据库
步骤一:装载驱动 DriverManager.registerDriver(new Driver());
步骤二:建立连接 Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/day13","root","123");
步骤三:将sql语句发送给数据库执行 Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("select * from users");
while(rs.next()){
   sysout(rs.getString("name"));
}
步骤四:释放资源 rs.close(); stmt.close();  conn.close();

JDBC API 详解
1、DriverManager 驱动管理器
DriverManager.registerDriver(new Driver())
DriverManager.getConnection(url, user, password)
* DriverManager 可以加载多个数据库驱动 同时加载Mysql Oracle DB2 ...  getDriver(String url)
* 可以加载多个驱动,连接数据库时,需要url ----- 包含JDBC协议 根据协议不同识别使用哪个数据库驱动

在实际开发中,并不会直接去写DriverManager.registerDriver() ------ 所有数据库厂商默认调用加载驱动
在开发中 只需要编写Class.forName("com.mysql.jdbc.Driver");
原因有两个:原因一:DriverManager.registerDriver(new Driver()) 会导致驱动加载两次 ;原因二:如果使用new Driver() 会使java程序依赖具体数据库API
* 在JDBC编程时,不需要import 具体数据库驱动 包 ,都import ---- java.sql 、javax.sql

2、连接任何数据库 编写JDBCURL
Mysql URL : jdbc:mysql://localhost:3306/day13 通过?传递参数
Oracle写法:jdbc:oracle:thin:@localhost:1521:sid

编写JDBC程序连接Oracle
1) 启动Oracle Listener和service两个服务
* Listener 服务默认端口8080  (和tomcat默认端口一样)
2) 开启cmd窗口
Oracle内部超级用户叫 system
sqlplus system/123
* 在Oracle内部 每个用户一个数据库空间

创建表和插入记录后,必须提交事务(Oracle默认不自动提交的,mysql默认自动提交的)commit;
3) 编写JDBC程序
导入数据库驱动 Oracle驱动 ----- 在Oracle安装目录找到 C:\oraclexe\app\oracle\product\10.2.0\server\jdbc\lib\ojdbc14.jar

* 编写JDBC程序时,数据库程序不同 driverClass、url、user 、password

JDBC连接MySQL 简写 如果使用localhost:3306 省略 : jdbc:mysql:///day13

常用属性:useUnicode=true&characterEncoding=UTF-8
jdbc:mysql:///day13?useUnicode=true&characterEncoding=UTF-8 参数拼接URL后面 ,参数指定客户端与服务器连接使用字符集
* 当客户端编码 与服务器端编码不同,通过参数设置编码
例如:客户端gbk 服务器utf8 ---- useUnicode=true&characterEncoding=gbk (这里字符集与客户端编码一致)


3、Connection接口 ---- JDBC连接表示接口
* Connection接口一个对象 代表 一个数据库 连接
作用两点:
1) 获得操作数据库Statement对象
createStatement() ----- Statement 获得普通操作状态对象
prepareStatement(String sql) ----- PreparedStatement(是Statement子接口) 预编译状态对象
prepareCall(String sql)  ------ CallableStatement(是PreparedStatement子接口) 操作数据库内部存储过程的
* Statement对象可以向数据库发送sql语句,获得ResultSet结果集

2) 进行事务控制
setAutoCommit(boolean) ; 开启一个事务
commit(); 提交一个事务
rollback(); 回滚一个事务

4、Statement接口 ---- 代表一个操作状态
作用:操作数据库SQL语句、调用存储过程
executeQuery(String sql) :用于向数据发送查询语句。select语句,返回值ResultSet 结果集
executeUpdate(String sql):用于向数据库发送insert、update或delete语句 返回值int 受影响行数
execute(String sql):用于向数据库发送任意sql语句 --- 建立数据库 建立数据表,增删改查 --- 返回值boolean
* sql结果是ResultSet 返回true --- 否则false

批处理 ---- 一次执行多条sql
addBatch(String sql) :把多条sql语句放到一个批处理中。
executeBatch():向数据库发送一批sql语句执行。

5、ResultSet
while(rs.next){
  // 根据数据表列类型 --- 转换表规则,调用java中相应getXXX方法
}

思考:如果一个SQL语句只返回一行数据 , 还用使用while?
if(rs.next){ // 因为结果只有1行,存在,不存在
}

------------------------------------------------------------------------
可滚动结果集 ---- 创建Statement时设置结果集可滚动性
createStatement(int resultSetType, int resultSetConcurrency)
resultSetType - 结果集类型,它是 ResultSet.TYPE_FORWARD_ONLY(只支持next 不支持其它滚动)、ResultSet.TYPE_SCROLL_INSENSITIVE(无法看到更改后数据) 或 ResultSet.TYPE_SCROLL_SENSITIVE(看到更改后数据) 之一
resultSetConcurrency - 并发类型;它是 ResultSet.CONCUR_READ_ONLY(只读) 或 ResultSet.CONCUR_UPDATABLE(可修改) 之一

释放资源写入finally 代码块 ----- finally中代码一定执行

练习:编写程序对users表进行增删改查操作

练习:编写工具类简化CRUD操作。(异常暂不处理)

JAVAEE(Java Enterprise Edition ) 模式 : DAO模式
23种设计模式
* JavaEE体系结构
* MVC 和 JavaEE经典三层结构 由两拨人分别提出的
三层结构中业务层、数据持久层 ---- Model
三层结构中web层 Servlet ---- Controller
三层结构中web层 JSP ---- View

DAO模式:数据层用DAO模式完全将数据源底层实现封装起来,业务层开发人员不需要了解底层实现。通过对象操作完成对数据源增删改查!
Business Object :代表数据的使用者 (业务层程序)
DataAccessObject :抽象并封装了对底层数据源的操作 (数据层程序)
DataSource 数据源 --- mysql数据库
TransferObject 表示数据的Java Bean

BussinessObject 通过 将transferObject 传递 DataAccessObject 完成对DataSource的增删改查

用DAO模式重写对users表增删改查 !
在service包中创建 BusinessObject对象
在dao包中 创建 DataAccessObject对象
在domain包中 创建 TransferObject 对象

* 业务层通过对象的操作,完成对数据源增删改查
DAO模式,将增删改查sql封装起来,方法参数和返回值都是对象,业务层通过操作这些对象,完成对数据库增删改查!

登陆程序
login.jsp ---- LoginServlet(web层) ---- UserService(业务层) ---- UserDAO(数据层)

SQL注入
在form中提交信息时,根据SQL语法特殊性,编写关键字,而这些关键字拼接到sql中会改变原来sql运行效果 --- 达到攻击目的
String sql = "select * from users where name = '' and pwd =''";
如果用户输入关键内容,改变登陆结果
用户名: ddd' or '1'='1
密码:xxx
select * from users where name = 'ddd' or '1'='1' and pwd ='xxx'

用注释注入 --
用户名: ddd' --
密码: xxx
select * from users where name = 'ddd' -- ' and pwd ='xxx'

不知道账户登陆
用户名: xxx' or '1'='1' --
密码: xxx
select * from users where name = 'xxx' or '1'='1' -- ' and pwd ='xxx'

在Java语言解决SQL 注入 ---- 使用预编译 PreparedStatement

在数据库中大数据 LOB ------ Oracle 提供Clob Blob  Clob大型文本数据 Blob大型二进制数据
Mysql Text 相当于 Oracle Clob
* LOB 最大存储范围4GB longText longBlob

创建存放Text文本文件 table
create table textdata(
   id int primary key not null auto_increment,
   mytext longtext
);

java.lang.AbstractMethodError: com.mysql.jdbc.PreparedStatement.setCharacterStream(ILjava/io/Reader;)V
没有设置文件长度  ---- 必须设置文件长度,类型int

com.mysql.jdbc.PacketTooBigException: Packet for query is too large (1928574 > 1048576). You can change this value on the server by setting the max_allowed_packet' variable.
文件太大了
* 必须设置mysql/my.ini
[mysqld] max_allowed_packet=64M

新建存放blob类型table
create table blobdata(
   id int primary key not null auto_increment,
   myblob longblob
);

* 在实际开发中,很少需要将 大文本文件或者音乐、电影保存到数据库
public class LobTest {
 @Test
 public void demo4() {
  // 读取blob数据
  Connection conn = null;
  PreparedStatement stmt = null;
  ResultSet rs = null;

  try {
   conn = JDBCUtils.getConnection();
   String sql = "select * from blobdata where id = 1";
   stmt = conn.prepareStatement(sql);
   rs = stmt.executeQuery();

   if (rs.next()) {
    InputStream in = new BufferedInputStream(rs
      .getBinaryStream("myblob"));
    OutputStream out = new BufferedOutputStream(
      new FileOutputStream("boy_bak.mp3"));
    int b;
    while ((b = in.read()) != -1) {
     out.write(b);
    }
    in.close();
    out.close();
   }
  } catch (Exception e) {
   e.printStackTrace();
  }
 }

 @Test
 public void demo3() {
  // 将 mp3 写入数据库
  // 将文本文件保存到数据库
  Connection conn = null;
  PreparedStatement stmt = null;

  try {
   conn = JDBCUtils.getConnection();
   String sql = "insert into blobdata values(null,?)";
   stmt = conn.prepareStatement(sql);// 预编译
   // 因为sql存在 ? 设置参数
   File file = new File("oldboy.mp3");
   stmt.setBinaryStream(1, new FileInputStream("oldboy.mp3"),
     (int) file.length());

   // 插入
   stmt.executeUpdate();// 预编译执行 不需要传入sql
  } catch (Exception e) {
   e.printStackTrace();
  } finally {
   JDBCUtils.release(stmt, conn);
  }
 }

 @Test
 public void demo2() {
  // 读取text大文本字段
  Connection conn = null;
  PreparedStatement stmt = null;
  ResultSet rs = null;

  try {
   conn = JDBCUtils.getConnection();
   String sql = "select * from textdata where id = ?";
   stmt = conn.prepareStatement(sql);
   // 设置参数
   stmt.setInt(1, 2);
   rs = stmt.executeQuery();// 这里不要写sql
   while (rs.next()) {
    Reader reader = rs.getCharacterStream("mytext");
    Writer writer = new FileWriter("dulala_bak.txt");
    int c;
    while ((c = reader.read()) != -1) {
     writer.write(c);
    }
    reader.close();
    writer.close();
   }
  } catch (Exception e) {
   e.printStackTrace();
  } finally {
   JDBCUtils.release(rs, stmt, conn);
  }
 }

 @Test
 public void demo1() {
  // 将文本文件保存到数据库
  Connection conn = null;
  PreparedStatement stmt = null;

  try {
   conn = JDBCUtils.getConnection();
   String sql = "insert into textdata values(null,?)";
   stmt = conn.prepareStatement(sql);// 预编译
   // 因为sql存在 ? 设置参数
   File file = new File("dulala.txt");
   stmt.setCharacterStream(1, new FileReader("dulala.txt"), (int) file
     .length());

   // 插入
   stmt.executeUpdate();// 预编译执行 不需要传入sql
  } catch (Exception e) {
   e.printStackTrace();
  } finally {
   JDBCUtils.release(stmt, conn);
  }
 }
}
----------------------------------------------------------------------------

关于JDBC编程批处理操作
第一种方式:使用Statement接口的批处理
addBatch(sql) 将一条sql 加入批处理到缓存
executeBatch() 执行批处理 将这组sql一次性发送数据库
clearBatch() 清除批处理缓存
缺点:如果sql结构都一样
                Insert into user(name,password) values(‘aa’,’111’);
  Insert into user(name,password) values(‘bb’,’222’);
  Insert into user(name,password) values(‘cc’,’333’);
  Insert into user(name,password) values(‘dd’,’444’);
会导致数据库编译sql语句四次 ---- 性能比较差

第二种方式:使用PreparedStatement进行批处理
好处:如果连续执行多条结构相同sql --- 采用预编译 ---- SQL只需要编译一次

案例:向数据库插入50000条数据
create table person(
   id int primary key,
   name varchar(40),
   email varchar(100)
);

mysql 50000 --- 59秒
Oracle 50000 --- 906毫秒 100000 --- 1328毫秒

如果sql 结构都相同 --- PreparedStatement 批处理
如果sql  结构存在不同 ---  Statement 批处理

public class BatchTest {
 @Test
 public void demo2() {
  long start = System.currentTimeMillis();
  // 向mysql 通过PreparedStatement 插入50000条数据
  Connection conn = null;
  PreparedStatement stmt = null;

  String sql = "insert into person values(?,?,?)";
  try {
   conn = JDBCUtils.getConnection();
   stmt = conn.prepareStatement(sql);// 预编译
   for (int i = 1; i <= 100000; i++) {
    stmt.setInt(1, i);
    stmt.setString(2, "name" + i);
    stmt.setString(3, "email" + i);
    // 将刚刚设置参数 加入批处理
    stmt.addBatch();

    if (i % 1000 == 0) { // 每1000条向数据库传递一次
     stmt.executeBatch();
     stmt.clearBatch();
    }
   }

   // 为了确保 缓存没有sql
   stmt.executeBatch();

   long end = System.currentTimeMillis();
   System.out.println("执行时间:" + (end - start));
  } catch (Exception e) {
   e.printStackTrace();
  } finally {
   JDBCUtils.release(stmt, conn);
  }
 }

 @Test
 public void demo1() {
  // 使用Statement接口 批处理操作
  // 批处理操作一般没有查询语句, insert update delete其它sql
  Connection conn = null;
  Statement stmt = null;

  try {
   conn = JDBCUtils.getConnection();
   stmt = conn.createStatement();

   // 连续执行多条sql
   stmt.addBatch("create database mytest");
   stmt.addBatch("use mytest");
   stmt.addBatch("create table mytable(id int , name varchar(20))");
   stmt.addBatch("insert into mytable values(1,'aaa')");
   stmt.addBatch("insert into mytable values(2,'bbb')");
   stmt.addBatch("insert into mytable values(3,'ccc')");
   stmt.addBatch("insert into mytable values(4,'ddd')");

   stmt.addBatch("update mytable set name ='abcd' where id = 2");
   stmt.addBatch("delete from mytable where id =3 ");

   stmt.executeBatch();

  } catch (Exception e) {
   e.printStackTrace();
  } finally {
   JDBCUtils.release(stmt, conn);
  }

 }
}

学习重点:
1、JDBC编程步骤 :装载驱动、建立连接、操作数据、释放资源 *
2、对一张数据表通过JDBC完成增删改查 
3、对一张表编写增删改查DAO  *
4、案例:SQL注入登陆案例  *
5、大数据处理Text Blob
6、批处理两种 Statement PreparedStatement

* 参加阅读资料
jdbc-introduce.pdf

昨天目录 sql练习 *

之前债务:用户登陆注册(xml pull)、cookie/session: 浏览记录、购物车  *******
JSP: form编写 JSTL+EL显示

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

分享到:
评论

相关推荐

    day01_jdbc_consumer_

    6. **事务处理**: JDBC支持事务管理,通过`Connection`对象的`setAutoCommit(false)`关闭自动提交,`commit()`提交事务,`rollback()`回滚事务。 7. **批处理**: 多个SQL语句可以组成一个批处理,用`addBatch()`...

    Spring aop、jdbc和事务tx练习

    编程式事务管理则需要在代码中手动调用TransactionTemplate或PlatformTransactionManager接口的方法来控制事务。 在"Spring_Day10"这个压缩包中,你可能找到了相关的练习项目,这些项目可能包含以下内容: - 一个...

    day18-事务与连接池 3.jdbc中事务操作介绍

    在实际开发中,Spring框架提供了对JDBC事务管理的高级支持,通过声明式事务管理,开发者可以在XML配置或注解中定义事务边界,简化事务处理。例如,使用`@Transactional`注解可以声明一个方法为事务方法,Spring会...

    传智播客崔希凡JavaWeb-day19JDBC第三天(DBUtil使用、jdbc案例)-全部资料

    在这个"传智播客崔希凡JavaWeb-day19JDBC第三天"教程中,崔希凡老师深入浅出地讲解了如何使用JDBC(Java Database Connectivity)进行数据库操作,特别是DBUtil工具类的运用以及JDBC实战案例。 首先,DBUtil是...

    day01_jdbc基础.md

    JDBC的定义,JDBCUtils,JDBC HelloWorld,什么情况会触发类加载,DriverManager,Connetion,Statement,ResultSet,三层结构,对象创建过程,配置Tomcat步骤

    详细标准的jdbc学习资料

    通过本套学习资料,你可以系统地了解和掌握JDBC的使用,包括建立连接、执行SQL、处理结果、事务处理、批处理和优化技巧等,为实际的数据库操作打下坚实的基础。资料分为四个部分,分别从初级到高级逐步深入,从day1...

    Jdbc_Day01.zip_jdbc

    在"Jdbc_Day01.zip_jdbc"这个压缩包中,我们可以预期找到一些关于JDBC基础使用和数据库连接的教程资料。 JDBC的核心组件包括以下几个部分: 1. **Driver Manager**:这是JDBC的入口点,负责管理所有已注册的数据库...

    传智播客崔希凡JavaWeb-day18JDBC第二天-全部资料

    【标题】"传智播客崔希凡JavaWeb-day18JDBC第二天-全部资料" 涉及的课程是崔希凡老师讲解的JavaWeb系列教程中的第18天内容,主要聚焦在JDBC(Java Database Connectivity)的学习上。JDBC是Java编程语言和各种数据库...

    02_JDBC_day02(代码).zip

    总结,"02_JDBC_day02(代码)" 包含的可能是从基础的数据库连接到更复杂的事务处理、批处理和预编译语句的示例代码,学习者可以通过这些代码深入了解和掌握JDBC在实际项目中的应用。通过分析并运行这些代码,可以更好...

    jdbc学习文件

    5. **事务管理**:JDBC中的事务控制是非常重要的,可能会在"day04"或"day05"中讲解,包括开始事务、提交事务、回滚事务以及事务的隔离级别。 6. **批处理**:当需要执行大量相似的SQL语句时,批处理可以提高效率。...

    批处理对数据库的应用

    - 例如,在Java中可以使用JDBC的`addBatch()`方法来添加一系列的SQL语句到一个批处理中,然后使用`executeBatch()`方法一次性执行所有添加到批处理中的语句。 3. **操作系统级批处理**: - 在操作系统级别,可以...

    day03_jdbc.md

    day03_jdbc.md

    Day22-JDBC初识_jdbc_java_knowyv3_

    在IT行业中,JDBC(Java Database Connectivity)是一个关键的组件,它允许Java应用程序与各种数据库...通过不断地练习和理解,你将能够熟练运用JDBC进行数据库开发,为后续的Java Web或企业级应用开发奠定坚实基础。

    达内Java大数据 Day01练习题及答案

    在“达内Java大数据 Day01练习题及答案”这个学习资源中,主要涵盖了Java编程语言的基础知识,这是学习Java大数据的重要前提。Day01的练习题旨在帮助初学者巩固和深化对Java基本概念的理解,为后续的大数据技术学习...

    day2_jdbc.zip_jdbc ut_jdbc util_jdbcUtil_jdbc封装

    下面我们将详细探讨JDBC的基础知识,以及`JdbcUtil`类的设计思想和实现方法。 首先,JDBC是Java平台上的一个标准API,它提供了一组接口和类,使得Java程序员能够通过标准的SQL语句与各种关系型数据库进行通信。JDBC...

    JDBC代码JDBC代码JDBC代码

    例如,`day1.zip`可能介绍了JDBC的基础知识和设置环境;`day2.zip`可能涉及连接数据库和执行简单查询;`day3.zip`可能是关于PreparedStatement和批处理的内容;最后,`day4.zip`可能讲解了事务管理和错误处理。通过...

    传智播客大数据day09第三部分

    传智播客大数据day09第三部分

    达内Java大数据 Day02练习题及答案

    达内java大数据 Day02的练习题以及部分答案。

    微服务架构的分布式事务控制解决方案day02.zip

    本资料包“微服务架构的分布式事务控制解决方案day02.zip”可能包含了关于如何在分布式系统中实现事务一致性的深入讲解。下面,我们将详细探讨分布式事务的相关知识点。 首先,分布式事务是为了保证在多个操作之间...

    day22--事务2

    1.1.3 JDBC事务操作 在Java中,我们可以使用JDBC API来管理数据库事务。通过`Connection`对象的以下方法: - `setAutoCommit(false)`:关闭自动提交,从而开启事务。 - `commit()`:提交当前事务。 - `rollback()`:...

Global site tag (gtag.js) - Google Analytics