1、写出文件上传的步骤 2、写出上传页面的表单需要设置的属性 3、写出文件下载的步骤
1、文件上传 2、文件下载
1、自定义数据库连接池 2、使用DBCP连接池 3、使用C3P0连接池 4、使用Druid连接池 5、DbUtils的使用
1、熟悉自定义数据库连接池 2、掌握DBCP连接池 3、掌握C3P0连接池的使用 4、掌握Druid连接池的使用 5、掌握DbUtils的使用
使用JDBC操作数据库,需要建立Connection,使用传统的JDBC操作需要每次创建Connection,创建Connection是一个非常性能和消耗时间的过程,我们需要在提高程序性能,那么就需要减少每次创建创建连接带来的负面影响,解决这个问题我们将利用池子概念,预先创建一些链接放入池子中,如果需要操作数据,不用创建新的Connection,只需要在池子中获取即可,使用完毕放入池子!这样就形成了复用!
我们可以通过自定义的方式实现连接池!分析连接池类应该包含特定的属性和方法!
属性: 集合 放置Connection
方法: 获取连接方法
回收连接方法
具体实现代码:
xxxxxxxxxxpublic class Pool{ static LinkedList<Connection> list = new LinkedList<Connection>(); static{ for (int i = 0; i < 10; i++) { Connection connection = JDBCUtils.newInstance().getConnection(); list.add(connection); } } /** * 从连接池子中获取连接的方式 * @return */ public static Connection getConnection(){ if (list.isEmpty()) { Connection connection = JDBCUtils.newInstance().getConnection(); list.addLast(connection); } Connection conn = list.removeFirst(); return conn; } /** * 返回到连接池子中 */ public static void addBack(Connection conn){ if (list.size() >= 10) { try { conn.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } }else{ list.addLast(conn); //10 } } /** * 获取连接池子中连接数量的方法 */ public static int getSize(){ return list.size(); } }Java为连接池实现提供了一个规范(接口),规范的写法,我们需要实现DataSource接口!
但是实现DataSource接口有一个弊端,没有提供回收链接方法!这里我们将使用装饰者模式!
装饰Connection!具体实现代码如下:
xpublic class MyConnection implements Connection{ //将被装饰者导入 private Connection conn; private LinkedList<Connection> list; public MyConnection(Connection conn, LinkedList<Connection> list) { super(); this.conn = conn; this.list = list; } public <T> T unwrap(Class<T> iface) throws SQLException { // TODO Auto-generated method stub return conn.unwrap(iface); } public boolean isWrapperFor(Class<?> iface) throws SQLException { // TODO Auto-generated method stub return conn.isWrapperFor(iface); } public Statement createStatement() throws SQLException { // TODO Auto-generated method stub return conn.createStatement(); } public PreparedStatement prepareStatement(String sql) throws SQLException { // TODO Auto-generated method stub return conn.prepareStatement(sql); } public CallableStatement prepareCall(String sql) throws SQLException { // TODO Auto-generated method stub return null; } public String nativeSQL(String sql) throws SQLException { // TODO Auto-generated method stub return null; } public void setAutoCommit(boolean autoCommit) throws SQLException { // TODO Auto-generated method stub } public boolean getAutoCommit() throws SQLException { // TODO Auto-generated method stub return false; } public void commit() throws SQLException { // TODO Auto-generated method stub conn.commit(); } public void rollback() throws SQLException { // TODO Auto-generated method stub conn.rollback(); } public void close() throws SQLException { // TODO Auto-generated method stub list.addLast(conn); } ...}基于规范实现的连接池
xxxxxxxxxx/** * 创建一个规范的连接池子 */public class DataSourcePool implements DataSource{ static LinkedList<Connection> list = new LinkedList<Connection>(); static{ for (int i = 0; i < 10; i++) { Connection connection = JDBCUtils.newInstance().getConnection(); list.add(connection); } } public static int getSize(){ return list.size(); } public Connection getConnection() throws SQLException { // TODO Auto-generated method stub Connection conn = list.removeFirst(); MyConnection conn1 = new MyConnection(conn, list); return conn1; } public PrintWriter getLogWriter() throws SQLException { // TODO Auto-generated method stub return null; } public void setLogWriter(PrintWriter out) throws SQLException { // TODO Auto-generated method stub } public void setLoginTimeout(int seconds) throws SQLException { // TODO Auto-generated method stub } public int getLoginTimeout() throws SQLException { // TODO Auto-generated method stub return 0; } public Logger getParentLogger() throws SQLFeatureNotSupportedException { // TODO Auto-generated method stub return null; } public <T> T unwrap(Class<T> iface) throws SQLException { // TODO Auto-generated method stub return null; } public boolean isWrapperFor(Class<?> iface) throws SQLException { // TODO Auto-generated method stub return false; } public Connection getConnection(String username, String password) throws SQLException { // TODO Auto-generated method stub return null; }}DBCP(DataBase connection pool),数据库连接池。是 apache 上的一个 java 连接池项目,也是 tomcat 使用的连接池组件。单独使用dbcp需要2个包:commons-dbcp.jar,commons-pool.jar由于建立数据库连接是一个非常耗时耗资源的行为,所以通过连接池预先同数据库建立一些连接,放在内存中,应用程序需要建立数据库连接时直接到连接池中申请一个就行,用完后再放回去。
创建JavaWeb项目
mysql-jdbc.jar
commons-dbcp.jar
commons-pool.jar
所谓的硬编码方式就是在代码中添加配置
xxxxxxxxxxpublic void testHard() throws SQLException{ //TODO 硬编码 使用DBCP连接池子 BasicDataSource source = new BasicDataSource(); //设置连接的信息 source.setDriverClassName("com.mysql.jdbc.Driver"); source.setUrl("jdbc:mysql://localhost:3306/day2"); source.setUsername("root"); source.setPassword("111"); Connection connection = source.getConnection(); String sql = "select * from student"; Statement createStatement = connection.createStatement(); ResultSet executeQuery = createStatement.executeQuery(sql); while (executeQuery.next()) { System.out.println(executeQuery.getString(2)); } connection.close(); //回收 }所谓的软编码,就是在项目中添加配置文件,这样就不需要每次代码中添加配合!
文件名称: info.properties
文件位置: src下
#连接设置 driverClassName=com.mysql.jdbc.Driver url=jdbc:mysql://localhost:3306/day2 username=root password=111 #<!-- 初始化连接 --> initialSize=10 #最大连接数量 maxActive=50 #<!-- 最大空闲连接 --> maxIdle=20 #<!-- 最小空闲连接 --> minIdle=5 #<!-- 超时等待时间以毫秒为单位 6000毫秒/1000等于60秒 --> maxWait=6000
xxxxxxxxxx public void testSoft() throws Exception{ //TODO DBCP软编码连接池子使用 BasicDataSourceFactory factory = new BasicDataSourceFactory(); Properties properties = new Properties(); //配置文件添加到properties对象中 javase properties.load(new FileInputStream("src/info.properties")); //生成连接池子 需要配置文件 DataSource source = factory.createDataSource(properties); Connection connection = source.getConnection(); String sql = "select * from student"; Statement createStatement = connection.createStatement(); ResultSet executeQuery = createStatement.executeQuery(sql); while (executeQuery.next()) { System.out.println(executeQuery.getString(2)); } connection.close(); //回收 }C3P0是一个开源的JDBC连接池,它实现了数据源和JNDI绑定,支持JDBC3规范和JDBC2的标准扩展。目前使用它的开源项目有Hibernate,Spring等。
c3p0与dbcp区别 1. dbcp没有自动回收空闲连接的功能 c3p0有自动回收空闲连接功能 2. dbcp需要手动设置配置文件 c3p0不需要手动设置
c3p0-0.9.1.2.jar
mysql-connector-java-5.0.8.jar
c3p0是在外部添加配置文件,工具直接进行应用,因为直接引用,所以要求固定的命名和文件位置
文件位置: src
文件命名:c3p0-config.xml/c3p0-config.properties
xxxxxxxxxx<c3p0-config> <!-- 默认配置,如果没有指定则使用这个配置 --> <default-config> <!-- 基本配置 --> <property name="driverClass">com.mysql.jdbc.Driver</property> <property name="jdbcUrl">jdbc:mysql://localhost:3306/day2</property> <property name="user">root</property> <property name="password">111</property> <!--扩展配置--> <!-- 连接超过30秒报错--> <property name="checkoutTimeout">30000</property> <!--30秒检查空闲连接 --> <property name="idleConnectionTestPeriod">30</property> <property name="initialPoolSize">10</property> <!-- 30秒不适用丢弃--> <property name="maxIdleTime">30</property> <property name="maxPoolSize">100</property> <property name="minPoolSize">10</property> <property name="maxStatements">200</property> </default-config> <!-- 命名的配置 --> <named-config name="zhaowf"> <property name="driverClass">com.mysql.jdbc.Driver</property> <property name="jdbcUrl">jdbc:mysql://localhost:3306/day2</property> <property name="user">root</property> <property name="password">111</property> <!-- 如果池中数据连接不够时一次增长多少个 --> <property name="acquireIncrement">5</property> <property name="initialPoolSize">20</property> <property name="minPoolSize">10</property> <property name="maxPoolSize">40</property> <property name="maxStatements">20</property> <property name="maxStatementsPerConnection">5</property> </named-config></c3p0-config> 注意: c3p0的配置文件内部可以包含命名配置文件和默认配置文件!默认是选择默认配置!如果需要切换命名配置可以在创建c3p0连接池的时候填入命名即可!
xxxxxxxxxxpublic class TestC3p0 { public static void main(String[] args) throws Exception { //1.创建C3P0连接池子 Connection connection = DataSourceUtils.getConnection(); Statement createStatement = connection.createStatement(); String sql = "select * from student;"; ResultSet resultSet = createStatement.executeQuery(sql); while (resultSet.next()) { System.out.println(resultSet.getString(1)); } DataSourceUtils.close(connection, createStatement, resultSet); } }基于c3p0连接池编写数据库操作工具类!
xxxxxxxxxx/** * 从连接池子中获取连接! * * C3P0的连接池子 * 0.获取连接池子对象 DBUtils * 1.获取连接 * 2.关闭资源 */public class DataSourceUtils { private static ComboPooledDataSource dataSource = new ComboPooledDataSource(); /** * 返回连接池对象方法 * @return c3p0连接池子 */ public static ComboPooledDataSource getDataSource(){ return dataSource; } /** * 连接池中获取连接的方法 * @return 连接 */ public static Connection getConnection(){ Connection conn = null; try { conn = dataSource.getConnection(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } return conn; } //关闭资源 public static void close(Connection conn){ if (conn != null) { try { conn.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } public static void close(Statement st){ if (st != null) { try { st.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } public static void close(ResultSet set){ if (set != null) { try { set.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } public static void close(Connection conn,Statement st){ close(conn); close(st); } public static void close(Connection conn,Statement st,ResultSet rt){ close(conn); close(st); close(rt); } }Druid 是目前比较流行的高性能的,分布式列存储的OLAP框架(具体来说是MOLAP)。它有如下几个特点:
一. 亚秒级查询
druid提供了快速的聚合能力以及亚秒级的OLAP查询能力,多租户的设计,是面向用户分析应用的理想方式。
二.实时数据注入
druid支持流数据的注入,并提供了数据的事件驱动,保证在实时和离线环境下事件的实效性和统一性
三.可扩展的PB级存储
druid集群可以很方便的扩容到PB的数据量,每秒百万级别的数据注入。即便在加大数据规模的情况下,也能保证时其效性
四.多环境部署
druid既可以运行在商业的硬件上,也可以运行在云上。它可以从多种数据系统中注入数据,包括hadoop,spark,kafka,storm和samza等
五.丰富的社区
druid拥有丰富的社区,供大家学习 xxxxxxxxxx /** * 阿里的数据库连接池 * 性能最好的 * Druid * */public class DruidUtils { //声明连接池对象 private static DruidDataSource ds; static{ ///实例化数据库连接池对象 ds=new DruidDataSource(); //实例化配置对象 Properties properties=new Properties(); try { //加载配置文件内容 properties.load(DruidUtils.class.getResourceAsStream("dbcpconfig.properties")); //设置驱动类全称 ds.setDriverClassName(properties.getProperty("driverClassName")); //设置连接的数据库 ds.setUrl(properties.getProperty("url")); //设置用户名 ds.setUsername(properties.getProperty("username")); //设置密码 ds.setPassword(properties.getProperty("password")); //设置最大连接数量 ds.setMaxActive(Integer.parseInt(properties.getProperty("maxActive"))); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } //获取连接对象 public static Connection getConnection() { try { return ds.getConnection(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; } } xxxxxxxxxxpublic class Druid_Test{ public void test1(){ findAll(); find("小千千","47983"); } public List<Master> findAll() { // TODO Auto-generated method stub Connection conn=null; PreparedStatement pstat=null; ResultSet rs=null; List<Master> masters=new ArrayList<Master>(); try{ conn=DruidUtils.getConnection(); pstat=conn.prepareStatement("select * from master"); rs=pstat.executeQuery(); while(rs.next()){ int id=rs.getInt("id"); String name=rs.getString("name"); String password=rs.getString("password"); int money=rs.getInt("money"); masters.add(new Master(id, name, password, money)); } return masters; }catch(Exception e){ throw new RuntimeException(e); }finally { DbUtils.release(rs, pstat, conn); } } public Master find(String name, String password) { // TODO Auto-generated method stub Connection conn=null; PreparedStatement pstat=null; ResultSet rs=null; Master master=null; try{ conn=DbUtils.getConnection(); pstat=conn.prepareStatement("select * from master where name=? and password=?"); pstat.setString(1, name); pstat.setString(2, password); rs=pstat.executeQuery(); if(rs.next()){ int id=rs.getInt("id"); int money=rs.getInt("money"); master=new Master(id, name, password, money); } return master; }catch(Exception e){ throw new RuntimeException(e); }finally { DbUtils.release(rs, pstat, conn); } }Commons DbUtils是Apache组织提供的一个对JDBC进行简单封装的开源工具类库,使用它能够简化JDBC应用程序的开发,同时也不会影响程序的性能。
DBUtils是java编程中的数据库操作实用工具,小巧简单实用,
1.对于数据表的读操作,他可以把结果转换成List,Array,Set等java集合,便于程序员操作;
2.对于数据表的写操作,也变得很简单(只需写sql语句)
3.可以使用数据源,使用JNDI,数据库连接池等技术来优化性能--重用已经构建好的数据库连接对象,而不像php,asp那样,费时费力的不断重复的构建和析构这样的对象。
DBUtils包括3个包:
org.apache.commons.dbutils
org.apache.commons.dbutils.handlers
org.apache.commons.dbutils.wrappers
DBUtils封装了对JDBC的操作,简化了JDBC操作,可以少写代码。
org.apache.commons.dbutils
DbUtils 关闭链接等操作
QueryRunner 进行查询的操作
org.apache.commons.dbutils.handlers
ArrayHandler :将ResultSet中第一行的数据转化成对象数组
ArrayListHandler将ResultSet中所有的数据转化成List,List中存放的是Object[]
BeanHandler :将ResultSet中第一行的数据转化成类对象
BeanListHandler :将ResultSet中所有的数据转化成List,List中存放的是类对象
ColumnListHandler :将ResultSet中某一列的数据存成List,List中存放的是Object对象
KeyedHandler :将ResultSet中存成映射,key为某一列对应为Map。Map中存放的是数据
MapHandler :将ResultSet中第一行的数据存成Map映射
MapListHandler :将ResultSet中所有的数据存成List。List中存放的是Map
ScalarHandler :将ResultSet中一条记录的其中某一列的数据存成Object
org.apache.commons.dbutils.wrappers
SqlNullCheckedResultSet :对ResultSet进行操作,改版里面的值
StringTrimmedResultSet :去除ResultSet中中字段的左右空格。Trim()
主要方法:
DbUtils类:启动类
ResultSetHandler接口:转换类型接口
MapListHandler类:实现类,把记录转化成List
BeanListHandler类:实现类,把记录转化成List,使记录为JavaBean类型的对象
Query Runner类:执行SQL语句的类
dbutils.jar
c3p0.jar
jdbc.jar
之前项目的info.properties
c3p0工具类
xxxxxxxxxxpublic class ResultHanlder { public void testArrayHander() throws SQLException { // ArrayHandler:适合取1条记录。把该条记录的每列值封装到一个数组中Object[] QueryRunner runner = new QueryRunner(C3P0Util.getDataSource()); Object[] query = runner.query("select * from day13 where id = ?", new ArrayHandler(), 9); for (Object object : query) { System.out.println(object); } } public void testArrayListHander() throws SQLException { // ArrayHandler:适合取1条记录。把该条记录的每列值封装到一个数组中Object[] QueryRunner runner = new QueryRunner(C3P0Util.getDataSource()); List<Object[]> query = runner.query("select * from day13 ", new ArrayListHandler()); for (Object[] objects : query) { for (Object object : objects) { System.out.println(object); } } } public void testColumnListHander() throws SQLException { // ColumnListHandler:取某一列的数据。封装到List中。 QueryRunner runner = new QueryRunner(C3P0Util.getDataSource()); List<Object> query = runner.query("select * from day13 ", new ColumnListHandler(2)); for (Object objects : query) { System.out.println(objects); } } public void testKeyedHandler() throws SQLException { // KeyedHandler:取多条记录,每一条记录封装到一个Map中,再把这个Map封装到另外一个Map中,key为指定的字段值 QueryRunner runner = new QueryRunner(C3P0Util.getDataSource()); Map<Object, Map<String, Object>> query = runner.query("select * from day13 ", new KeyedHandler(2)); for (Object key : query.keySet()) { System.out.println(key); for (Entry<String, Object> entry : query.get(key).entrySet()) { System.out.println("key:" + entry.getKey() + " values:" + entry.getValue()); } } } public void testMapHandler() throws SQLException { // MapHandler:适合取1条记录。把当前记录的列名和列值放到一个Map中 QueryRunner runner = new QueryRunner(C3P0Util.getDataSource()); Map<String, Object> query = runner.query("select * from day13 ", new MapHandler()); for (Entry<String, Object> entry : query.entrySet()) { System.out.println("key:" + entry.getKey() + " values:" + entry.getValue()); } } public void testMapListHandler() throws SQLException { // MapListHandler:适合取多条记录。把每条记录封装到一个Map中,再把Map封装到List中 QueryRunner runner = new QueryRunner(C3P0Util.getDataSource()); List<Map<String, Object>> query = runner.query("select * from day13 ", new MapListHandler()); for (Map<String, Object> entry : query) { for (Entry<String, Object> mapEntr : entry.entrySet()) { System.out.println("key:" + mapEntr.getKey() + " values:" + mapEntr.getValue()); } } } public void testScalarHandler() throws SQLException { // ScalarHandler:适合取单行单列数据 QueryRunner runner = new QueryRunner(C3P0Util.getDataSource()); Object query = runner.query("select count(*) from day13 ", new ScalarHandler()); System.out.println(query); } public void testBeanHandler() throws SQLException { // BeanHandler:适合取单行单列数据 QueryRunner runner = new QueryRunner(C3P0Util.getDataSource()); Day13 query = runner.query("select name,age from day13 ", new BeanHandler<Day13>(Day13.class)); System.out.println(query.toString()); }}1、使用数据库连接池和DbUtils改造之前的项目
1、描述数据库连接池的优缺点