JavaWeb之JDBC(十四)

JDBC快速入门二

1. LOB存取

1. 向数据库中插入二进制数据
@Test
public void testInsert() {

	Connection conn = null;
	PreparedStatement stmt = null;
	try {
		conn = JDBCUtils.getConnection();
		String sql = "insert into t1 values(?,?)";
		stmt = conn.prepareStatement(sql);
		stmt.setInt(1, 1);
	--------------读取文件中数据-----------------------------
		InputStream is = new FileInputStream("src/22.jpg");
		stmt.setBinaryStream(2, is,is.available());
	--------------关键两行代码-------------------------------
		stmt.executeUpdate();

	} catch(Exception e) {
		throw new RuntimeException(e);
	} finally {
		JDBCUtils.close(null, stmt, conn);
	}
}

2. 向数据库读取二进制文件
conn = JDBCUtils.getConnection();
String sql = "select * from t1 where id=?";
stmt = conn.prepareStatement(sql);
stmt.setInt(1, 1);

rs = stmt.executeQuery();
if (rs.next()) {
------------------------得到查询的iod----------------
	InputStream is = rs.getBinaryStream(2);
	OutputStream os = new FileOutputStream("d:/down.jpg");
------------------------关键两行代码-----------------
	int len = -1;
	byte buf[] = new byte[1024];
	while((len=is.read(buf)) != -1) {
		os.write(buf,0,len);
		os.flush();
	}
}

3. 关于文本文件读写问题和二进制一样,方法不一样而已
stmt.setCharacterStream(2, reader,(int)file.length());
rs.getCharacterStream(2);

2. Batch批处理

Statement
	1. sql语句固定
	2. 可以一次性批量执行不同的sql语句
	conn = JDBCUtils.getConnection();
	stmt = conn.createStatement();
	String sql = "insert into testbatch value(1,‘cgx‘)";
	String sql2 = "update testbatch set name=‘aj‘ where id=‘1‘";
	stmt.addBatch(sql);

	stmt.addBatch(sql2);
	int result[] = stmt.executeBatch();
	for(int i: result) {
		System.out.println(i);
	}

------------------------------------------------
PreparedStatement
	1. sql语句的参数是不确定的
	2. 一次性批量执行相同的sql语句

	conn = JDBCUtils.getConnection();
	stmt = conn.prepareStatement("insert into testbatch values(?,?)");

	for(int i=100; i<100; i++ ) {
		stmt.setInt(1,10+i);
		stmt.setString(2,"cgx"+i);

		stmt.addBatch();
		if(i%1000==0) {
			//分批执行批处理
			stmt.executeBatch();
			//清空批处理队列
			stmt.clearBatch();
		}
	}
	//执行批处理
	stmt.executeBatch();
	//清空批处理队列
	stmt.clearBatch();

3. 调用存储过程

存储过程
1、存储过程简介(存储过程的创建DBA)
2、运行在服务器上,事先由DBA开发了也编译好了
3、java调用 时,只要知道过程名就可以了
4、提高了安全性

conn = JDBCUtils.getConnection();
stmt = conn.prepareCall("{call demoSp(?,?)}");
stmt.setString(1, "cgx");//输入参数赋值

//对于过程的输出参数要先注册
stmt.registerOutParameter(2, java.sql.Types.VARCHAR);
//执行存储过程
stmt.execute();

String result = stmt.getString(2);//调用存储过程后,返回输出参数
System.out.println(result);

4. 事务入门

1、TPL:事务(Transaction)处理语言
数据库有可能是自动提交事务的(MySQL默认就是自动提交事务的),每一条语句都是单独的事务
start transaction:开启事务
commit:提交事务。永久的存储到硬盘上
rollback:回滚事务。回到最开始的地方

银行转账!张三转10000块到李四的账户,这其实需要两条SQL语句:
?	给张三的账户减去10000元;
?	给李四的账户加上10000元。
如果在第一条SQL语句执行成功后,在执行第二条SQL语句之前,程序被中断了(可能是抛出了某个异常,也可能是其他什么原因),那么李四的账户没有加上10000元,而张三却减去了10000元。这肯定是不行的!

try {
	conn = JDBCUtils.getConnection();
	conn.setAutoCommit(false);	//开启事务
	String sql = "update account set money=money+100 where id=1";
	String sql2 = "update account set money=money-100 where id=2";
	stmt = conn.prepareStatement(sql);
	stmt2 = conn.prepareStatement(sql2);

	stmt.executeUpdate();
//	int i= 1/0;
	stmt2.executeUpdate();
	conn.commit();

}catch(ArithmeticException e) {
	if(conn != null) {
		try {
			conn.rollback();
		} catch (SQLException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
	}
} 

5. 事务的特性和隔离级别(提高数据安全)

1.      ISOLATION_DEFAULT: 这是一个PlatfromTransactionManager默认的隔离级别,使用数据库默认的事务隔离级别.
	  另外四个与JDBC的隔离级别相对应
2.      ISOLATION_READ_UNCOMMITTED: 这是事务最低的隔离级别,它充许令外一个事务可以看到这个事务未提交的数据。
	  这种隔离级别会产生脏读,不可重复读和幻像读。
3.      ISOLATION_READ_COMMITTED: 保证一个事务修改的数据提交后才能被另外一个事务读取。另外一个事务不能读取该事务未提交的数据
4.      ISOLATION_REPEATABLE_READ: 这种事务隔离级别可以防止脏读,不可重复读。但是可能出现幻像读。
5.      ISOLATION_SERIALIZABLE 这是花费最高代价但是最可靠的事务隔离级别。事务被处理为顺序执行。

	  除了防止脏读,不可重复读外,还避免了幻像读。

1. 脏读就是指当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,这时,另外一个事务也访问这个数据,然后使用了这个数据。
2. 不可重复读是 指在一个事务内,多次读同一数据。在这个事务还没有结束时,另外一个事务也访问该同一数据。
那么,在第一个事务中的两次读数据之间,由于第二个事务的修 改,那么第一个事务两次读到的的数据可能是不一样的。
3. 幻觉读是 指当事务不是独立执行时发生的一种现象,例如第一个事务对一个表中的数据进行了修改,这种修改涉及到表中的全部数据行
。同时,第二个事务也修改这个表中的 数据,这种修改是向表中插入一行新数据。那么,以后就会发生操作第一个事务的用户发现表中还有没有修改的数据行,就好象发生了幻觉一样

SQL中查询隔离级别
seelect @@session.tx_isolation
seelect @@global.tx_isolation

设置隔离级别
set global transaction isolationlevel
set session transaction isolationlevel 

Java中设置隔离级别
con. setTransactionIsolation(int level)

6. 数据库连接池

当定义了数据库连接池之后,程序需要使用Connection都是从连接池那来获取,但是怎么来获取连接池对象呢?这里又存在一个解耦的问题!
通常在Java Web环境中都会使用JNDI(Java命名目录接口)来查找想要的资源,通常JavaWeb服务器也都是JNDI服务器,所以使用JNDI需要在JavaWeb服务器(Tomcat)中进行配置。
如果需要你的连接池可以配置到JNDI中,那么就要让你的连接池去实现DataSource接口

自定义连接池
?	继承原有Connection,然后重写close()方法;
?	使用装饰者模式(回忆一下IO流),重写close()方法;(简化代码可以使用适配器模式)
?	JDK动态代理

7. DBCP

DBCP是Apache提供的一款开源免费的数据库连接池!
Hibernate3.0之后不再对DBCP提供支持!因为Hibernate声明DBCP有致命的缺欠!DBCP因为Hibernate的这一毁谤很是生气,并且说自己没有缺欠

DataSource ds = BasicDataSourceFactory.createDataSource(prop)
ds.getConnection();

8. CP30

1. 导包
	c3p0-0.9.1.2.jar
	mysql-connector-java-5.0.8-bin.jar
2. src路径下c3p0-config.xml
3. 调用
DataSource ds = new ComboPooledDataSource();
return ds.getConnection();

总结:(必须知道)
1、日后尽量使用标准的数据源(一般都带有连接池),为的就是提高效率
2、当用户调用Connection.close()方法,并不能关闭链接,而是还回池中
时间: 2024-10-12 22:28:01

JavaWeb之JDBC(十四)的相关文章

JavaWeb学习 (二十四)————Filter(过滤器)常见应用

一.统一全站字符编码 通过配置参数charset指明使用何种字符编码,以处理Html Form请求参数的中文问题 1 package me.gacl.web.filter; 2 3 import java.io.IOException; 4 import javax.servlet.Filter; 5 import javax.servlet.FilterChain; 6 import javax.servlet.FilterConfig; 7 import javax.servlet.Serv

JavaWeb总结(十四)

无脚本JSP表达式语言EL JSP页面中显示结果 jsp:useBean和jsp:getProperty两个元素冗长而笨拙 jsp:getProperty只支持对简单Bean属性的访问 public class Person implements Serializable { private String name; private Dog dog; -- } public class Dog implements Serializable { public String name; -- }

JavaWeb系列之十四(DBUtil)

 1.数据库的元数据 元数据:数据库,或则数据库表,表中的字段额度一些信息 比如数据库名称,驱动,表中的主键的名称 主要完成一些通用性比较高的代码 数据库里面,有三类元数据: 第一类:数据库元数据 获取元数据:Connection.getMateData();得到数据元数据 DatabaseMateData里面的方法:getDriverName(),getURL(),getUserName(), getTables(), rs=db.getTables("", "&quo

javaweb学习总结(十四)——JSP原理

一.什么是JSP? JSP全称是Java Server Pages,它和servle技术一样,都是SUN公司定义的一种用于开发动态web资源的技术. JSP这门技术的最大的特点在于,写jsp就像在写html,但它相比html而言,html只能为用户提供静态数据,而Jsp技术允许在页面中嵌套java代码,为用户提供动态数据. 二.JSP原理 2.1.Web服务器是如何调用并执行一个jsp页面的? 浏览器向服务器发请求,不管访问的是什么资源,其实都是在访问Servlet,所以当访问一个jsp页面时,

javaweb学习总结十四(xml约束之Schema)

一:schema约束简单介绍 1:xml Schema的定义以及优缺点 2:xml schema入门 3:命名空间 这里http://www.itcast.cn 并没有什么具体的意义,只是命名而已. 4:xml schema的引入 5:命名空间引入schema 6:不使用命名空间引入schema 二:schema约束语法 这个可以参考xml schema的约束文档

javaWeb核心技术第十四篇之easyui

网站是分为网站的前台和网站的后台. 前台--给用户看的 例如:商城 后台--给管理员看的 例如:商城后台 目的:用来添加维护数据 BootStrap:jsp 页面显示,效果好,美观,适合作为用户界面. EasyUI : jsp页面,快速开发,格式统一,美观效果一般. EasyUI里面有很多组件(功能模块):有自己的特使,但编写简单,只需固定html代码结构. EasyUI环境搭建: 1.导入css , 需要2个css 2.导入jquery,需要2个js <link rel="stylesh

爪哇国新游记之十四----初试JDBC

import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; public class A{ public static void search1(){ Connection conn=null; PreparedStatement ps=null; Resu

SSM(十四) 基于annotation的http防重插件

SSM(十四) 基于annotation的http防重插件 前言 针对于我们现在常用的RESTful API通常我们需要对请求进行唯一标识,也就是每次都要带上一个请求号,如reqNO. 对于入库这种操作数据库的请求我们一般要保证他的唯一性,一个请求号通常只能用一次,所以需要我们对这种请求加上校验机制. 该需求的实现思路是通过自定义annotation,只给需要进行校验的接口加上注解.然后通过切面使用了注解的接口将每次请求号存进Redis,每次都进行判断是否存在这个请求号即可. 来看下加上本次插件

处女男学Android(十四)---Android 重量级数据存储之SQLite

前言 不知不觉的Android基础系列已经写了十三篇了,这是第十四篇~上一篇blog记录了Android中的一种数据存储方案,即共享参数(Sharedpreferences)的使用(处女男学Android(十三)---Android 轻量级数据存储之SharedPreferences).最近初学如何在Android中应用SQLite,写了一个基于ListView的增删查的小例子,本篇blog就记录一下我学习到的如何在Android中操作SQLite持久化客户端数据. 初始化SQLite 关于SQ