【javaweb笔记】5、JDBC调用存储过程与存储函数,处理大文本CLOB(TEXT)与二进制BLOB类型数据,JSP访问数据库,JavaBean

1.jdbc总结(模板、八股文):

try{
a.导入驱动包、加载具体驱动类Class.forName("具体驱动类");
b.与数据库建立连接connection = DriverManager.getConnection(...);
c.通过connection,获取操作数据库的对象(Statement\preparedStatement\callablestatement)
stmt = connection.createStatement();
d.(查询)处理结果集rs = pstmt.executeQuery()
while(rs.next()){ rs.getXxx(..) ;}
}catch(ClassNotFoundException e  )
{ ...}
catch(SQLException e)
{...
}
catch(Exception e)
{...
}
finally
{
    //打开顺序,与关闭顺序相反
    if(rs!=null)rs.close()
    if(stmt!=null) stmt.close();
    if(connection!=null)connection.close();
}

--jdbc中,除了Class.forName() 抛出ClassNotFoundException,其余方法全部抛SQLException



2.CallableStatement:调用 存储过程、存储函数
connection.prepareCall(参数:存储过程或存储函数名)
参数格式:
存储过程(无返回值return,用out参数替代):
    { call  存储过程名(参数列表) }
存储函数(有返回值return):
    { ? = call  存储函数名(参数列表) }

create or replace procedure addTwoNum ( num1  in number,num2  in number,result out number )  -- 1 + 2 ->3
as
begin
    result := num1+num2 ;
end ;
/


强调:
如果通过sqlplus 访问数据库,只需要开启:OracleServiceSID
通过其他程序访问数据(sqldevelop、navicate、JDBC),需要开启:OracleServiceSID、XxxListener


JDBC调用存储过程的步骤:
a.产生 调用存储过程的对象(CallableStatement) cstmt =     connection.prepareCall(   "..." ) ;
b.通过setXxx()处理 输出参数值 cstmt.setInt(1, 30);
c.通过 registerOutParameter(...)处理输出参数类型
d.cstmt.execute()执行
e.接受 输出值(返回值)getXxx()


调存储函数:
create or replace function addTwoNumfunction ( num1  in number,num2  in number)  -- 1 + 2 
return number
as
    result number ;    
begin
    result := num1+num2 ;
    return result ;
end ;
/
JDBC调用存储函数:与调存储过程的区别:
在调用时,注意参数:"{? =  call addTwoNumfunction    (?,?) }"

JDBCCallableStatement.java

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Types;
import java.util.Scanner;

public class JDBCCallableStatement {
	private static final String URL = "jdbc:oracle:thin:@localhost:1521:ORCL";
	private static final String USERNAME = "scott";
	private static final String PWD = "tiger";

	public static void invokeProcedure() {
		Connection connection = null;
		CallableStatement cstmt = null;
		try {
			// a.导入驱动,加载具体的驱动类
			Class.forName("oracle.jdbc.OracleDriver");// 加载具体的驱动类
			// b.与数据库建立连接
			connection = DriverManager.getConnection(URL, USERNAME, PWD);
			
			
			// c.发送sql,执行(增删改、查)  num1+num2 ->num3
			 cstmt = 	connection.prepareCall(   "{ call addTwoNum(?,?,?) }" ) ;
			 cstmt.setInt(1, 30);
			 cstmt.setInt(2, 40);
			
			 cstmt.registerOutParameter(3, Types.INTEGER);
			 cstmt.execute() ;//num1+num2 ,execute()之前处理 输入参数以及输出参数类型,之后接受输出参数值
			 //设置输出参数的类型
			
			 int result = cstmt.getInt(3) ;//获取计算结果 
			System.out.println(result);
			
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		} catch(Exception e) {
			e.printStackTrace();
		}
		finally {
			try {
				 if(cstmt!=null) cstmt.close();// 对象.方法
				 if(connection!=null)connection.close();
			}catch(SQLException e) {
				e.printStackTrace();
			}
		}
	}
	
	public static void invokeFunction() {
		Connection connection = null;
		CallableStatement cstmt = null;
		try {
			// a.导入驱动,加载具体的驱动类
			Class.forName("oracle.jdbc.OracleDriver");// 加载具体的驱动类
			// b.与数据库建立连接
			connection = DriverManager.getConnection(URL, USERNAME, PWD);
			
			// c.发送sql,执行(增删改、查)  num1+num2 ->num3
			 cstmt = 	connection.prepareCall(   "{? =  call addTwoNumfunction	(?,?) }" ) ;
		
			 cstmt.setInt(2, 30);
			 cstmt.setInt(3,40);
			
			 cstmt.registerOutParameter(1, Types.INTEGER);
			 cstmt.execute() ;//num1+num2 ,execute()之前处理 输入参数以及输出参数类型,之后接受输出参数值
			 //设置输出参数的类型
			
			 int result = cstmt.getInt(1) ;//获取计算结果 
			System.out.println(result);
			
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		} catch(Exception e) {
			e.printStackTrace();
		}
		finally {
			try {
				 if(cstmt!=null) cstmt.close();// 对象.方法
				 if(connection!=null)connection.close();
			}catch(SQLException e) {
				e.printStackTrace();
			}
		}
	}
	public static void main(String[] args) {
//		update() ;
//		invokeProcedure();
		invokeFunction() ;
	}
}


3.处理CLOB:oracle(TEXT:mysql)、BLOB类型
处理稍大型数据:
    
a.存储路径    E:\JDK_API_zh_CN.CHM
    通过JDBC存储文件路径,然后 根据IO操作处理
    例如:JDBC将 E:\JDK_API_zh_CN.CHM 文件 以字符串形式“E:\JDK_API_zh_CN.CHM”存储到数据库中
        获取:1.获取该路径“E:\JDK_API_zh_CN.CHM”  2.IO    

b.
    CLOB:大文本数据 (小说->数据)
    BLOB:二进制(图片、视频等一切数据)


clob:大文本数据   字符流 Reader Writer

1.先通过pstmt 的? 代替小说内容 (占位符)
2.再通过pstmt.setCharacterStream(2, reader,  (int)file.length());  将上一步的?替换为 小说流, 注意第三个参数需要是 Int类型

取:
1.通过Reader reader = rs.getCharacterStream("NOVEL") ; 将cloc类型的数据  保存到Reader对象中
2. 将Reader通过Writer输出即可。

JDBCClob.java

import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.Writer;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Scanner;


public class JDBCClob {
	
	private static final String URL = "jdbc:oracle:thin:@localhost:1521:ORCL";
	private static final String USERNAME = "scott";
	private static final String PWD = "tiger";

	//通过jdbc存储大文本数据(小说)CLOB
	//设置CLOB类型:setCharacterStream
	public static void clobDemo() {
		Connection connection = null;
		PreparedStatement pstmt = null;
		try {
			// a.导入驱动,加载具体的驱动类
			Class.forName("oracle.jdbc.OracleDriver");// 加载具体的驱动类
			// b.与数据库建立连接
			connection = DriverManager.getConnection(URL, USERNAME, PWD);
			
			String sql = "insert into mynovel values(?,?)";
			// c.发送sql,执行(增删改、查)
			pstmt = connection.prepareStatement(sql);
			pstmt.setInt(1, 1);
			File file = new File("E:\\all.txt");
			InputStream in = new FileInputStream( file) ;
			Reader reader = new InputStreamReader( in   ,"UTF-8") ;//转换流 可以设置编码
			pstmt.setCharacterStream(2, reader,  (int)file.length());
			int count =pstmt.executeUpdate() ;
			// d.处理结果
			if (count > 0) {  
				System.out.println("操作成功!");
			}
			
			reader.close();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		} catch(Exception e) {
			e.printStackTrace();
		}
		finally {
			try {
				 if(pstmt!=null) pstmt.close();// 对象.方法
				 if(connection!=null)connection.close();
			}catch(SQLException e) {
				e.printStackTrace();
			}
		}
	}
	
	//读取小说
	public static void clobReaderDemo() {
		Connection connection = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null ; 
		try {
			// a.导入驱动,加载具体的驱动类
			Class.forName("oracle.jdbc.OracleDriver");// 加载具体的驱动类
			// b.与数据库建立连接
			connection = DriverManager.getConnection(URL, USERNAME, PWD);
			
			String sql = "select NOVEL from mynovel where id = ? ";
			// c.发送sql,执行(查)
			pstmt = connection.prepareStatement(sql);
			pstmt.setInt(1, 1);
			
			rs = pstmt.executeQuery() ;
			//setXxxx getXxxx      setInt  getInt
			if(rs.next())
			{
				Reader reader = rs.getCharacterStream("NOVEL") ;
				Writer writer = new FileWriter("src/小说.txt");
				
				char[] chs = new char[100] ;
				int len = -1;
				while(  (len = reader.read(chs)) !=-1 ) {
					writer.write( chs,0,len  );
				}
				writer.close();
				reader.close();
			}
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		} catch(Exception e) {
			e.printStackTrace();
		}
		finally {
			try {
				 if(pstmt!=null) pstmt.close();// 对象.方法
				 if(connection!=null)connection.close();
			}catch(SQLException e) {
				e.printStackTrace();
			}
		}
	}
	
	
	
	public static void main(String[] args) {
//		clobDemo() ;
		clobReaderDemo() ;
	}
}


blob:二进制  字节流 InputStream OutputStream
与CLOB步骤基本一致,区别:setBinaryStream(...)  getBinaryStream(...)   

JDBCBlob.java

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.Reader;
import java.io.Writer;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Scanner;


public class JDBCBlob {
	private static final String URL = "jdbc:oracle:thin:@localhost:1521:ORCL";
	private static final String USERNAME = "scott";
	private static final String PWD = "tiger";

	//通过jdbc存储二进制类型 (mp3)
	//设置BLOB类型:
	public static void blobDemo() {
		Connection connection = null;
		PreparedStatement pstmt = null;
		try {
			// a.导入驱动,加载具体的驱动类
			Class.forName("oracle.jdbc.OracleDriver");// 加载具体的驱动类
			// b.与数据库建立连接
			connection = DriverManager.getConnection(URL, USERNAME, PWD);
			
			String sql = "insert into mymusic values(?,?)";
			// c.发送sql,执行(增删改、查)
			pstmt = connection.prepareStatement(sql);
			pstmt.setInt(1, 1);
			File file = new File("d:\\luna.mp3");
			
			InputStream in = new FileInputStream(file );
			pstmt.setBinaryStream(2,in ,(int)file.length()  );
			
			
			int count =pstmt.executeUpdate() ;
			// d.处理结果
			if (count > 0) {  
				System.out.println("操作成功!");
			}
			
			in.close();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		} catch(Exception e) {
			e.printStackTrace();
		}
		finally {
			try {
				 if(pstmt!=null) pstmt.close();// 对象.方法
				 if(connection!=null)connection.close();
			}catch(SQLException e) {
				e.printStackTrace();
			}
		}
	}
	
	//读取二进制文件
	public static void blobReaderDemo() {
		Connection connection = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null ; 
		try {
			// a.导入驱动,加载具体的驱动类
			Class.forName("oracle.jdbc.OracleDriver");// 加载具体的驱动类
			// b.与数据库建立连接
			connection = DriverManager.getConnection(URL, USERNAME, PWD);
			
			String sql = "select music from mymusic where id = ? ";
			
			
			// c.发送sql,执行(查)
			pstmt = connection.prepareStatement(sql);
			pstmt.setInt(1, 1);
			
			rs = pstmt.executeQuery() ;
			if(rs.next())
			{
				InputStream in = rs.getBinaryStream("music") ;
				OutputStream out = new FileOutputStream("src/music.mp3") ;
				
				byte[] chs = new byte[100] ;
				int len = -1;
				while(  (len = in.read(chs)) !=-1 ) {
					out.write( chs,0,len  );
				}
				out.close();
				in.close();
			}
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		} catch(Exception e) {
			e.printStackTrace();
		}
		finally {
			try {
				 if(pstmt!=null) pstmt.close();// 对象.方法
				 if(connection!=null)connection.close();
			}catch(SQLException e) {
				e.printStackTrace();
			}
		}
	}
	
	
	
	public static void main(String[] args) {
//		blobDemo() ;
		blobReaderDemo();
	}
}

4.JSP访问数据库

JSP就是在html中嵌套的java代码,因此 java代码可以写在jsp中(<%  ... %>)

导包操作:java项目 :1 Jar复制到工程中 2.右键该Jar :build path ->add to build Path
      Web项目:jar复制到WEB-INF/lib

核心:就是将 java中的JDBC代码,复制到 JSP中的<% ... %>
注意:如果jsp出现错误:The import Xxx cannot be resolved
尝试解决步骤:

    a.(可能是Jdk、tomcat版本问题) 右键项目->build path,将其中 报错的 libary或Lib 删除后 重新导入
    b.清空各种缓存:右键项目->Clean tomcat... clean  (Project -clean或者 进tomcat目录 删除里面work的子目录)
    c.删除之前的tomcat,重新解压缩、配置tomcat,重启计算机
    d.如果类之前没有包,则将该类加入包中


5.JavaBean
刚才我们将 jsp中 登录操作的代码  转移到了LoginDao.java;其中LoginDao类 就称之为JavaBean。
JavaBean的作用:a.减轻的jsp复杂度  b.提高代码复用(以后任何地方的 登录操作,都可以通过调用LoginDao实现)

JavaBean(就是一个Java类)的定义:满足一下2点 ,就可以称为JavaBean
    a.public 修饰的类  ,public 无参构造
    b.所有属性(如果有) 都是private,并且提供set/get   (如果boolean 则get 可以替换成is)

使用层面,Java分为2大类:
a.封装业务逻辑的JavaBean (LoginDao.java封装了登录逻辑)            逻辑
    可以将jsp中的JDBC代码,封装到Login.java类中 (Login.java)

b.封装数据的JavaBean   (实体类,Student.java  Person.java  )        数据 
    对应于数据库中的一张表
    Login login = new Login(uname,upwd) ;//即用Login对象 封装了2个数据(用户名 和密码)

封装数据的JavaBean 对应于数据库中的一张表   (Login(name,pwd))
封装业务逻辑的JavaBean 用于操作 一个封装数据的JavaBean  

可以发现,JavaBean可以简化 代码(jsp->jsp+java)、提供代码复用(LoginDao.java)

public  void sleep(String name,String place, int time)
{

}

public  void sleep(Person per)
{
    per.getName()
    per.getPlace()
    ...
}

猜你喜欢

转载自blog.csdn.net/kuaileky/article/details/86315604