| @@ -0,0 +1,184 @@ | |||
| package cn.zzs.dbcp; | |||
| import java.io.InputStream; | |||
| import java.sql.Connection; | |||
| import java.sql.ResultSet; | |||
| import java.sql.SQLException; | |||
| import java.sql.Statement; | |||
| import java.util.Properties; | |||
| import javax.sql.DataSource; | |||
| import org.apache.commons.dbcp2.BasicDataSourceFactory; | |||
| import org.apache.commons.logging.Log; | |||
| import org.apache.commons.logging.LogFactory; | |||
| /** | |||
| * @ClassName: BasicDataSourceUtil | |||
| * @Description: 用于获取数据库连接对象的工具类。这里使用BasicDataSource获取连接对象,获取到的连接对象可满足一般的数据库操作 | |||
| * @author: zzs | |||
| * @date: 2019年8月31日 下午9:05:08 | |||
| */ | |||
| public class BasicDataSourceUtil { | |||
| private static DataSource dataSource; | |||
| private static ThreadLocal<Connection> tl = new ThreadLocal<>(); | |||
| private static final Object obj = new Object(); | |||
| private static final Log log = LogFactory.getLog(BasicDataSourceUtil.class); | |||
| static { | |||
| init(); | |||
| } | |||
| /** | |||
| * | |||
| * @Title: getConnection | |||
| * @Description: 获取数据库连接对象的方法,线程安全 | |||
| * @author: zzs | |||
| * @date: 2019年8月31日 下午9:22:29 | |||
| * @return: Connection | |||
| */ | |||
| public static Connection getConnection() throws SQLException { | |||
| // 从当前线程中获取连接对象 | |||
| Connection connection = tl.get(); | |||
| // 判断为空的话,创建连接并绑定到当前线程 | |||
| if(connection == null) { | |||
| synchronized(obj) { | |||
| if(tl.get() == null) { | |||
| connection = createConnection(); | |||
| tl.set(connection); | |||
| } | |||
| } | |||
| } | |||
| return connection; | |||
| } | |||
| /** | |||
| * | |||
| * @Title: release | |||
| * @Description: 释放资源 | |||
| * @author: zzs | |||
| * @date: 2019年8月31日 下午9:39:24 | |||
| * @param conn | |||
| * @param statement | |||
| * @return: void | |||
| */ | |||
| public static void release(Connection conn, Statement statement, ResultSet resultSet) { | |||
| if(resultSet != null) { | |||
| try { | |||
| resultSet.close(); | |||
| } catch(SQLException e) { | |||
| log.error("关闭ResultSet对象异常", e); | |||
| } | |||
| } | |||
| if(statement != null) { | |||
| try { | |||
| statement.close(); | |||
| } catch(SQLException e) { | |||
| log.error("关闭Statement对象异常", e); | |||
| } | |||
| } | |||
| // 注意:这里不关闭连接 | |||
| if(conn != null) { | |||
| try { | |||
| conn.close(); | |||
| tl.remove(); | |||
| } catch(SQLException e) { | |||
| log.error("关闭Connection对象异常", e); | |||
| } | |||
| } | |||
| } | |||
| /** | |||
| * | |||
| * @Title: startTrasaction | |||
| * @Description: 开启事务 | |||
| * @author: zzs | |||
| * @date: 2019年11月3日 上午11:03:24 | |||
| * @return: void | |||
| * @throws Exception | |||
| */ | |||
| public static void startTrasaction() throws SQLException { | |||
| getConnection().setAutoCommit(false); | |||
| } | |||
| /** | |||
| * | |||
| * @Title: commit | |||
| * @Description: 提交事务 | |||
| * @author: zzs | |||
| * @date: 2019年11月3日 上午11:05:54 | |||
| * @return: void | |||
| */ | |||
| public static void commit() { | |||
| Connection connection = tl.get(); | |||
| if(connection != null) { | |||
| try { | |||
| connection.commit(); | |||
| connection.setAutoCommit(true); | |||
| } catch(SQLException e) { | |||
| log.error("提交事务失败", e); | |||
| } | |||
| } | |||
| } | |||
| /** | |||
| * | |||
| * @Title: rollback | |||
| * @Description: 回滚事务 | |||
| * @author: zzs | |||
| * @date: 2019年11月3日 上午11:08:12 | |||
| * @return: void | |||
| */ | |||
| public static void rollback() { | |||
| Connection connection = tl.get(); | |||
| if(connection != null) { | |||
| try { | |||
| connection.rollback(); | |||
| connection.setAutoCommit(true); | |||
| } catch(SQLException e) { | |||
| log.error("回滚事务失败", e); | |||
| } | |||
| } | |||
| } | |||
| /** | |||
| * | |||
| * @Title: createConnection | |||
| * @Description: 创建数据库连接 | |||
| * @author: zzs | |||
| * @date: 2019年8月31日 下午9:27:03 | |||
| * @return: Connection | |||
| * @throws SQLException | |||
| */ | |||
| private static Connection createConnection() throws SQLException { | |||
| Connection conn = null; | |||
| // 获得连接 | |||
| conn = dataSource.getConnection(); | |||
| return conn; | |||
| } | |||
| /** | |||
| * @Title: init | |||
| * @Description: 根据指定配置文件创建数据源对象 | |||
| * @author: zzs | |||
| * @date: 2019年9月1日 上午10:53:05 | |||
| * @return: void | |||
| * @throws Exception | |||
| */ | |||
| private static void init() { | |||
| // 导入配置文件 | |||
| Properties properties = new Properties(); | |||
| InputStream in = BasicDataSourceUtil.class.getClassLoader().getResourceAsStream("jdbc.properties"); | |||
| try { | |||
| properties.load(in); | |||
| // 根据配置文件内容获得数据源对象 | |||
| dataSource = BasicDataSourceFactory.createDataSource(properties); | |||
| } catch(Exception ex) { | |||
| throw new RuntimeException("根据指定配置文件创建数据源出错", ex); | |||
| } | |||
| } | |||
| } | |||
| @@ -1,136 +0,0 @@ | |||
| package cn.zzs.dbcp; | |||
| import java.io.IOException; | |||
| import java.io.InputStream; | |||
| import java.sql.Connection; | |||
| import java.sql.ResultSet; | |||
| import java.sql.SQLException; | |||
| import java.sql.Statement; | |||
| import java.util.Properties; | |||
| import javax.sql.DataSource; | |||
| import org.apache.commons.dbcp2.BasicDataSourceFactory; | |||
| /** | |||
| * @ClassName: JDBCUtil | |||
| * @Description: 用于获取数据库连接对象的工具类 | |||
| * @author: zzs | |||
| * @date: 2019年8月31日 下午9:05:08 | |||
| */ | |||
| public class JDBCUtil { | |||
| private static DataSource dataSource; | |||
| private static ThreadLocal<Connection> tl = new ThreadLocal<>(); | |||
| private static Object obj = new Object(); | |||
| static { | |||
| init(); | |||
| } | |||
| /** | |||
| * | |||
| * @Title: getConnection | |||
| * @Description: 获取数据库连接对象的方法,线程安全 | |||
| * @author: zzs | |||
| * @date: 2019年8月31日 下午9:22:29 | |||
| * @return: Connection | |||
| */ | |||
| public static Connection getConnection(){ | |||
| //从当前线程中获取连接对象 | |||
| Connection connection = tl.get(); | |||
| //判断为空的话,创建连接并绑定到当前线程 | |||
| if(connection == null) { | |||
| synchronized (obj) { | |||
| if(tl.get() == null) { | |||
| connection = createConnection(); | |||
| tl.set(connection); | |||
| } | |||
| } | |||
| } | |||
| return connection; | |||
| } | |||
| /** | |||
| * | |||
| * @Title: release | |||
| * @Description: 释放资源 | |||
| * @author: zzs | |||
| * @date: 2019年8月31日 下午9:39:24 | |||
| * @param conn | |||
| * @param statement | |||
| * @return: void | |||
| */ | |||
| public static void release(Connection conn,Statement statement,ResultSet resultSet) { | |||
| if(resultSet!=null) { | |||
| try { | |||
| resultSet.close(); | |||
| } catch (SQLException e) { | |||
| System.err.println("关闭ResultSet对象异常"); | |||
| e.printStackTrace(); | |||
| } | |||
| } | |||
| if(statement != null) { | |||
| try { | |||
| statement.close(); | |||
| } catch (SQLException e) { | |||
| System.err.println("关闭Statement对象异常"); | |||
| e.printStackTrace(); | |||
| } | |||
| } | |||
| //注意:这里不关闭连接 | |||
| if(conn!=null) { | |||
| try { | |||
| //如果连接失效的话,从当前线程的绑定中删除 | |||
| if(!conn.isValid(3)) { | |||
| tl.remove(); | |||
| } | |||
| } catch (SQLException e) { | |||
| System.err.println("校验连接有效性"); | |||
| e.printStackTrace(); | |||
| } | |||
| } | |||
| } | |||
| /** | |||
| * | |||
| * @Title: createConnection | |||
| * @Description: 创建数据库连接 | |||
| * @author: zzs | |||
| * @date: 2019年8月31日 下午9:27:03 | |||
| * @return: Connection | |||
| */ | |||
| private static Connection createConnection(){ | |||
| Connection conn = null; | |||
| //获得连接 | |||
| try { | |||
| conn = dataSource.getConnection(); | |||
| } catch (SQLException e) { | |||
| System.err.println("从数据源获取连接失败"); | |||
| e.printStackTrace(); | |||
| } | |||
| return conn; | |||
| } | |||
| /** | |||
| * @Title: init | |||
| * @Description: 根据指定配置文件创建数据源对象 | |||
| * @author: zzs | |||
| * @date: 2019年9月1日 上午10:53:05 | |||
| * @return: void | |||
| */ | |||
| private static void init() { | |||
| //导入配置文件 | |||
| Properties properties = new Properties(); | |||
| InputStream in = JDBCUtil.class.getClassLoader().getResourceAsStream("jdbc.properties"); | |||
| try { | |||
| properties.load(in); | |||
| //根据配置文件内容获得数据源对象 | |||
| dataSource = BasicDataSourceFactory.createDataSource(properties); | |||
| } catch (IOException e) { | |||
| System.err.println("导入配置文件出错"); | |||
| e.printStackTrace(); | |||
| } catch (Exception e) { | |||
| System.err.println("根据指定配置文件创建数据源出错"); | |||
| e.printStackTrace(); | |||
| } | |||
| } | |||
| } | |||
| @@ -1,99 +1,183 @@ | |||
| #数据库基本配置 | |||
| #\u6570\u636e\u5e93\u57fa\u672c\u914d\u7f6e | |||
| driverClassName=com.mysql.cj.jdbc.Driver | |||
| url=jdbc:mysql://localhost:3306/demo?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&useSSL=true | |||
| url=jdbc:mysql://localhost:3306/github_demo?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&useSSL=true | |||
| username=root | |||
| password=root | |||
| #-------------连接数据相关参数-------------------------------- | |||
| #初始化连接:连接池启动时创建的初始化连接数量 | |||
| #默认为0 | |||
| #-------------\u8fde\u63a5\u6c60\u6570\u636e\u76f8\u5173\u53c2\u6570-------------------------------- | |||
| #\u521d\u59cb\u5316\u8fde\u63a5\u6570\u91cf:\u8fde\u63a5\u6c60\u542f\u52a8\u65f6\u521b\u5efa\u7684\u521d\u59cb\u5316\u8fde\u63a5\u6570\u91cf | |||
| #\u9ed8\u8ba4\u4e3a0 | |||
| initialSize=0 | |||
| #最大活动连接 | |||
| #连接池在同一时间能够分配的最大活动连接的数量, 如果设置为非正数则表示不限制 | |||
| #默认为8 | |||
| maxActive=8 | |||
| #最大空闲连接 | |||
| #连接池中容许保持空闲状态的最大连接数量,超过的空闲连接将被释放,如果设置为负数表示不限制 | |||
| #默认为8 | |||
| #\u6700\u5927\u6d3b\u52a8\u8fde\u63a5\u6570\u91cf:\u8fde\u63a5\u6c60\u5728\u540c\u4e00\u65f6\u95f4\u80fd\u591f\u5206\u914d\u7684\u6700\u5927\u6d3b\u52a8\u8fde\u63a5\u7684\u6570\u91cf, \u5982\u679c\u8bbe\u7f6e\u4e3a\u8d1f\u6570\u5219\u8868\u793a\u4e0d\u9650\u5236 | |||
| #\u9ed8\u8ba4\u4e3a8 | |||
| maxTotal=8 | |||
| #\u6700\u5927\u7a7a\u95f2\u8fde\u63a5:\u8fde\u63a5\u6c60\u4e2d\u5bb9\u8bb8\u4fdd\u6301\u7a7a\u95f2\u72b6\u6001\u7684\u6700\u5927\u8fde\u63a5\u6570\u91cf,\u8d85\u8fc7\u7684\u7a7a\u95f2\u8fde\u63a5\u5c06\u88ab\u91ca\u653e,\u5982\u679c\u8bbe\u7f6e\u4e3a\u8d1f\u6570\u8868\u793a\u4e0d\u9650\u5236 | |||
| #\u9ed8\u8ba4\u4e3a8 | |||
| maxIdle=8 | |||
| #最小空闲连接 | |||
| #连接池中容许保持空闲状态的最小连接数量,低于这个数量将创建新的连接,如果设置为0则不创建 | |||
| #默认为0 | |||
| #\u6700\u5c0f\u7a7a\u95f2\u8fde\u63a5:\u8fde\u63a5\u6c60\u4e2d\u5bb9\u8bb8\u4fdd\u6301\u7a7a\u95f2\u72b6\u6001\u7684\u6700\u5c0f\u8fde\u63a5\u6570\u91cf,\u4f4e\u4e8e\u8fd9\u4e2a\u6570\u91cf\u5c06\u521b\u5efa\u65b0\u7684\u8fde\u63a5,\u5982\u679c\u8bbe\u7f6e\u4e3a0\u5219\u4e0d\u521b\u5efa | |||
| #\u6ce8\u610f\uff1atimeBetweenEvictionRunsMillis\u4e3a\u6b63\u6570\u65f6\uff0c\u8fd9\u4e2a\u53c2\u6570\u624d\u80fd\u751f\u6548\u3002 | |||
| #\u9ed8\u8ba4\u4e3a0 | |||
| minIdle=0 | |||
| #最大等待时间 | |||
| #当没有可用连接时,连接池等待连接被归还的最大时间(以毫秒计数),超过时间则抛出异常,如果设置为-1表示无限等待 | |||
| #默认无限 | |||
| maxWait=-1 | |||
| #-------------事务相关的属性-------------------------------- | |||
| #连接池创建的连接的默认的auto-commit状态 | |||
| #默认为true | |||
| defaultAutoCommit=false | |||
| #连接池创建的连接的默认的read-only状态. 如果没有设置则setReadOnly方法将不会被调用. (某些驱动不支持只读模式,比如:Informix) | |||
| #默认值由驱动决定 | |||
| #defaultReadOnly=false | |||
| #连接池创建的连接的默认的TransactionIsolation状态 | |||
| #可用值为下列之一:NONE,READ_UNCOMMITTED, READ_COMMITTED, REPEATABLE_READ, SERIALIZABLE | |||
| #默认值由驱动决定 | |||
| defaultTransactionIsolation=REPEATABLE_READ | |||
| #连接池创建的连接的默认的catalog | |||
| #defaultCatalog | |||
| #-------------连接检查情况-------------------------------- | |||
| #SQL查询,用来验证从连接池取出的连接,在将连接返回给调用者之前.如果指定,则查询必须是一个SQL SELECT并且必须返回至少一行记录 | |||
| validationQuery= select 1 | |||
| #指明是否在从池中取出连接前进行检验,如果检验失败,则从池中去除连接并尝试取出另一个. | |||
| #注意: 设置为true后如果要生效,validationQuery参数必须设置为非空字符串 | |||
| #默认为true | |||
| #\u6700\u5927\u7b49\u5f85\u65f6\u95f4 | |||
| #\u5f53\u6ca1\u6709\u53ef\u7528\u8fde\u63a5\u65f6,\u8fde\u63a5\u6c60\u7b49\u5f85\u8fde\u63a5\u88ab\u5f52\u8fd8\u7684\u6700\u5927\u65f6\u95f4(\u4ee5\u6beb\u79d2\u8ba1\u6570),\u8d85\u8fc7\u65f6\u95f4\u5219\u629b\u51fa\u5f02\u5e38,\u5982\u679c\u8bbe\u7f6e\u4e3a<=0\u8868\u793a\u65e0\u9650\u7b49\u5f85 | |||
| #\u9ed8\u8ba4-1 | |||
| maxWaitMillis=-1 | |||
| #-------------\u8fde\u63a5\u68c0\u67e5\u60c5\u51b5-------------------------------- | |||
| #\u901a\u8fc7SQL\u67e5\u8be2\u68c0\u6d4b\u8fde\u63a5,\u6ce8\u610f\u5fc5\u987b\u8fd4\u56de\u81f3\u5c11\u4e00\u884c\u8bb0\u5f55 | |||
| #\u9ed8\u8ba4\u4e3a\u7a7a\u3002\u5373\u4f1a\u8c03\u7528Connection\u7684isValid\u548cisClosed\u8fdb\u884c\u68c0\u6d4b | |||
| #\u6ce8\u610f\uff1a\u5982\u679c\u662foracle\u6570\u636e\u5e93\u7684\u8bdd\uff0c\u5e94\u8be5\u6539\u4e3aselect 1 from dual | |||
| validationQuery=select 1 from dual | |||
| #SQL\u68c0\u9a8c\u8d85\u65f6\u65f6\u95f4 | |||
| validationQueryTimeout=-1 | |||
| #\u662f\u5426\u4ece\u6c60\u4e2d\u53d6\u51fa\u8fde\u63a5\u524d\u8fdb\u884c\u68c0\u9a8c\u3002 | |||
| #\u9ed8\u8ba4\u4e3atrue | |||
| testOnBorrow=true | |||
| #指明是否在归还到池中前进行检验 | |||
| #注意: 设置为true后如果要生效,validationQuery参数必须设置为非空字符串 | |||
| #默认为false | |||
| #\u662f\u5426\u5728\u5f52\u8fd8\u5230\u6c60\u4e2d\u524d\u8fdb\u884c\u68c0\u9a8c | |||
| #\u9ed8\u8ba4\u4e3afalse | |||
| testOnReturn=false | |||
| #是否开启空闲资源监测。 | |||
| #注意: 设置为true后如果要生效,validationQuery参数必须设置为非空字符串 | |||
| #默认为false | |||
| testWhileIdle= true | |||
| #空闲资源的检测周期(单位为毫秒)。默认-1:不检测。建议设置,周期自行选择。timeBetweenEvictionRunsMillis=30000 | |||
| #做空闲资源检测时,每次的采样数。默认3。 | |||
| #可根据自身应用连接数进行微调,如果设置为-1,就是对所有连接做空闲监测。 | |||
| #\u662f\u5426\u5f00\u542f\u7a7a\u95f2\u8d44\u6e90\u56de\u6536\u5668\u3002 | |||
| #\u9ed8\u8ba4\u4e3afalse | |||
| testWhileIdle=false | |||
| #\u7a7a\u95f2\u8d44\u6e90\u7684\u68c0\u6d4b\u5468\u671f(\u5355\u4f4d\u4e3a\u6beb\u79d2)\u3002 | |||
| #\u9ed8\u8ba4-1\u3002\u5373\u7a7a\u95f2\u8d44\u6e90\u56de\u6536\u5668\u4e0d\u5de5\u4f5c\u3002 | |||
| timeBetweenEvictionRunsMillis=-1 | |||
| #\u505a\u7a7a\u95f2\u8d44\u6e90\u56de\u6536\u5668\u65f6\uff0c\u6bcf\u6b21\u7684\u91c7\u6837\u6570\u3002 | |||
| #\u9ed8\u8ba43\uff0c\u5355\u4f4d\u6beb\u79d2\u3002\u5982\u679c\u8bbe\u7f6e\u4e3a-1\uff0c\u5c31\u662f\u5bf9\u6240\u6709\u8fde\u63a5\u505a\u7a7a\u95f2\u76d1\u6d4b\u3002 | |||
| numTestsPerEvictionRun=3 | |||
| #资源池中资源最小空闲时间(单位为毫秒),达到此值后空闲资源将被移除。 | |||
| #默认值1000*60*30 = 30分钟。建议默认,或根据自身业务选择。 | |||
| #\u8d44\u6e90\u6c60\u4e2d\u8d44\u6e90\u6700\u5c0f\u7a7a\u95f2\u65f6\u95f4(\u5355\u4f4d\u4e3a\u6beb\u79d2)\uff0c\u8fbe\u5230\u6b64\u503c\u540e\u5c06\u88ab\u79fb\u9664\u3002 | |||
| #\u9ed8\u8ba4\u503c1000*60*30 = 30\u5206\u949f | |||
| minEvictableIdleTimeMillis=1800000 | |||
| #-------------缓存语句-------------------------------- | |||
| #开启池的prepared statement 池功能 | |||
| #注意: 确认连接还有剩余资源可以留给其他statement | |||
| #默认为false | |||
| #\u8d44\u6e90\u6c60\u4e2d\u8d44\u6e90\u6700\u5c0f\u7a7a\u95f2\u65f6\u95f4(\u5355\u4f4d\u4e3a\u6beb\u79d2)\uff0c\u8fbe\u5230\u6b64\u503c\u540e\u5c06\u88ab\u79fb\u9664\u3002\u4f46\u662f\u4f1a\u4fdd\u8bc1minIdle | |||
| #\u9ed8\u8ba4\u503c-1 | |||
| #softMinEvictableIdleTimeMillis=-1 | |||
| #\u7a7a\u95f2\u8d44\u6e90\u56de\u6536\u7b56\u7565 | |||
| #\u9ed8\u8ba4org.apache.commons.pool2.impl.DefaultEvictionPolicy | |||
| #\u5982\u679c\u8981\u81ea\u5b9a\u4e49\u7684\u8bdd\uff0c\u9700\u8981\u5b9e\u73b0EvictionPolicy\u91cd\u5199evict\u65b9\u6cd5 | |||
| evictionPolicyClassName=org.apache.commons.pool2.impl.DefaultEvictionPolicy | |||
| #\u8fde\u63a5\u6700\u5927\u5b58\u6d3b\u65f6\u95f4\u3002\u975e\u6b63\u6570\u8868\u793a\u4e0d\u9650\u5236 | |||
| #\u9ed8\u8ba4-1 | |||
| maxConnLifetimeMillis=-1 | |||
| #\u5f53\u8fbe\u5230maxConnLifetimeMillis\u88ab\u5173\u95ed\u65f6\uff0c\u662f\u5426\u6253\u5370\u76f8\u5173\u6d88\u606f | |||
| #\u9ed8\u8ba4true | |||
| #\u6ce8\u610f\uff1amaxConnLifetimeMillis\u8bbe\u7f6e\u4e3a\u6b63\u6570\u65f6\uff0c\u8fd9\u4e2a\u53c2\u6570\u624d\u6709\u6548 | |||
| logExpiredConnections=true | |||
| #-------------\u7f13\u5b58\u8bed\u53e5-------------------------------- | |||
| #\u662f\u5426\u7f13\u5b58PreparedStatements\uff0c\u8fd9\u4e2a\u529f\u80fd\u5728\u4e00\u4e9b\u652f\u6301\u6e38\u6807\u7684\u6570\u636e\u5e93\u4e2d\u53ef\u4ee5\u6781\u5927\u63d0\u9ad8\u6027\u80fd\uff08Oracle\u3001SQL Server\u3001DB2\u3001Sybase\uff09 | |||
| #\u9ed8\u8ba4\u4e3afalse | |||
| poolPreparedStatements=false | |||
| #statement池能够同时分配的打开的statements的最大数量, 如果设置为0表示不限制 | |||
| #默认为0 | |||
| maxOpenPreparedStatements=0 | |||
| #-------------连接泄漏回收参数-------------------------------- | |||
| #标记是否删除泄露的连接,如果他们超过了removeAbandonedTimout的限制. | |||
| #如果设置为true, 连接被认为是被泄露并且可以被删除,如果空闲时间超过removeAbandonedTimeout. | |||
| #设置为true可以为写法糟糕的没有关闭连接的程序修复数据库连接. | |||
| #默认为false | |||
| removeAbandoned=false | |||
| #泄露的连接可以被删除的超时值, 单位秒 | |||
| #默认为300 | |||
| #\u7f13\u5b58PreparedStatements\u7684\u6700\u5927\u4e2a\u6570 | |||
| #\u9ed8\u8ba4\u4e3a-1 | |||
| #\u6ce8\u610f\uff1apoolPreparedStatements\u4e3atrue\u65f6\uff0c\u8fd9\u4e2a\u53c2\u6570\u624d\u6709\u6548 | |||
| maxOpenPreparedStatements=-1 | |||
| #\u7f13\u5b58read-only\u548cauto-commit\u72b6\u6001\u3002\u8bbe\u7f6e\u4e3atrue\u7684\u8bdd\uff0c\u6240\u6709\u8fde\u63a5\u7684\u72b6\u6001\u90fd\u4f1a\u662f\u4e00\u6837\u7684\u3002 | |||
| #\u9ed8\u8ba4\u662ftrue | |||
| cacheState=true | |||
| #-------------\u4e8b\u52a1\u76f8\u5173\u7684\u5c5e\u6027-------------------------------- | |||
| #\u8fde\u63a5\u6c60\u521b\u5efa\u7684\u8fde\u63a5\u7684\u9ed8\u8ba4\u7684auto-commit\u72b6\u6001 | |||
| #\u9ed8\u8ba4\u4e3a\u7a7a\uff0c\u7531\u9a71\u52a8\u51b3\u5b9a | |||
| defaultAutoCommit=true | |||
| #\u8fde\u63a5\u6c60\u521b\u5efa\u7684\u8fde\u63a5\u7684\u9ed8\u8ba4\u7684read-only\u72b6\u6001\u3002 | |||
| #\u9ed8\u8ba4\u503c\u4e3a\u7a7a\uff0c\u7531\u9a71\u52a8\u51b3\u5b9a | |||
| defaultReadOnly=false | |||
| #\u8fde\u63a5\u6c60\u521b\u5efa\u7684\u8fde\u63a5\u7684\u9ed8\u8ba4\u7684TransactionIsolation\u72b6\u6001 | |||
| #\u53ef\u7528\u503c\u4e3a\u4e0b\u5217\u4e4b\u4e00\uff1aNONE,READ_UNCOMMITTED, READ_COMMITTED, REPEATABLE_READ, SERIALIZABLE | |||
| #\u9ed8\u8ba4\u503c\u4e3a\u7a7a\uff0c\u7531\u9a71\u52a8\u51b3\u5b9a | |||
| defaultTransactionIsolation=REPEATABLE_READ | |||
| #\u5f52\u8fd8\u8fde\u63a5\u65f6\u662f\u5426\u8bbe\u7f6e\u81ea\u52a8\u63d0\u4ea4\u4e3atrue | |||
| #\u9ed8\u8ba4true | |||
| autoCommitOnReturn=true | |||
| #\u5f52\u8fd8\u8fde\u63a5\u65f6\u662f\u5426\u8bbe\u7f6e\u56de\u6eda\u4e8b\u52a1 | |||
| #\u9ed8\u8ba4true | |||
| rollbackOnReturn=true | |||
| #\u8fde\u63a5\u6c60\u521b\u5efa\u7684\u8fde\u63a5\u7684\u9ed8\u8ba4\u7684\u6570\u636e\u5e93\u540d | |||
| #defaultCatalog=github_demo | |||
| #\u8fde\u63a5\u6c60\u521b\u5efa\u7684\u8fde\u63a5\u7684\u9ed8\u8ba4\u7684schema\u3002\u5982\u679c\u662fmysql\uff0c\u8fd9\u4e2a\u8bbe\u7f6e\u6ca1\u4ec0\u4e48\u7528\u3002 | |||
| #defaultSchema=github_demo | |||
| #-------------\u8fde\u63a5\u6cc4\u6f0f\u56de\u6536\u53c2\u6570-------------------------------- | |||
| #\u5f53\u672a\u4f7f\u7528\u7684\u65f6\u95f4\u8d85\u8fc7removeAbandonedTimeout\u65f6\uff0c\u662f\u5426\u89c6\u8be5\u8fde\u63a5\u4e3a\u6cc4\u9732\u8fde\u63a5\u5e76\u5220\u9664\uff08\u5f53getConnection()\u88ab\u8c03\u7528\u65f6\u68c0\u6d4b\uff09 | |||
| #\u9ed8\u8ba4\u4e3afalse | |||
| #\u6ce8\u610f\uff1a\u8fd9\u4e2a\u673a\u5236\u5728(getNumIdle() < 2) and (getNumActive() > (getMaxActive() - 3))\u65f6\u88ab\u89e6\u53d1 | |||
| removeAbandonedOnBorrow=false | |||
| #\u5f53\u672a\u4f7f\u7528\u7684\u65f6\u95f4\u8d85\u8fc7removeAbandonedTimeout\u65f6\uff0c\u662f\u5426\u89c6\u8be5\u8fde\u63a5\u4e3a\u6cc4\u9732\u8fde\u63a5\u5e76\u5220\u9664\uff08\u7a7a\u95f2evictor\u68c0\u6d4b\uff09 | |||
| #\u9ed8\u8ba4\u4e3afalse | |||
| #\u6ce8\u610f\uff1a\u5f53\u7a7a\u95f2\u8d44\u6e90\u56de\u6536\u5668\u5f00\u542f\u624d\u751f\u6548 | |||
| removeAbandonedOnMaintenance=false | |||
| #\u6cc4\u9732\u7684\u8fde\u63a5\u53ef\u4ee5\u88ab\u5220\u9664\u7684\u8d85\u65f6\u503c, \u5355\u4f4d\u79d2 | |||
| #\u9ed8\u8ba4\u4e3a300 | |||
| removeAbandonedTimeout=300 | |||
| #标记当Statement或连接被泄露时是否打印程序的stack traces日志。 | |||
| #被泄露的Statements和连接的日志添加在每个连接打开或者生成新的Statement,因为需要生成stack trace。 | |||
| #默认为false | |||
| logAbandoned=false | |||
| #如果开启"removeAbandoned",那么连接在被认为泄露时可能被池回收. | |||
| #这个机制在(getNumIdle() < 2) and (getNumActive() > getMaxActive() - 3)时被触发. | |||
| #举例当maxActive=20, 活动连接为18,空闲连接为1时可以触发"removeAbandoned". | |||
| #但是活动连接只有在没有被使用的时间超过"removeAbandonedTimeout"时才被删除,默认300秒.在resultset中游历不被计算为被使用. | |||
| #-------------其他-------------------------------- | |||
| #控制PoolGuard是否容许获取底层连接 | |||
| #默认为false | |||
| #\u6807\u8bb0\u5f53Statement\u6216\u8fde\u63a5\u88ab\u6cc4\u9732\u65f6\u662f\u5426\u6253\u5370\u7a0b\u5e8f\u7684stack traces\u65e5\u5fd7\u3002 | |||
| #\u9ed8\u8ba4\u4e3afalse | |||
| logAbandoned=true | |||
| #\u8fd9\u4e2a\u4e0d\u662f\u5f88\u61c2 | |||
| #\u9ed8\u8ba4\u4e3afalse | |||
| abandonedUsageTracking=false | |||
| #-------------\u5176\u4ed6-------------------------------- | |||
| #\u662f\u5426\u4f7f\u7528\u5feb\u901f\u5931\u8d25\u673a\u5236 | |||
| #\u9ed8\u8ba4\u4e3a\u7a7a\uff0c\u7531\u9a71\u52a8\u51b3\u5b9a | |||
| fastFailValidation=false | |||
| #\u5f53\u4f7f\u7528\u5feb\u901f\u5931\u8d25\u673a\u5236\u65f6\uff0c\u8bbe\u7f6e\u89e6\u53d1\u7684\u5f02\u5e38\u7801 | |||
| #\u591a\u4e2acode\u7528","\u9694\u5f00 | |||
| #disconnectionSqlCodes | |||
| #borrow\u8fde\u63a5\u7684\u987a\u5e8f | |||
| #\u9ed8\u8ba4true | |||
| lifo=true | |||
| #\u6bcf\u4e2a\u8fde\u63a5\u521b\u5efa\u65f6\u6267\u884c\u7684\u8bed\u53e5 | |||
| #connectionInitSqls= | |||
| #\u8fde\u63a5\u53c2\u6570\uff1a\u4f8b\u5982username\u3001password\u3001characterEncoding\u7b49\u90fd\u53ef\u4ee5\u5728\u8fd9\u91cc\u8bbe\u7f6e | |||
| #\u591a\u4e2a\u53c2\u6570\u7528";"\u9694\u5f00 | |||
| #connectionProperties= | |||
| #\u6307\u5b9a\u6570\u636e\u6e90\u7684jmx\u540d | |||
| #jmxName= | |||
| #\u67e5\u8be2\u8d85\u65f6\u65f6\u95f4 | |||
| #\u9ed8\u8ba4\u4e3a\u7a7a\uff0c\u5373\u6839\u636e\u9a71\u52a8\u8bbe\u7f6e | |||
| #defaultQueryTimeout= | |||
| #\u63a7\u5236PoolGuard\u662f\u5426\u5bb9\u8bb8\u83b7\u53d6\u5e95\u5c42\u8fde\u63a5 | |||
| #\u9ed8\u8ba4\u4e3afalse | |||
| accessToUnderlyingConnectionAllowed=false | |||
| #如果容许则可以使用下面的方式来获取底层物理连接: | |||
| #\u5982\u679c\u5bb9\u8bb8\u5219\u53ef\u4ee5\u4f7f\u7528\u4e0b\u9762\u7684\u65b9\u5f0f\u6765\u83b7\u53d6\u5e95\u5c42\u7269\u7406\u8fde\u63a5: | |||
| # Connection conn = ds.getConnection(); | |||
| # Connection dconn = ((DelegatingConnection) conn).getInnermostDelegate(); | |||
| # ... | |||
| @@ -1,12 +1,10 @@ | |||
| #OFF,systemOut,logFile,logDailyFile,logRollingFile,logMail,logDB,ALL | |||
| #①配置根Logger | |||
| log4j.rootLogger=debug,systemOut | |||
| #OFF,systemOut,logFile,logDailyFile,logRollingFile,logMail,logDB,ALL | |||
| #②配置其他Logger | |||
| #log4j.logger.myLogger=debug,systemOut | |||
| #log4j.additivity.mobileLogger=false | |||
| #\u2460\u914d\u7f6e\u6839Logger | |||
| log4j.rootLogger=info,systemOut | |||
| log4j.logger.cn.zzs.dbcp=debug,systemOut | |||
| log4j.additivity.cn.zzs.dbcp=false | |||
| #输出到控制台 | |||
| #\u8f93\u51fa\u5230\u63a7\u5236\u53f0 | |||
| log4j.appender.systemOut= org.apache.log4j.ConsoleAppender | |||
| log4j.appender.systemOut.layout= org.apache.log4j.PatternLayout | |||
| log4j.appender.systemOut.layout.ConversionPattern=[%p][Thread:%t]: %m%n | |||
| @@ -14,7 +12,7 @@ log4j.appender.systemOut.Threshold= debug | |||
| log4j.appender.systemOut.ImmediateFlush= TRUE | |||
| log4j.appender.systemOut.Target= System.out | |||
| #输出到文件 | |||
| #\u8f93\u51fa\u5230\u6587\u4ef6 | |||
| log4j.appender.logFile= org.apache.log4j.FileAppender | |||
| log4j.appender.logFile.layout= org.apache.log4j.PatternLayout | |||
| log4j.appender.logFile.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss a} [Thread:%t][Class:%c Method: %M]%n%p: %m%n | |||
| @@ -24,7 +22,7 @@ log4j.appender.logFile.Append= TRUE | |||
| log4j.appender.logFile.File= logs/file_log.log | |||
| log4j.appender.logFile.Encoding= utf-8 | |||
| #按DatePattern输出到文件 | |||
| #\u6309DatePattern\u8f93\u51fa\u5230\u6587\u4ef6 | |||
| log4j.appender.logDailyFile= org.apache.log4j.DailyRollingFileAppender | |||
| log4j.appender.logDailyFile.layout= org.apache.log4j.PatternLayout | |||
| log4j.appender.logDailyFile.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss a} [Thread:%t][Class:%c Method: %M]%n%p: %m%n | |||
| @@ -36,7 +34,7 @@ log4j.appender.logDailyFile.File= logs/daily_log | |||
| log4j.appender.logDailyFile.DatePattern= '_'yyyy-MM-dd-HH-mm'.log' | |||
| log4j.appender.logDailyFile.Encoding= utf-8 | |||
| #设定文件大小输出到文件 | |||
| #\u8bbe\u5b9a\u6587\u4ef6\u5927\u5c0f\u8f93\u51fa\u5230\u6587\u4ef6 | |||
| log4j.appender.logRollingFile= org.apache.log4j.RollingFileAppender | |||
| log4j.appender.logRollingFile.layout= org.apache.log4j.PatternLayout | |||
| log4j.appender.logRollingFile.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss a} [Thread:%t][Class:%c Method: %M]%n%p: %m%n | |||
| @@ -48,7 +46,7 @@ log4j.appender.logRollingFile.MaxFileSize= 1mb | |||
| log4j.appender.logRollingFile.MaxBackupIndex= 10 | |||
| log4j.appender.logRollingFile.Encoding= utf-8 | |||
| #用Email发送日志 | |||
| #\u7528Email\u53d1\u9001\u65e5\u5fd7 | |||
| log4j.appender.logMail= org.apache.log4j.net.SMTPAppender | |||
| log4j.appender.logMail.layout= org.apache.log4j.HTMLLayout | |||
| log4j.appender.logMail.layout.LocationInfo= TRUE | |||
| @@ -66,7 +64,7 @@ log4j.appender.logMail.Subject= Log4j Log Messages | |||
| #log4j.appender.logMail.BufferSize= 1024 | |||
| #log4j.appender.logMail.SMTPAuth= TRUE | |||
| #将日志登录到MySQL数据库 | |||
| #\u5c06\u65e5\u5fd7\u767b\u5f55\u5230MySQL\u6570\u636e\u5e93 | |||
| log4j.appender.logDB= org.apache.log4j.jdbc.JDBCAppender | |||
| log4j.appender.logDB.layout= org.apache.log4j.PatternLayout | |||
| log4j.appender.logDB.Driver= com.mysql.cj.jdbc.Driver | |||
| @@ -75,109 +73,109 @@ log4j.appender.logDB.User= root | |||
| log4j.appender.logDB.Password= root | |||
| log4j.appender.logDB.Sql= INSERT INTO T_log4j(project_name,create_date,level,category,file_name,thread_name,line,all_category,message)values('Struts2','%d{yyyy-MM-ddHH:mm:ss}','%p','%c','%F','%t','%L','%l','%m') | |||
| ################################################################################ | |||
| #①配置根Logger,其语法为: | |||
| #\u2460\u914d\u7f6e\u6839Logger\uff0c\u5176\u8bed\u6cd5\u4e3a\uff1a | |||
| # | |||
| #log4j.rootLogger =[level],appenderName,appenderName2,... | |||
| #level是日志记录的优先级,分为OFF,TRACE,DEBUG,INFO,WARN,ERROR,FATAL,ALL | |||
| ##Log4j建议只使用四个级别,优先级从低到高分别是DEBUG,INFO,WARN,ERROR | |||
| #通过在这里定义的级别,您可以控制到应用程序中相应级别的日志信息的开关 | |||
| #比如在这里定义了INFO级别,则应用程序中所有DEBUG级别的日志信息将不被打印出来 | |||
| #appenderName就是指定日志信息输出到哪个地方。可同时指定多个输出目的 | |||
| #level\u662f\u65e5\u5fd7\u8bb0\u5f55\u7684\u4f18\u5148\u7ea7\uff0c\u5206\u4e3aOFF,TRACE,DEBUG,INFO,WARN,ERROR,FATAL,ALL | |||
| ##Log4j\u5efa\u8bae\u53ea\u4f7f\u7528\u56db\u4e2a\u7ea7\u522b\uff0c\u4f18\u5148\u7ea7\u4ece\u4f4e\u5230\u9ad8\u5206\u522b\u662fDEBUG,INFO,WARN,ERROR | |||
| #\u901a\u8fc7\u5728\u8fd9\u91cc\u5b9a\u4e49\u7684\u7ea7\u522b\uff0c\u60a8\u53ef\u4ee5\u63a7\u5236\u5230\u5e94\u7528\u7a0b\u5e8f\u4e2d\u76f8\u5e94\u7ea7\u522b\u7684\u65e5\u5fd7\u4fe1\u606f\u7684\u5f00\u5173 | |||
| #\u6bd4\u5982\u5728\u8fd9\u91cc\u5b9a\u4e49\u4e86INFO\u7ea7\u522b\uff0c\u5219\u5e94\u7528\u7a0b\u5e8f\u4e2d\u6240\u6709DEBUG\u7ea7\u522b\u7684\u65e5\u5fd7\u4fe1\u606f\u5c06\u4e0d\u88ab\u6253\u5370\u51fa\u6765 | |||
| #appenderName\u5c31\u662f\u6307\u5b9a\u65e5\u5fd7\u4fe1\u606f\u8f93\u51fa\u5230\u54ea\u4e2a\u5730\u65b9\u3002\u53ef\u540c\u65f6\u6307\u5b9a\u591a\u4e2a\u8f93\u51fa\u76ee\u7684 | |||
| ################################################################################ | |||
| ################################################################################ | |||
| #②配置日志信息输出目的地Appender,其语法为: | |||
| #\u2461\u914d\u7f6e\u65e5\u5fd7\u4fe1\u606f\u8f93\u51fa\u76ee\u7684\u5730Appender\uff0c\u5176\u8bed\u6cd5\u4e3a\uff1a | |||
| # | |||
| #log4j.appender.appenderName =fully.qualified.name.of.appender.class | |||
| #log4j.appender.appenderName.optionN =valueN | |||
| # | |||
| #Log4j提供的appender有以下几种: | |||
| #1)org.apache.log4j.ConsoleAppender(输出到控制台) | |||
| #2)org.apache.log4j.FileAppender(输出到文件) | |||
| #3)org.apache.log4j.DailyRollingFileAppender(每天产生一个日志文件) | |||
| #4)org.apache.log4j.RollingFileAppender(文件大小到达指定尺寸的时候产生一个新的文件) | |||
| #5)org.apache.log4j.WriterAppender(将日志信息以流格式发送到任意指定的地方) | |||
| #Log4j\u63d0\u4f9b\u7684appender\u6709\u4ee5\u4e0b\u51e0\u79cd\uff1a | |||
| #1)org.apache.log4j.ConsoleAppender(\u8f93\u51fa\u5230\u63a7\u5236\u53f0) | |||
| #2)org.apache.log4j.FileAppender(\u8f93\u51fa\u5230\u6587\u4ef6) | |||
| #3)org.apache.log4j.DailyRollingFileAppender(\u6bcf\u5929\u4ea7\u751f\u4e00\u4e2a\u65e5\u5fd7\u6587\u4ef6) | |||
| #4)org.apache.log4j.RollingFileAppender(\u6587\u4ef6\u5927\u5c0f\u5230\u8fbe\u6307\u5b9a\u5c3a\u5bf8\u7684\u65f6\u5019\u4ea7\u751f\u4e00\u4e2a\u65b0\u7684\u6587\u4ef6) | |||
| #5)org.apache.log4j.WriterAppender(\u5c06\u65e5\u5fd7\u4fe1\u606f\u4ee5\u6d41\u683c\u5f0f\u53d1\u9001\u5230\u4efb\u610f\u6307\u5b9a\u7684\u5730\u65b9) | |||
| # | |||
| #1)ConsoleAppender选项属性 | |||
| # -Threshold = DEBUG:指定日志消息的输出最低层次 | |||
| # -ImmediateFlush = TRUE:默认值是true,所有的消息都会被立即输出 | |||
| # -Target = System.err:默认值System.out,输出到控制台(err为红色,out为黑色) | |||
| #1)ConsoleAppender\u9009\u9879\u5c5e\u6027 | |||
| # -Threshold = DEBUG:\u6307\u5b9a\u65e5\u5fd7\u6d88\u606f\u7684\u8f93\u51fa\u6700\u4f4e\u5c42\u6b21 | |||
| # -ImmediateFlush = TRUE:\u9ed8\u8ba4\u503c\u662ftrue,\u6240\u6709\u7684\u6d88\u606f\u90fd\u4f1a\u88ab\u7acb\u5373\u8f93\u51fa | |||
| # -Target = System.err:\u9ed8\u8ba4\u503cSystem.out,\u8f93\u51fa\u5230\u63a7\u5236\u53f0(err\u4e3a\u7ea2\u8272,out\u4e3a\u9ed1\u8272) | |||
| # | |||
| #2)FileAppender选项属性 | |||
| # -Threshold = INFO:指定日志消息的输出最低层次 | |||
| # -ImmediateFlush = TRUE:默认值是true,所有的消息都会被立即输出 | |||
| # -File = C:\log4j.log:指定消息输出到C:\log4j.log文件 | |||
| # -Append = FALSE:默认值true,将消息追加到指定文件中,false指将消息覆盖指定的文件内容 | |||
| # -Encoding = UTF-8:可以指定文件编码格式 | |||
| #2)FileAppender\u9009\u9879\u5c5e\u6027 | |||
| # -Threshold = INFO:\u6307\u5b9a\u65e5\u5fd7\u6d88\u606f\u7684\u8f93\u51fa\u6700\u4f4e\u5c42\u6b21 | |||
| # -ImmediateFlush = TRUE:\u9ed8\u8ba4\u503c\u662ftrue,\u6240\u6709\u7684\u6d88\u606f\u90fd\u4f1a\u88ab\u7acb\u5373\u8f93\u51fa | |||
| # -File = C:\log4j.log:\u6307\u5b9a\u6d88\u606f\u8f93\u51fa\u5230C:\log4j.log\u6587\u4ef6 | |||
| # -Append = FALSE:\u9ed8\u8ba4\u503ctrue,\u5c06\u6d88\u606f\u8ffd\u52a0\u5230\u6307\u5b9a\u6587\u4ef6\u4e2d\uff0cfalse\u6307\u5c06\u6d88\u606f\u8986\u76d6\u6307\u5b9a\u7684\u6587\u4ef6\u5185\u5bb9 | |||
| # -Encoding = UTF-8:\u53ef\u4ee5\u6307\u5b9a\u6587\u4ef6\u7f16\u7801\u683c\u5f0f | |||
| # | |||
| #3)DailyRollingFileAppender选项属性 | |||
| #-Threshold = WARN:指定日志消息的输出最低层次 | |||
| #-ImmediateFlush = TRUE:默认值是true,所有的消息都会被立即输出 | |||
| # -File =C:\log4j.log:指定消息输出到C:\log4j.log文件 | |||
| # -Append= FALSE:默认值true,将消息追加到指定文件中,false指将消息覆盖指定的文件内容 | |||
| #-DatePattern='.'yyyy-ww:每周滚动一次文件,即每周产生一个新的文件。还可以按用以下参数: | |||
| # '.'yyyy-MM:每月 | |||
| # '.'yyyy-ww:每周 | |||
| # '.'yyyy-MM-dd:每天 | |||
| # '.'yyyy-MM-dd-a:每天两次 | |||
| # '.'yyyy-MM-dd-HH:每小时 | |||
| # '.'yyyy-MM-dd-HH-mm:每分钟 | |||
| #-Encoding = UTF-8:可以指定文件编码格式 | |||
| #3)DailyRollingFileAppender\u9009\u9879\u5c5e\u6027 | |||
| #-Threshold = WARN:\u6307\u5b9a\u65e5\u5fd7\u6d88\u606f\u7684\u8f93\u51fa\u6700\u4f4e\u5c42\u6b21 | |||
| #-ImmediateFlush = TRUE:\u9ed8\u8ba4\u503c\u662ftrue,\u6240\u6709\u7684\u6d88\u606f\u90fd\u4f1a\u88ab\u7acb\u5373\u8f93\u51fa | |||
| # -File =C:\log4j.log:\u6307\u5b9a\u6d88\u606f\u8f93\u51fa\u5230C:\log4j.log\u6587\u4ef6 | |||
| # -Append= FALSE:\u9ed8\u8ba4\u503ctrue,\u5c06\u6d88\u606f\u8ffd\u52a0\u5230\u6307\u5b9a\u6587\u4ef6\u4e2d\uff0cfalse\u6307\u5c06\u6d88\u606f\u8986\u76d6\u6307\u5b9a\u7684\u6587\u4ef6\u5185\u5bb9 | |||
| #-DatePattern='.'yyyy-ww:\u6bcf\u5468\u6eda\u52a8\u4e00\u6b21\u6587\u4ef6,\u5373\u6bcf\u5468\u4ea7\u751f\u4e00\u4e2a\u65b0\u7684\u6587\u4ef6\u3002\u8fd8\u53ef\u4ee5\u6309\u7528\u4ee5\u4e0b\u53c2\u6570: | |||
| # '.'yyyy-MM:\u6bcf\u6708 | |||
| # '.'yyyy-ww:\u6bcf\u5468 | |||
| # '.'yyyy-MM-dd:\u6bcf\u5929 | |||
| # '.'yyyy-MM-dd-a:\u6bcf\u5929\u4e24\u6b21 | |||
| # '.'yyyy-MM-dd-HH:\u6bcf\u5c0f\u65f6 | |||
| # '.'yyyy-MM-dd-HH-mm:\u6bcf\u5206\u949f | |||
| #-Encoding = UTF-8:\u53ef\u4ee5\u6307\u5b9a\u6587\u4ef6\u7f16\u7801\u683c\u5f0f | |||
| # | |||
| #4)RollingFileAppender选项属性 | |||
| #-Threshold = ERROR:指定日志消息的输出最低层次 | |||
| #-ImmediateFlush = TRUE:默认值是true,所有的消息都会被立即输出 | |||
| # -File =C:/log4j.log:指定消息输出到C:/log4j.log文件 | |||
| # -Append= FALSE:默认值true,将消息追加到指定文件中,false指将消息覆盖指定的文件内容 | |||
| #-MaxFileSize = 100KB:后缀可以是KB,MB,GB.在日志文件到达该大小时,将会自动滚动.如:log4j.log.1 | |||
| #-MaxBackupIndex = 2:指定可以产生的滚动文件的最大数 | |||
| #-Encoding = UTF-8:可以指定文件编码格式 | |||
| #4)RollingFileAppender\u9009\u9879\u5c5e\u6027 | |||
| #-Threshold = ERROR:\u6307\u5b9a\u65e5\u5fd7\u6d88\u606f\u7684\u8f93\u51fa\u6700\u4f4e\u5c42\u6b21 | |||
| #-ImmediateFlush = TRUE:\u9ed8\u8ba4\u503c\u662ftrue,\u6240\u6709\u7684\u6d88\u606f\u90fd\u4f1a\u88ab\u7acb\u5373\u8f93\u51fa | |||
| # -File =C:/log4j.log:\u6307\u5b9a\u6d88\u606f\u8f93\u51fa\u5230C:/log4j.log\u6587\u4ef6 | |||
| # -Append= FALSE:\u9ed8\u8ba4\u503ctrue,\u5c06\u6d88\u606f\u8ffd\u52a0\u5230\u6307\u5b9a\u6587\u4ef6\u4e2d\uff0cfalse\u6307\u5c06\u6d88\u606f\u8986\u76d6\u6307\u5b9a\u7684\u6587\u4ef6\u5185\u5bb9 | |||
| #-MaxFileSize = 100KB:\u540e\u7f00\u53ef\u4ee5\u662fKB,MB,GB.\u5728\u65e5\u5fd7\u6587\u4ef6\u5230\u8fbe\u8be5\u5927\u5c0f\u65f6,\u5c06\u4f1a\u81ea\u52a8\u6eda\u52a8.\u5982:log4j.log.1 | |||
| #-MaxBackupIndex = 2:\u6307\u5b9a\u53ef\u4ee5\u4ea7\u751f\u7684\u6eda\u52a8\u6587\u4ef6\u7684\u6700\u5927\u6570 | |||
| #-Encoding = UTF-8:\u53ef\u4ee5\u6307\u5b9a\u6587\u4ef6\u7f16\u7801\u683c\u5f0f | |||
| ################################################################################ | |||
| ################################################################################ | |||
| #③配置日志信息的格式(布局),其语法为: | |||
| #\u2462\u914d\u7f6e\u65e5\u5fd7\u4fe1\u606f\u7684\u683c\u5f0f(\u5e03\u5c40)\uff0c\u5176\u8bed\u6cd5\u4e3a\uff1a | |||
| # | |||
| #log4j.appender.appenderName.layout=fully.qualified.name.of.layout.class | |||
| #log4j.appender.appenderName.layout.optionN= valueN | |||
| # | |||
| #Log4j提供的layout有以下几种: | |||
| #5)org.apache.log4j.HTMLLayout(以HTML表格形式布局) | |||
| #6)org.apache.log4j.PatternLayout(可以灵活地指定布局模式) | |||
| #7)org.apache.log4j.SimpleLayout(包含日志信息的级别和信息字符串) | |||
| #8)org.apache.log4j.TTCCLayout(包含日志产生的时间、线程、类别等等信息) | |||
| #9)org.apache.log4j.xml.XMLLayout(以XML形式布局) | |||
| #Log4j\u63d0\u4f9b\u7684layout\u6709\u4ee5\u4e0b\u51e0\u79cd\uff1a | |||
| #5)org.apache.log4j.HTMLLayout(\u4ee5HTML\u8868\u683c\u5f62\u5f0f\u5e03\u5c40) | |||
| #6)org.apache.log4j.PatternLayout(\u53ef\u4ee5\u7075\u6d3b\u5730\u6307\u5b9a\u5e03\u5c40\u6a21\u5f0f) | |||
| #7)org.apache.log4j.SimpleLayout(\u5305\u542b\u65e5\u5fd7\u4fe1\u606f\u7684\u7ea7\u522b\u548c\u4fe1\u606f\u5b57\u7b26\u4e32) | |||
| #8)org.apache.log4j.TTCCLayout(\u5305\u542b\u65e5\u5fd7\u4ea7\u751f\u7684\u65f6\u95f4\u3001\u7ebf\u7a0b\u3001\u7c7b\u522b\u7b49\u7b49\u4fe1\u606f) | |||
| #9)org.apache.log4j.xml.XMLLayout(\u4ee5XML\u5f62\u5f0f\u5e03\u5c40) | |||
| # | |||
| #5)HTMLLayout选项属性 | |||
| #-LocationInfo = TRUE:默认值false,输出java文件名称和行号 | |||
| #-Title=Struts Log Message:默认值 Log4JLog Messages | |||
| #5)HTMLLayout\u9009\u9879\u5c5e\u6027 | |||
| #-LocationInfo = TRUE:\u9ed8\u8ba4\u503cfalse,\u8f93\u51fajava\u6587\u4ef6\u540d\u79f0\u548c\u884c\u53f7 | |||
| #-Title=Struts Log Message:\u9ed8\u8ba4\u503c Log4JLog Messages | |||
| # | |||
| #6)PatternLayout选项属性 | |||
| #-ConversionPattern = %m%n:格式化指定的消息(参数意思下面有) | |||
| #6)PatternLayout\u9009\u9879\u5c5e\u6027 | |||
| #-ConversionPattern = %m%n:\u683c\u5f0f\u5316\u6307\u5b9a\u7684\u6d88\u606f(\u53c2\u6570\u610f\u601d\u4e0b\u9762\u6709) | |||
| # | |||
| #9)XMLLayout选项属性 | |||
| #-LocationInfo = TRUE:默认值false,输出java文件名称和行号 | |||
| #9)XMLLayout\u9009\u9879\u5c5e\u6027 | |||
| #-LocationInfo = TRUE:\u9ed8\u8ba4\u503cfalse,\u8f93\u51fajava\u6587\u4ef6\u540d\u79f0\u548c\u884c\u53f7 | |||
| # | |||
| #Log4J采用类似C语言中的printf函数的打印格式格式化日志信息,打印参数如下: | |||
| #%m 输出代码中指定的消息 | |||
| #%p 输出优先级,即DEBUG,INFO,WARN,ERROR,FATAL | |||
| #%r 输出自应用启动到输出该log信息耗费的毫秒数 | |||
| #%c 输出所属的类目,通常就是所在类的全名 | |||
| #%t 输出产生该日志事件的线程名 | |||
| #%n 输出一个回车换行符,Windows平台为“\r\n”,Unix平台为“\n” | |||
| #%d 输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式 | |||
| # 如:%d{yyyy年MM月dd日HH:mm:ss,SSS},输出类似:2012年01月05日 22:10:28,921 | |||
| #%l 输出日志事件的发生位置,包括类目名、发生的线程,以及在代码中的行数 | |||
| # 如:Testlog.main(TestLog.java:10) | |||
| #%F 输出日志消息产生时所在的文件名称 | |||
| #%L 输出代码中的行号 | |||
| #%x 输出和当前线程相关联的NDC(嵌套诊断环境),像javaservlets多客户多线程的应用中 | |||
| #%% 输出一个"%"字符 | |||
| #Log4J\u91c7\u7528\u7c7b\u4f3cC\u8bed\u8a00\u4e2d\u7684printf\u51fd\u6570\u7684\u6253\u5370\u683c\u5f0f\u683c\u5f0f\u5316\u65e5\u5fd7\u4fe1\u606f\uff0c\u6253\u5370\u53c2\u6570\u5982\u4e0b\uff1a | |||
| #%m \u8f93\u51fa\u4ee3\u7801\u4e2d\u6307\u5b9a\u7684\u6d88\u606f | |||
| #%p \u8f93\u51fa\u4f18\u5148\u7ea7\uff0c\u5373DEBUG,INFO,WARN,ERROR,FATAL | |||
| #%r \u8f93\u51fa\u81ea\u5e94\u7528\u542f\u52a8\u5230\u8f93\u51fa\u8be5log\u4fe1\u606f\u8017\u8d39\u7684\u6beb\u79d2\u6570 | |||
| #%c \u8f93\u51fa\u6240\u5c5e\u7684\u7c7b\u76ee,\u901a\u5e38\u5c31\u662f\u6240\u5728\u7c7b\u7684\u5168\u540d | |||
| #%t \u8f93\u51fa\u4ea7\u751f\u8be5\u65e5\u5fd7\u4e8b\u4ef6\u7684\u7ebf\u7a0b\u540d | |||
| #%n \u8f93\u51fa\u4e00\u4e2a\u56de\u8f66\u6362\u884c\u7b26\uff0cWindows\u5e73\u53f0\u4e3a\u201c\r\n\u201d\uff0cUnix\u5e73\u53f0\u4e3a\u201c\n\u201d | |||
| #%d \u8f93\u51fa\u65e5\u5fd7\u65f6\u95f4\u70b9\u7684\u65e5\u671f\u6216\u65f6\u95f4\uff0c\u9ed8\u8ba4\u683c\u5f0f\u4e3aISO8601\uff0c\u4e5f\u53ef\u4ee5\u5728\u5176\u540e\u6307\u5b9a\u683c\u5f0f | |||
| # \u5982\uff1a%d{yyyy\u5e74MM\u6708dd\u65e5HH:mm:ss,SSS}\uff0c\u8f93\u51fa\u7c7b\u4f3c\uff1a2012\u5e7401\u670805\u65e5 22:10:28,921 | |||
| #%l \u8f93\u51fa\u65e5\u5fd7\u4e8b\u4ef6\u7684\u53d1\u751f\u4f4d\u7f6e\uff0c\u5305\u62ec\u7c7b\u76ee\u540d\u3001\u53d1\u751f\u7684\u7ebf\u7a0b\uff0c\u4ee5\u53ca\u5728\u4ee3\u7801\u4e2d\u7684\u884c\u6570 | |||
| # \u5982\uff1aTestlog.main(TestLog.java:10) | |||
| #%F \u8f93\u51fa\u65e5\u5fd7\u6d88\u606f\u4ea7\u751f\u65f6\u6240\u5728\u7684\u6587\u4ef6\u540d\u79f0 | |||
| #%L \u8f93\u51fa\u4ee3\u7801\u4e2d\u7684\u884c\u53f7 | |||
| #%x \u8f93\u51fa\u548c\u5f53\u524d\u7ebf\u7a0b\u76f8\u5173\u8054\u7684NDC(\u5d4c\u5957\u8bca\u65ad\u73af\u5883),\u50cfjavaservlets\u591a\u5ba2\u6237\u591a\u7ebf\u7a0b\u7684\u5e94\u7528\u4e2d | |||
| #%% \u8f93\u51fa\u4e00\u4e2a"%"\u5b57\u7b26 | |||
| # | |||
| # 可以在%与模式字符之间加上修饰符来控制其最小宽度、最大宽度、和文本的对齐方式。如: | |||
| # %5c: 输出category名称,最小宽度是5,category<5,默认的情况下右对齐 | |||
| # %-5c:输出category名称,最小宽度是5,category<5,"-"号指定左对齐,会有空格 | |||
| # %.5c:输出category名称,最大宽度是5,category>5,就会将左边多出的字符截掉,<5不会有空格 | |||
| # %20.30c:category名称<20补空格,并且右对齐,>30字符,就从左边交远销出的字符截掉 | |||
| # \u53ef\u4ee5\u5728%\u4e0e\u6a21\u5f0f\u5b57\u7b26\u4e4b\u95f4\u52a0\u4e0a\u4fee\u9970\u7b26\u6765\u63a7\u5236\u5176\u6700\u5c0f\u5bbd\u5ea6\u3001\u6700\u5927\u5bbd\u5ea6\u3001\u548c\u6587\u672c\u7684\u5bf9\u9f50\u65b9\u5f0f\u3002\u5982\uff1a | |||
| # %5c: \u8f93\u51facategory\u540d\u79f0\uff0c\u6700\u5c0f\u5bbd\u5ea6\u662f5\uff0ccategory<5\uff0c\u9ed8\u8ba4\u7684\u60c5\u51b5\u4e0b\u53f3\u5bf9\u9f50 | |||
| # %-5c:\u8f93\u51facategory\u540d\u79f0\uff0c\u6700\u5c0f\u5bbd\u5ea6\u662f5\uff0ccategory<5\uff0c"-"\u53f7\u6307\u5b9a\u5de6\u5bf9\u9f50,\u4f1a\u6709\u7a7a\u683c | |||
| # %.5c:\u8f93\u51facategory\u540d\u79f0\uff0c\u6700\u5927\u5bbd\u5ea6\u662f5\uff0ccategory>5\uff0c\u5c31\u4f1a\u5c06\u5de6\u8fb9\u591a\u51fa\u7684\u5b57\u7b26\u622a\u6389\uff0c<5\u4e0d\u4f1a\u6709\u7a7a\u683c | |||
| # %20.30c:category\u540d\u79f0<20\u8865\u7a7a\u683c\uff0c\u5e76\u4e14\u53f3\u5bf9\u9f50\uff0c>30\u5b57\u7b26\uff0c\u5c31\u4ece\u5de6\u8fb9\u4ea4\u8fdc\u9500\u51fa\u7684\u5b57\u7b26\u622a\u6389 | |||
| ################################################################################ | |||
| ################################################################################ | |||
| #④指定特定包的输出特定的级别 | |||
| #\u2463\u6307\u5b9a\u7279\u5b9a\u5305\u7684\u8f93\u51fa\u7279\u5b9a\u7684\u7ea7\u522b | |||
| #log4j.logger.org.springframework=DEBUG | |||
| ################################################################################ | |||
| @@ -0,0 +1,45 @@ | |||
| CREATE DATABASE `github_demo` DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci; | |||
| USE `github_demo`; | |||
| DROP TABLE IF EXISTS `demo_user`; | |||
| CREATE TABLE `demo_user` ( | |||
| `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '用户id', | |||
| `name` varchar(16) COLLATE utf8_unicode_ci NOT NULL COMMENT '用户名', | |||
| `age` int(3) unsigned DEFAULT NULL COMMENT '用户年龄', | |||
| `gmt_create` datetime DEFAULT NULL COMMENT '记录创建时间', | |||
| `gmt_modified` datetime DEFAULT NULL COMMENT '记录最近修改时间', | |||
| `deleted` bit(1) DEFAULT b'0' COMMENT '是否删除', | |||
| PRIMARY KEY (`id`), | |||
| UNIQUE KEY `uk_name` (`name`), | |||
| KEY `index_age` (`age`) | |||
| ) ENGINE=InnoDB AUTO_INCREMENT=17 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; | |||
| insert into `demo_user`( | |||
| `id`, `name`, `age`, `gmt_create`, | |||
| `gmt_modified`, `deleted` | |||
| ) | |||
| values | |||
| ( | |||
| 1, 'zzs001', 18, '2019-10-01 11:13:42', | |||
| '2019-11-01 11:13:50', '\0' | |||
| ), | |||
| ( | |||
| 2, 'zzs002', 18, '2019-11-23 00:00:00', | |||
| '2019-11-23 00:00:00', '\0' | |||
| ), | |||
| ( | |||
| 3, 'zzs003', 25, '2019-11-01 11:14:36', | |||
| '2019-11-03 00:00:00', '\0' | |||
| ), | |||
| ( | |||
| 4, 'zzf001', 26, '2019-11-04 11:14:51', | |||
| '2019-11-03 00:00:00', '\0' | |||
| ), | |||
| ( | |||
| 5, 'zzf002', 17, '2019-11-03 00:00:00', | |||
| '2019-11-03 00:00:00', '\0' | |||
| ); | |||
| @@ -0,0 +1,152 @@ | |||
| package cn.zzs.dbcp; | |||
| import java.sql.Connection; | |||
| import java.sql.Date; | |||
| import java.sql.PreparedStatement; | |||
| import java.sql.ResultSet; | |||
| import java.sql.SQLException; | |||
| import org.apache.commons.logging.Log; | |||
| import org.apache.commons.logging.LogFactory; | |||
| import org.junit.Test; | |||
| /** | |||
| * @ClassName: BasicDataSourceTest | |||
| * @Description: 测试使用BasicDataSource获取连接并操作数据库 | |||
| * @author: zzs | |||
| * @date: 2019年8月31日 下午9:39:54 | |||
| */ | |||
| public class BasicDataSourceTest { | |||
| private static final Log log = LogFactory.getLog(BasicDataSourceTest.class); | |||
| /** | |||
| * 测试添加用户 | |||
| */ | |||
| @Test | |||
| public void save() { | |||
| // 创建sql | |||
| String sql = "insert into demo_user values(null,?,?,?,?,?)"; | |||
| Connection connection = null; | |||
| PreparedStatement statement = null; | |||
| try { | |||
| // 获得连接 | |||
| connection = BasicDataSourceUtil.getConnection(); | |||
| // 开启事务设置非自动提交 | |||
| BasicDataSourceUtil.startTrasaction(); | |||
| // 获得Statement对象 | |||
| statement = connection.prepareStatement(sql); | |||
| // 设置参数 | |||
| statement.setString(1, "zzf003"); | |||
| statement.setInt(2, 18); | |||
| statement.setDate(3, new Date(System.currentTimeMillis())); | |||
| statement.setDate(4, new Date(System.currentTimeMillis())); | |||
| statement.setBoolean(5, false); | |||
| // 执行 | |||
| statement.executeUpdate(); | |||
| // 提交事务 | |||
| BasicDataSourceUtil.commit(); | |||
| } catch(Exception e) { | |||
| BasicDataSourceUtil.rollback(); | |||
| log.error("保存用户失败", e); | |||
| } finally { | |||
| // 释放资源 | |||
| BasicDataSourceUtil.release(connection, statement, null); | |||
| } | |||
| } | |||
| /** | |||
| * 测试更新用户 | |||
| */ | |||
| @Test | |||
| public void update() { | |||
| // 创建sql | |||
| String sql = "update demo_user set age = ?,gmt_modified = ? where name = ?"; | |||
| Connection connection = null; | |||
| PreparedStatement statement = null; | |||
| try { | |||
| // 获得连接 | |||
| connection = BasicDataSourceUtil.getConnection(); | |||
| // 开启事务 | |||
| BasicDataSourceUtil.startTrasaction(); | |||
| // 获得Statement对象 | |||
| statement = connection.prepareStatement(sql); | |||
| // 设置参数 | |||
| statement.setInt(1, 19); | |||
| statement.setDate(2, new Date(System.currentTimeMillis())); | |||
| statement.setString(3, "zzf003"); | |||
| // 执行 | |||
| statement.executeUpdate(); | |||
| // 提交事务 | |||
| BasicDataSourceUtil.commit(); | |||
| } catch(Exception e) { | |||
| log.error("异常导致操作回滚", e); | |||
| BasicDataSourceUtil.rollback(); | |||
| } finally { | |||
| // 释放资源 | |||
| BasicDataSourceUtil.release(connection, statement, null); | |||
| } | |||
| } | |||
| /** | |||
| * 测试查找用户 | |||
| */ | |||
| @Test | |||
| public void findAll() { | |||
| // 创建sql | |||
| String sql = "select * from demo_user where deleted = false"; | |||
| Connection connection = null; | |||
| PreparedStatement statement = null; | |||
| ResultSet resultSet = null; | |||
| try { | |||
| // 获得连接 | |||
| connection = BasicDataSourceUtil.getConnection(); | |||
| // 获得Statement对象 | |||
| statement = connection.prepareStatement(sql); | |||
| // 执行 | |||
| resultSet = statement.executeQuery(); | |||
| // 遍历结果集 | |||
| while(resultSet.next()) { | |||
| String name = resultSet.getString(2); | |||
| int age = resultSet.getInt(3); | |||
| System.out.println("用户名:" + name + ",年龄:" + age); | |||
| } | |||
| } catch(SQLException e) { | |||
| log.error("查询用户异常", e); | |||
| } finally { | |||
| // 释放资源 | |||
| BasicDataSourceUtil.release(connection, statement, resultSet); | |||
| } | |||
| } | |||
| /** | |||
| * 测试删除用户 | |||
| */ | |||
| @Test | |||
| public void delete() throws Exception { | |||
| // 创建sql | |||
| String sql = "delete from demo_user where name = ?"; | |||
| Connection connection = null; | |||
| PreparedStatement statement = null; | |||
| try { | |||
| // 获得连接 | |||
| connection = BasicDataSourceUtil.getConnection(); | |||
| // 设置非自动提交 | |||
| BasicDataSourceUtil.startTrasaction(); | |||
| // 获得Statement对象 | |||
| statement = connection.prepareStatement(sql); | |||
| // 设置参数 | |||
| statement.setString(1, "zzf003"); | |||
| // 执行 | |||
| statement.executeUpdate(); | |||
| // 提交事务 | |||
| BasicDataSourceUtil.commit(); | |||
| } catch(Exception e) { | |||
| log.error("异常导致操作回滚", e); | |||
| BasicDataSourceUtil.rollback(); | |||
| } finally { | |||
| // 释放资源 | |||
| BasicDataSourceUtil.release(connection, statement, null); | |||
| } | |||
| } | |||
| } | |||
| @@ -1,146 +0,0 @@ | |||
| package cn.zzs.dbcp; | |||
| import java.sql.Connection; | |||
| import java.sql.Date; | |||
| import java.sql.PreparedStatement; | |||
| import java.sql.ResultSet; | |||
| import java.sql.SQLException; | |||
| import org.junit.Test; | |||
| /** | |||
| * @ClassName: DBCPTest | |||
| * @Description: 测试DBCP | |||
| * @author: zzs | |||
| * @date: 2019年8月31日 下午9:39:54 | |||
| */ | |||
| public class DBCPTest { | |||
| /** | |||
| * 测试添加用户 | |||
| * @throws SQLException | |||
| */ | |||
| @Test | |||
| public void saveUser() throws Exception { | |||
| //创建sql | |||
| String sql = "insert into user values(null,?,?,?,?)"; | |||
| //获得连接 | |||
| Connection connection = JDBCUtil.getConnection(); | |||
| PreparedStatement statement = null; | |||
| try { | |||
| //设置非自动提交 | |||
| connection.setAutoCommit(false); | |||
| //获得Statement对象 | |||
| statement = connection.prepareStatement(sql); | |||
| //设置参数 | |||
| statement.setString(1, "zzs001"); | |||
| statement.setInt(2, 18); | |||
| statement.setDate(3, new Date(System.currentTimeMillis())); | |||
| statement.setDate(4, new Date(System.currentTimeMillis())); | |||
| //执行 | |||
| statement.executeUpdate(); | |||
| //提交事务 | |||
| connection.commit(); | |||
| } catch (Exception e) { | |||
| System.out.println("异常导致操作回滚"); | |||
| connection.rollback(); | |||
| e.printStackTrace(); | |||
| } finally { | |||
| //释放资源 | |||
| JDBCUtil.release(connection, statement,null); | |||
| } | |||
| } | |||
| /** | |||
| * 测试更新用户 | |||
| */ | |||
| @Test | |||
| public void updateUser() throws Exception { | |||
| //创建sql | |||
| String sql = "update user set age = ?,gmt_modified = ? where name = ?"; | |||
| //获得连接 | |||
| Connection connection = JDBCUtil.getConnection(); | |||
| PreparedStatement statement = null; | |||
| try { | |||
| //设置非自动提交 | |||
| connection.setAutoCommit(false); | |||
| //获得Statement对象 | |||
| statement = connection.prepareStatement(sql); | |||
| //设置参数 | |||
| statement.setInt(1, 19); | |||
| statement.setDate(2, new Date(System.currentTimeMillis())); | |||
| statement.setString(3, "zzs001"); | |||
| //执行 | |||
| statement.executeUpdate(); | |||
| //提交事务 | |||
| connection.commit(); | |||
| } catch (Exception e) { | |||
| System.out.println("异常导致操作回滚"); | |||
| connection.rollback(); | |||
| e.printStackTrace(); | |||
| } finally { | |||
| //释放资源 | |||
| JDBCUtil.release(connection, statement,null); | |||
| } | |||
| } | |||
| /** | |||
| * 测试查找用户 | |||
| */ | |||
| @Test | |||
| public void findUser() throws Exception { | |||
| //创建sql | |||
| String sql = "select * from user where name = ?"; | |||
| //获得连接 | |||
| Connection connection = JDBCUtil.getConnection(); | |||
| PreparedStatement statement = null; | |||
| ResultSet resultSet = null; | |||
| try { | |||
| //获得Statement对象 | |||
| statement = connection.prepareStatement(sql); | |||
| //设置参数 | |||
| statement.setString(1, "zzs001"); | |||
| //执行 | |||
| resultSet = statement.executeQuery(); | |||
| //遍历结果集 | |||
| while (resultSet.next()) { | |||
| String name = resultSet.getString(2); | |||
| int age = resultSet.getInt(3); | |||
| System.out.println("用户名:" + name + ",年龄:" + age); | |||
| } | |||
| } finally { | |||
| //释放资源 | |||
| JDBCUtil.release(connection, statement,resultSet); | |||
| } | |||
| } | |||
| /** | |||
| * 测试删除用户 | |||
| */ | |||
| @Test | |||
| public void deleteUser() throws Exception { | |||
| //创建sql | |||
| String sql = "delete from user where name = ?"; | |||
| //获得连接 | |||
| Connection connection = JDBCUtil.getConnection(); | |||
| PreparedStatement statement = null; | |||
| try { | |||
| //设置非自动提交 | |||
| connection.setAutoCommit(false); | |||
| //获得Statement对象 | |||
| statement = connection.prepareStatement(sql); | |||
| //设置参数 | |||
| statement.setString(1, "zzs001"); | |||
| //执行 | |||
| statement.executeUpdate(); | |||
| //提交事务 | |||
| connection.commit(); | |||
| } catch (Exception e) { | |||
| System.out.println("异常导致操作回滚"); | |||
| connection.rollback(); | |||
| e.printStackTrace(); | |||
| } finally { | |||
| //释放资源 | |||
| JDBCUtil.release(connection, statement,null); | |||
| } | |||
| } | |||
| } | |||
| @@ -0,0 +1,22 @@ | |||
| /** | |||
| * Copyright © 2019 zzs. All rights reserved. | |||
| * | |||
| * @Title: InstanceKeyDataSourceTest.java | |||
| * @Prject: DBCP-demo | |||
| * @Package: cn.zzs.dbcp | |||
| * @Description: TODO | |||
| * @author: zzs | |||
| * @date: 2019年11月27日 上午8:33:40 | |||
| * @version: V 1.0.0 | |||
| */ | |||
| package cn.zzs.dbcp; | |||
| /** | |||
| * @ClassName: InstanceKeyDataSourceTest | |||
| * @Description: 测试使用SharedPoolDataSource和PerUserPoolDataSource获取连接,并对比二者差异 | |||
| * @author: zzs | |||
| * @date: 2019年11月27日 上午8:33:40 | |||
| */ | |||
| public class InstanceKeyDataSourceTest { | |||
| } | |||