jdbc的五大常见应用场景

 

在实际开发工做中,有关于jdbc的应用,常常性地会出现如下五个问题:java

 

业务场景一:过滤条件比较弱,一次性可能读出较多记录

增长或修改查询语句来优化查询结果mysql

业务场景二:须要统计的记录比较多

eg.:读取数据库表中全部的记录,千万级的记录的读取可能会出现java的内存溢出异常OutOfMemoryErrorsql

缘由分析:java程序是运行在java虚拟机中的,jvm是有内存大小限制的,当咱们把大量的记录一次性地读入jvm的内存中的时候,读出的数据若是超出了jvm所规定的内存最大值的时候就会出现内存溢出的错误。数据库

解决办法:既然内存容量是有限的,咱们能够读取一部分数据进行处理,处理完毕以后在进行下一部分数据的读取,这样避免一次性地载入过多的数据致使内存的溢出。jvm

在jdbc中是如何具体实现的呢?优化

使用游标:

游标的开启:编码

须要在加载驱动后,得到与数据库的链接的同时需啊哟啊在url后面加上?useCursorFetch=trueurl

表示咱们对这个数据库的读取须要使用游标spa

要是使用有标的话,必须使用PreparedStatement 的setFetchSize();code

入参为int型的整数,表示jdbc从数据库中一次读取记录的数量,须要在查询executeQuery以前须要设置一次查询的记录的数量。

import java.sql.*;

public class Test001 {
	private String driver = "com.mysql.jdbc.Driver";
	private String url = "jdbc:mysql://host:port/dataBaseName";
	private String userName = "xxx";
	private String passWord = "xxx";
	
	public void Test() {
		Connection connection = null;
		String sql = null;
		PreparedStatement prepareStatement = null;
		ResultSet rs = null;
		try {
			//装载驱动
			Class.forName(driver);	
			//获取链接
			connection = DriverManager.getConnection(url,userName,passWord);
			//变动url设置
			url = url + "userCursorFecth = true";
			//sql语句
			sql = "select * from tableName where sex = Female";
			//执行sql语句
			prepareStatement = connection.prepareStatement(sql);
			//设置游标读取参数
			prepareStatement.setFetchSize(1);
			//执行查询语句,返回结果集
			rs = prepareStatement.executeQuery();
			//取结果集
			while(rs.next()) {
				System.out.println(rs.getString(1));
			}
			//此时的执行结果的按照设置的参数进行结果的操做,一条条地处理
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			try {
				if (null != connection) 
				connection.close();
				if (null != rs) 
					rs.close();
				if (null != prepareStatement)
					prepareStatement.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}
}

 

业务场景三:大对象读取

读取的每一条记录中包含大字段的内容,在实际开发过程当中,为了方便管理,每每数据记录会包含大字段的内容,读取可能会出现内存溢出。

处理方式:流方式读取

jdbc的实现:

ResultSet.getBinaryStream()获取流

 

rs = prepareStatement.executeQuery();
			//取结果集
			while(rs.next()) {
				System.out.println(rs.getString(1));
				
				InputStream in = rs.getBinaryStream(1);
				File file = new File(File_URL);
				OutputStream out = null;
				out = new FileOutputStream(file);
				int temp = 0;
				while ((temp = in.read()) != -1) {
					out.write(temp);
				}
				in.close();
				out.close();
			}

 

业务场景四:大量数据插入

海量的数据插入,若是一条条的插入,每一次的sql语句的发送与接收都须要时间

 

更加高效的使用方式为

批处理:

发送一次sql 插入多条语句

Statement提供了三个接口:

addbatch()

executeBatch()

clearBatch()

遍历须要插入的元素,将其放入batch中,而后执行executeBatch最后执行clearBatch()。

Set<String> users = new HashSet<String>();  
			String user1 = "zhangsan";
			String user2 = "lisi";
			String  user3 = "zhaowu";	
			users.add(user1);
			users.add(user2);
			users.add(user3);
			
			Statement statement = connection.createStatement();
			String sql2 = "insert into tableName(user)values(";
			for (String user : users) {
				statement.addBatch(sql + user + ")");
			}
			statement.executeBatch();
			statement.clearBatch();

 

业务场景五:字符编码问题

涉及到中文,须要注意可能出现的乱码问题

能够设置不一样级别的代码:server级别,database级别,table级别, 字段级别,

优先级依次增大,好比设置列级别的编码,那么其余三个就不会生效。

Server-->Database-->Table-->column

咱们须要设置jdbc的编码方式来适应数据库的编码方式,设置方式也很简单,须要在url中增长

例如 :      url = url +"characterEncoding=utf8";

相关文章
相关标签/搜索