【Java EE 学习第16天】【dbcp数据库连接池】【c3p0数据库连接池】

零、回顾之前使用的动态代理的方式实现的数据库连接池:

代码:

 1 package day16.utils;
 2
 3 import java.io.IOException;
 4 import java.lang.reflect.InvocationHandler;
 5 import java.lang.reflect.Method;
 6 import java.lang.reflect.Proxy;
 7 import java.sql.Connection;
 8 import java.sql.DriverManager;
 9 import java.sql.SQLException;
10 import java.util.LinkedList;
11 import java.util.Properties;
12
13 public class JDBCUtils {
14     private static LinkedList<Connection>pool=new LinkedList<Connection>();//定义连接池,使用LinkedList能提高效率
15     static{
16         Properties properties=new Properties();
17         try {
18             properties.load(JDBCUtils.class.getClassLoader().getResourceAsStream("config.properties"));
19             String driver=properties.getProperty("driver");
20             String username=properties.getProperty("username");
21             String password=properties.getProperty("password");
22             String url=properties.getProperty("url");
23             int connectionMaxNum=Integer.parseInt(properties.getProperty("connectionMaxNum"));
24             Class.forName(driver);
25             for(int i=0;i<connectionMaxNum;i++)
26             {
27                 final Connection conn=DriverManager.getConnection(url, username, password);
28                 //关键的一步:进行代理设置。
29                 Object proxy=Proxy.newProxyInstance(
30                         JDBCUtils.class.getClassLoader()
31                         , new Class[]{Connection.class},
32                         new InvocationHandler() {
33                             @Override
34                             public Object invoke(Object proxy, Method method, Object[] args)
35                                     throws Throwable {
36                                 //如果调用了close方法,则不要关闭连接,而应当将连接回收。
37                                 if(method.getName().equals("close"))
38                                 {
39                                     synchronized(pool)
40                                     {
41                                         pool.addLast((Connection) proxy);//这里进行强制转换
42                                         System.out.println("调用了close方法!回收 "+proxy+" ,剩余连接数为"+pool.size());
43                                         pool.notify();//从等待池中唤醒任意一条线程
44                                     }
45                                     return null;//返回值是null表名拦截该方法的执行。这里的return位置非常重要,一不小心就会是的创建反射对象失败
46                                 }
47                                 //如果调用了其他的方法,则要放行
48                                 else
49                                 {
50                                     System.out.println("调用了 "+method.getName()+" 方法,放行!");
51                                     return method.invoke(conn, args);//注意这里的对象是conn,而不是其它对象
52                                 }
53                             }
54                         });
55 //                System.out.println(proxy);
56                 pool.addLast((Connection) proxy);//这里添加的一定是被代理的对象
57             }
58             System.out.println(pool);
59         } catch (IOException e) {
60             e.printStackTrace();
61         } catch (ClassNotFoundException e) {
62             e.printStackTrace();
63         } catch (SQLException e) {
64             e.printStackTrace();
65         }
66     }
67     //获得连接对象的方法
68     public static Connection getConnection()
69     {
70         synchronized (pool) {
71             if(pool.size()==0)
72             {
73                 System.out.println("连接池中没有可用连接,等待中------------");
74                 try {
75                     pool.wait();//等待的方式,使用的是pool*************************
76                 } catch (InterruptedException e) {
77                     e.printStackTrace();
78                 }
79                 return getConnection();//递归调用该方法目的是解锁之后重新获得连接
80             }
81             else
82             {
83                 Connection conn=pool.removeFirst();
84                 System.out.println("分配一条连接,剩余连接数目为"+pool.size());
85                 return conn;
86             }
87         }
88     }
89 }

JDBCUtils.java

测试:

public void testByProxy() throws SQLException
    {
        Connection conn1=JDBCUtils.getConnection();
        Connection conn2=JDBCUtils.getConnection();
        Connection conn3=JDBCUtils.getConnection();
        conn1.close();
        Connection conn4=JDBCUtils.getConnection();
    }

测试代码

运行结果:

调用了 toString 方法,放行!
调用了 toString 方法,放行!
调用了 toString 方法,放行!
[[email protected], [email protected], [email protected]]
分配一条连接,剩余连接数目为2
分配一条连接,剩余连接数目为1
分配一条连接,剩余连接数目为0
调用了 toString 方法,放行!
调用了close方法!回收 [email protected] ,剩余连接数为1
分配一条连接,剩余连接数目为0

运行结果

和之前的相比有些改进:连接池使用LinkedList,效率更高。

功能增强的方式有两种:

  1.使用动态代理的方式

  2.使用包装的方式

实际上实现数据库连接池只需要实现一个接口:DataSource,然后改连接池就实现了标准化~

一、使用动态代理实现数据库连接池。

1.数据库连接池动态代理实现方式

package day16.utils;
//实现DataSource接口使用反射机制实现数据库连接池。
import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.util.LinkedList;
import java.util.Properties;
import java.util.logging.Logger;

import javax.sql.DataSource;

public class DBCPPools implements DataSource{
    private  LinkedList<Connection>pools=new LinkedList<Connection>();
    public DBCPPools()
    {
        try {
            Properties config=new Properties();
            config.load(DBCPPools.class.getClassLoader().getResourceAsStream("config.properties"));
            Class.forName(config.getProperty("driver"));
            String url=config.getProperty("url");
            String username=config.getProperty("username");
            String password=config.getProperty("password");
            for(int i=0;i<3;i++)
            {
                final Connection conn=DriverManager.getConnection(url,username,password);
                Object proxy=Proxy.newProxyInstance(
                        DBCPPools.class.getClassLoader(),
                        new Class[]{Connection.class},
                        new InvocationHandler() {
                            @Override
                            public Object invoke(Object proxy, Method method, Object[] args)
                                    throws Throwable {
                                if(method.getName().equals("close"))
                                {
                                    synchronized(pools)
                                    {
                                        pools.addLast((Connection) proxy);
                                        System.out.println("调用了close方法!回收 "+proxy+" ,剩余连接数为"+pools.size());
                                        pools.notify();
                                    }
                                    return null;
                                }
                                else
                                {
//                                    System.out.println(proxy(这里不能写上proxy,否则异常报出!!!!为什么????)+"调用了 "+method.getName()+" 方法,放行!");
                                    System.out.println("调用了 "+method.getName()+" 方法,放行!");
                                    return method.invoke(conn, args);
                                }
                            }
                        });
                pools.add((Connection) proxy);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
    //最重要的是实现这个方法。
    @Override
    public  Connection getConnection(){
        synchronized(pools)
        {
            if(pools.size()==0)
            {
                System.out.println("连接池中没有可用连接,等待中------------");
                try {
                    pools.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                return getConnection();
            }
            else
            {
                Connection conn=pools.removeFirst();
                System.out.println("分配一条连接,剩余连接数目为"+pools.size());
                return conn;
            }
        }
    }
    @Override
    public PrintWriter getLogWriter() throws SQLException {
        return null;
    }
    @Override
    public void setLogWriter(PrintWriter out) throws SQLException {
    }
    @Override
    public void setLoginTimeout(int seconds) throws SQLException {
    }
    @Override
    public int getLoginTimeout() throws SQLException {
        return 0;
    }
    @Override
    public <T> T unwrap(Class<T> iface) throws SQLException {
        return null;
    }
    @Override
    public boolean isWrapperFor(Class<?> iface) throws SQLException {
        return false;
    }
    @Override
    public Connection getConnection(String username, String password)
            throws SQLException {
        return null;
    }
    @Override
    public Logger getParentLogger() throws SQLFeatureNotSupportedException {
        return null;
    }
}

DBCPPools.java

2.测试代码

public void testImplementsDataSourceInterfaceByProxy() throws SQLException
    {
        DBCPPools pool=new DBCPPools();
        Connection conn1=pool.getConnection();
        System.out.println(conn1);
        System.out.println();

        Connection conn2=pool.getConnection();
        System.out.println(conn2);
        System.out.println();

        Connection conn3=pool.getConnection();
        System.out.println(conn3);
        System.out.println();
//        conn1.close();//如果这里没有注释掉,则可以拿到第四条连接,连接池大小默认为3
        Connection conn4=pool.getConnection();//第四条连接因为拿不到连接而进入等待池中。
        System.out.println(conn4);
    }

运行结果:

分配一条连接,剩余连接数目为2
调用了 toString 方法,放行!
com.mysql.jdbc.J[email protected]

分配一条连接,剩余连接数目为1
调用了 toString 方法,放行!
[email protected]

分配一条连接,剩余连接数目为0
调用了 toString 方法,放行!
[email protected]

连接池中没有可用连接,等待中------------

将关闭连接的代码放开:

分配一条连接,剩余连接数目为2
调用了 toString 方法,放行!
[email protected]

分配一条连接,剩余连接数目为1
调用了 toString 方法,放行!
[email protected]

分配一条连接,剩余连接数目为0
调用了 toString 方法,放行!
[email protected]

调用了 toString 方法,放行!
调用了close方法!回收 [email protected] ,剩余连接数为1
分配一条连接,剩余连接数目为0
调用了 toString 方法,放行!
[email protected]

二、使用包装的方法实现自定义数据库连接池

  1.包装对象:Connection类,这里作为数据库连接池的一个内部类(MyConnection)。

  2.使用包装的方法实现的数据库连接池:

  1 package day16.utils;
  2
  3 import java.io.PrintWriter;
  4 import java.sql.Array;
  5 import java.sql.Blob;
  6 import java.sql.CallableStatement;
  7 import java.sql.Clob;
  8 import java.sql.Connection;
  9 import java.sql.DatabaseMetaData;
 10 import java.sql.DriverManager;
 11 import java.sql.NClob;
 12 import java.sql.PreparedStatement;
 13 import java.sql.SQLClientInfoException;
 14 import java.sql.SQLException;
 15 import java.sql.SQLFeatureNotSupportedException;
 16 import java.sql.SQLWarning;
 17 import java.sql.SQLXML;
 18 import java.sql.Savepoint;
 19 import java.sql.Statement;
 20 import java.sql.Struct;
 21 import java.util.LinkedList;
 22 import java.util.Map;
 23 import java.util.Properties;
 24 import java.util.concurrent.Executor;
 25 import java.util.logging.Logger;
 26
 27 import javax.sql.DataSource;
 28
 29 //测试使用包装的方法定义一个数据库连接池
 30 public class MyDBCPpool implements DataSource{
 31     private LinkedList<Connection> pool =new LinkedList<Connection>();
 32     public MyDBCPpool()
 33     {
 34         Properties properties=new Properties();
 35         try {
 36             properties.load(JDBCUtils.class.getClassLoader().getResourceAsStream("config.properties"));
 37             String driver=properties.getProperty("driver");
 38             String username=properties.getProperty("username");
 39             String password=properties.getProperty("password");
 40             String url=properties.getProperty("url");
 41             int connectionMaxNum=Integer.parseInt(properties.getProperty("connectionMaxNum"));
 42             Class.forName(driver);
 43             for(int i=0;i<connectionMaxNum;i++)
 44             {
 45                 Connection conn=DriverManager.getConnection(url,username,password);
 46                 MyConnection connection =new MyConnection(conn);
 47                 pool.addLast(connection);
 48             }
 49         }
 50         catch(Exception e)
 51         {
 52             e.printStackTrace();
 53         }
 54     }
 55     @Override
 56     public Connection getConnection() throws SQLException {
 57         System.out.println(pool);
 58         synchronized(pool)
 59         {
 60             if(pool.size()==0)
 61             {
 62                 try {
 63                     pool.wait();
 64                 } catch (InterruptedException e) {
 65                     e.printStackTrace();
 66                 }
 67                 return getConnection();
 68             }
 69             else
 70             {
 71                 Connection conn=pool.removeFirst();
 72                 System.out.println("分配出一条连接:"+conn+" 剩余"+pool.size()+" 条连接!");
 73                 return conn;
 74             }
 75         }
 76     }
 77     @Override
 78     public Connection getConnection(String username, String password)
 79             throws SQLException {
 80         return null;
 81     }
 82     @Override
 83     public PrintWriter getLogWriter() throws SQLException {
 84         return null;
 85     }
 86     @Override
 87     public void setLogWriter(PrintWriter out) throws SQLException {
 88     }
 89     @Override
 90     public void setLoginTimeout(int seconds) throws SQLException {
 91     }
 92     @Override
 93     public int getLoginTimeout() throws SQLException {
 94         return 0;
 95     }
 96 //    @Override
 97     public Logger getParentLogger() throws SQLFeatureNotSupportedException {
 98         return null;
 99     }
100     @Override
101     public <T> T unwrap(Class<T> iface) throws SQLException {
102         return null;
103     }
104     @Override
105     public boolean isWrapperFor(Class<?> iface) throws SQLException {
106         return false;
107     }
108     class MyConnection implements Connection
109     {
110         private Connection conn;
111         public MyConnection(Connection conn){
112             this.conn=conn;
113         }
114         //重写close方法
115         @Override
116         public void close() throws SQLException {
117             synchronized(pool)
118             {120                 pool.addLast(this);            System.out.println(this+"还连接!剩余连接数:"+pool.size());
121                 pool.notify();
122             }
123         }
124         @Override
125         public <T> T unwrap(Class<T> iface) throws SQLException {
126             return conn.unwrap(iface);
127         }
128         @Override
129         public boolean isWrapperFor(Class<?> iface) throws SQLException {
130             return conn.isWrapperFor(iface);
131         }
132         @Override
133         public Statement createStatement() throws SQLException {
134             return conn.createStatement();
135         }
136         @Override
137         public PreparedStatement prepareStatement(String sql)
138                 throws SQLException {
139             return conn.prepareStatement(sql);
140         }
141         @Override
142         public CallableStatement prepareCall(String sql) throws SQLException {
143             return conn.prepareCall(sql);
144         }
145         @Override
146         public String nativeSQL(String sql) throws SQLException {
147             return conn.nativeSQL(sql);
148         }
149         @Override
150         public void setAutoCommit(boolean autoCommit) throws SQLException {
151             conn.setAutoCommit(autoCommit);
152         }
153         @Override
154         public boolean getAutoCommit() throws SQLException {
155             return conn.getAutoCommit();
156         }
157         @Override
158         public void commit() throws SQLException {
159             conn.commit();
160         }
161         @Override
162         public void rollback() throws SQLException {
163             conn.rollback();
164         }
165         @Override
166         public boolean isClosed() throws SQLException {
167             return conn.isClosed();
168         }
169         @Override
170         public DatabaseMetaData getMetaData() throws SQLException {
171             return conn.getMetaData();
172         }
173         @Override
174         public void setReadOnly(boolean readOnly) throws SQLException {
175             conn.setReadOnly(readOnly);
176         }
177         @Override
178         public boolean isReadOnly() throws SQLException {
179             return conn.isReadOnly();
180         }
181         @Override
182         public void setCatalog(String catalog) throws SQLException {
183             conn.setCatalog(catalog);
184         }
185         @Override
186         public String getCatalog() throws SQLException {
187             return conn.getCatalog();
188         }
189         @Override
190         public void setTransactionIsolation(int level) throws SQLException {
191             conn.setTransactionIsolation(level);
192         }
193         @Override
194         public int getTransactionIsolation() throws SQLException {
195             return conn.getTransactionIsolation();
196         }
197         @Override
198         public SQLWarning getWarnings() throws SQLException {
199             return conn.getWarnings();
200         }
201         @Override
202         public void clearWarnings() throws SQLException {
203             conn.clearWarnings();
204         }
205         @Override
206         public Statement createStatement(int resultSetType,
207                 int resultSetConcurrency) throws SQLException {
208             return conn.createStatement(resultSetType, resultSetConcurrency);
209         }
210         @Override
211         public PreparedStatement prepareStatement(String sql,
212                 int resultSetType, int resultSetConcurrency)
213                 throws SQLException {
214             return conn.prepareStatement(sql, resultSetType, resultSetConcurrency);
215         }
216         @Override
217         public CallableStatement prepareCall(String sql, int resultSetType,
218                 int resultSetConcurrency) throws SQLException {
219             return conn.prepareCall(sql, resultSetType, resultSetConcurrency);
220         }
221         @Override
222         public Map<String, Class<?>> getTypeMap() throws SQLException {
223             return conn.getTypeMap();
224         }
225         @Override
226         public void setTypeMap(Map<String, Class<?>> map) throws SQLException {
227             conn.setTypeMap(map);
228         }
229         @Override
230         public void setHoldability(int holdability) throws SQLException {
231             conn.setHoldability(holdability);
232         }
233         @Override
234         public int getHoldability() throws SQLException {
235             return conn.getHoldability();
236         }
237         @Override
238         public Savepoint setSavepoint() throws SQLException {
239             return conn.setSavepoint();
240         }
241         @Override
242         public Savepoint setSavepoint(String name) throws SQLException {
243             return conn.setSavepoint(name);
244         }
245         @Override
246         public void rollback(Savepoint savepoint) throws SQLException {
247             conn.rollback(savepoint);
248         }
249         @Override
250         public void releaseSavepoint(Savepoint savepoint) throws SQLException {
251             conn.releaseSavepoint(savepoint);
252         }
253         @Override
254         public Statement createStatement(int resultSetType,
255                 int resultSetConcurrency, int resultSetHoldability)
256                 throws SQLException {
257             return conn.createStatement(resultSetType, resultSetConcurrency, resultSetHoldability);
258         }
259         @Override
260         public PreparedStatement prepareStatement(String sql,
261                 int resultSetType, int resultSetConcurrency,
262                 int resultSetHoldability) throws SQLException {
263             return conn.prepareStatement(sql, resultSetType, resultSetConcurrency, resultSetHoldability);
264         }
265         @Override
266         public CallableStatement prepareCall(String sql, int resultSetType,
267                 int resultSetConcurrency, int resultSetHoldability)
268                 throws SQLException {
269             return conn.prepareCall(sql, resultSetType, resultSetConcurrency, resultSetHoldability);
270         }
271         @Override
272         public PreparedStatement prepareStatement(String sql,
273                 int autoGeneratedKeys) throws SQLException {
274             return conn.prepareStatement(sql, autoGeneratedKeys);
275         }
276         @Override
277         public PreparedStatement prepareStatement(String sql,
278                 int[] columnIndexes) throws SQLException {
279             return conn.prepareStatement(sql, columnIndexes);
280         }
281         @Override
282         public PreparedStatement prepareStatement(String sql,
283                 String[] columnNames) throws SQLException {
284             return conn.prepareStatement(sql, columnNames);
285         }
286         @Override
287         public Clob createClob() throws SQLException {
288             return conn.createClob();
289         }
290         @Override
291         public Blob createBlob() throws SQLException {
292             return conn.createBlob();
293         }
294         @Override
295         public NClob createNClob() throws SQLException {
296             return conn.createNClob();
297         }
298         @Override
299         public SQLXML createSQLXML() throws SQLException {
300             return conn.createSQLXML();
301         }
302         @Override
303         public boolean isValid(int timeout) throws SQLException {
304             return conn.isValid(timeout);
305         }
306         @Override
307         public void setClientInfo(String name, String value)
308                 throws SQLClientInfoException {
309             conn.setClientInfo(name, value);
310         }
311         @Override
312         public void setClientInfo(Properties properties)
313                 throws SQLClientInfoException {
314             conn.setClientInfo(properties);
315         }
316         @Override
317         public String getClientInfo(String name) throws SQLException {
318             return conn.getClientInfo(name);
319         }
320         @Override
321         public Properties getClientInfo() throws SQLException {
322             return conn.getClientInfo();
323         }
324         @Override
325         public Array createArrayOf(String typeName, Object[] elements)
326                 throws SQLException {
327             return conn.createArrayOf(typeName, elements);
328         }
329         @Override
330         public Struct createStruct(String typeName, Object[] attributes)
331                 throws SQLException {
332             return conn.createStruct(typeName, attributes);
333         }
334         @Override
335         public void setSchema(String schema) throws SQLException {
336         }
337         @Override
338         public String getSchema() throws SQLException {
339             return conn.getSchema();
340         }
341         @Override
342         public void abort(Executor executor) throws SQLException {
343         }
344         @Override
345         public void setNetworkTimeout(Executor executor, int milliseconds)
346                 throws SQLException {
347         }
348         @Override
349         public int getNetworkTimeout() throws SQLException {
350             return conn.getNetworkTimeout();
351         }
352     }
353 }

  3.和之前的相比有哪些改动?

    (1)将数据库连接池的初始化放在了构造方法中。

    (2)连接池中放的是重写的Connection对象。

    (3)没有使用动态代理,效率更高。

    (4)将重写的Connection类放到了连接池类的内部作为内部类使用。

  4.测试代码

public void testMyDBCPpool() throws SQLException
    {
        MyDBCPpool pool=new MyDBCPpool();
        Connection conn1=pool.getConnection();
        System.out.println(conn1);
        Connection conn2=pool.getConnection();
        System.out.println(conn2);
        Connection conn3=pool.getConnection();
        System.out.println(conn3);
        conn1.close();
        Connection conn4=pool.getConnection();//第四条连接因为拿不到连接而进入等待池中。
        System.out.println(conn4);
    }

  6.运行结果:

[[email protected], [email protected], [email protected]]
分配出一条连接:[email protected]13f7cd2 剩余2 条连接!
[email protected]
[[email protected], [email protected]]
分配出一条连接:[email protected] 剩余1 条连接!
[email protected]
[[email protected]]
分配出一条连接:[email protected] 剩余0 条连接!
[email protected]
[email protected]还连接!剩余连接数:1
[[email protected]]
分配出一条连接:[email protected]13f7cd2 剩余0 条连接!
[email protected]

  分析和总结:实际上使用DBCP数据库连接池原理和这基本上差不多,所以该数据库连接池的名字为MyDBCPpool,下面开始进入正题。



【Java EE 学习第16天】【dbcp数据库连接池】【c3p0数据库连接池】

时间: 2024-10-21 17:03:55

【Java EE 学习第16天】【dbcp数据库连接池】【c3p0数据库连接池】的相关文章

【Java EE 学习第16天】【dbutils的使用方法】

一.为什么要使用dbutils 使用dbutils可以极大程度的简化代码书写,使得开发进度更快,效率更高 二.dbutils下载地址 http://commons.apache.org/proper/commons-dbutils/download_dbutils.cgi 出现的ds为数据源对象,可以是某个数据库连接池的DataSource,也可以是自定义数据库连接池的DataSource,这里我是用了dbcp数据库连接池. 1 package day16.regular.utils; 2 3

Java EE 学习(7):IDEA + maven + spring 搭建 web(3)- 配置数据库

参考: https://my.oschina.net/gaussik/blog/513444 注:在阅读本文前,请先阅读: Java EE 学习(5):IDEA + maven + spring 搭建 web(1) Java EE 学习(6):IDEA + maven + spring 搭建 web(2) 5 数据库配置 下面,就要通过一个简单的例子,来介绍 SpringMVC 如何集成 Spring Data JPA(由 Hibernate JPA 提供),来进行强大的数据库访问,并通过本章节

Java EE 学习(5):IDEA + maven + spring 搭建 web(1)

参考:http://www.cnblogs.com/lonelyxmas/p/5397422.html http://www.ctolib.com/docs-IntelliJ-IDEA-c--159047.html 孔老师的<SpringMVC视频教程> 记录: 本节主要完成 使用 maven 管理 spring + 项目 包,搭建 maven+spring 的 web 项目平台. 前提: 已安装并配置好 - Intellij IDEA 16.3.5 Ultimate - JDK 1.8.0_

Java EE学习——Quartz的Cron表达式

经历过低谷后,还是要好好学习,越失落会越来越落后. 今天写一下Cron表达式的用法,虽然是之前自己写的,也过了挺长一段时间,这次就拿出来作为回顾吧. Cron表达式是Quartz的精髓(个人觉得),比如我们想设定淘宝“秒杀”的那一秒时间,完全可以用下面的方法设置执行时间. Calendar cal = Calendar.getInstance(); //设置将要发生的时间... cal.set(Calendar.DATE, xxx); //.......常规的生成scheduler和job //

Java EE学习--Quartz基本用法

新浪博客完全不适合写技术类文章.本来是想找一个技术性的博客发发自己最近学的东西,发现博客园起源于咱江苏,一个非常质朴的网站,行,咱要养成好习惯,以后没事多总结总结经验吧.很多时候都在网上搜索别人的总结,我自己也总结些东西,或许多多少少能帮得上别人. 首先提到的是Quartz,一个开源的定期执行计划任务的框架.其实我内心好奇这个框架很久了,像那些能定时修改数据库数据,定时分配任务的功能一直觉得很神奇.心动不如行动,今天我就小小的学习了一下用法,力求言简意赅,大家都懂的我就不说了. 第一步:下载Qu

JAVA EE 学习笔记[V1 jsp编程]

在三月初学校开设了javaee的课程,也就此展开了对javaee基础的学习.然后老师也对这次的课程有一定要求.前面的基础就为最终的作业做准备啦~ 在上学期我们学习了java相关知识,也对java se 的安装使用有了一定的认知,而java ee则是构建于java se 平台之上的一套多层的,可扩展的的网络应用. 学习java ee我们首先进行环境的搭建.无非就是使用 tomcat进行服务器的搭建和jdk环境变量配置.而IDE这方面我们选择myeclipse 2016 CI(这个编译器自带tomc

Java EE 学习(8):IDEA + maven + spring 搭建 web(4)- 用户管理

转载:Gaussic(一个致力于AI研究却不得不兼顾项目的研究生) 注:在阅读本文前,请先阅读: Java EE 学习(5):IDEA + maven + spring 搭建 web(1) ava EE 学习(6):IDEA + maven + spring 搭建 web(2)- 配置 Spring Java EE 学习(7):IDEA + maven + spring 搭建 web(3)- 配置数据库 记录: 通过对用户表的管理,更加深入地讲解SpringMVC的操作. 6 用户管理 既然我们

Java EE 学习(9):IDEA + maven + spring 搭建 web(5)- 博客文章管理

转载:Gaussic(一个致力于AI研究却不得不兼顾项目的研究生) . 注:在阅读本文前,请先阅读: Java EE 学习(5):IDEA + maven + spring 搭建 web(1) Java EE 学习(6):IDEA + maven + spring 搭建 web(2)- 配置 Spring Java EE 学习(7):IDEA + maven + spring 搭建 web(3)- 配置数据库 Java EE 学习(8):IDEA + maven + spring 搭建 web(

Java EE学习之旅1——HeadFirstJavaEE

因为找到的实习是用Java开发的公司,所以来学习一下Java EE的知识. 首先找来了书<轻量级Java EE企业应用实战>. 啊不得不说学了Java之后直接看这个还是完全不行呢,好多名词看都没有看过啊哈哈. 首先来看看都些啥看不懂的词... 1.JSP.Servlet和JavaBean JSP和Servlet都是用在表现层的东西,而实质上JSP编译成Servlet才运行. 但Servlet开发成本太大,所以用JSP. JavaBean用来通信交换表现层和底层数据. 2.MVC和Struts