数据库——JavaWEB数据库连接
一、数据库连接的发展
1.数据库连接
用户每次请求都需要向数据库获得链接,而数据库创建连接通常需要消耗相对较大的资源,创建时间也较长。假设网站一天10万访问量,数据库服务器就需要创建10万次连接,极大的浪费数据库的资源,并且极易造成数据库服务器内存溢出、拓机。如下图所示:
2.解决创建数据库连接花费系统开销浪费系统资源和可能产生数据库服务器内存溢出和宕机的办法
①数据库连接池
数据库连接池负责分配,管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是重新建立一个
数据库连接池在初始化时将创建一定数量的数据库连接放到连接池中, 这些数据库连接的数量是由最小数据库连接数来设定的.无论这些数据库连接是否被使用,连接池都将一直保证至少拥有这么多的连接数量.连接池的最大数据库连接数量限定了这个连接池能占有的最大连接数,当应用程序向连接池请求的连接数超过最大连接数量时,这些请求将被加入到等待队列中.
连接数量对服务器相应连接请求性能的影响:
- 最小连接数:是连接池一直保持的数据库连接,所以如果应用程序对数据库连接的使用量不大,将会有大量的数据库连接资源被浪费.
- 最大连接数:是连接池能申请的最大连接数,如果数据库连接请求超过次数,后面的数据库连接请求将被加入到等待队列中,这会影响以后的数据库操作
- 如果最小连接数与最大连接数相差很大:那么最先连接请求将会获利,之后超过最小连接数量的连接请求等价于建立一个新的数据库连接.不过,这些大于最小连接数的数据库连接在使用完不会马上被释放,他将被放到连接池中等待重复使用或是空间超时后被释放.
②数据库连接池的实现
编写连接池需实现java.sql.DataSource接口。DataSource接口中定义了两个重载的 getConnection方法:
- Connection getConnection()
- Connection getConnection(String username, String password)
实现DataSource接口,并实现连接池功能的步骤:
- 在DataSource构造函数中批量创建与数据库的连接,并把创建的连接加入LinkedList对象中。
- 实现getConnection方法,让getConnection方法每次调用时,从LinkedList中取一个Connection返回给用户。
- 当用户使用完Connection,调用Connection.close()方法时,Collection对象应保证将自己返回到LinkedList中,而不要把conn还给数据库。Collection保证将自己返回到LinkedList中是此处编程的难点。
实现一(动态代理技术进行实现):
proxyConn = (Connection) Proxy.newProxyInstance(this.getClass().getClassLoader(),conn.getClass()
.getInterfaces(),new InvocationHandler(){
//内部类,当colse方法被调用时将conn还回池中,其他方法直接执行
public Object invoke(Object proxy,Method method,Object[] args)throws Throwable{
if(method.getName().equals("close")){
pool.addLast(conn);
return null;
}
return method.invoke(conn,args);
}
}
完整案例
import java.io.InputStram;
import java.io.PrintWriter;
import java.lang.reflect.InvocationHandler;
import java.lang.reflet.Method;
import java.lang.reflet.Proxy;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.LinkedList;
import java.util.Properties;
import java.sql.DataSource; Public class JdbcPool implements DataSource{
//LinkedList存储数据库连接对象
private static LinkedList<Connection> listConnections = new LinkedList<Connection>();
static{
//在静态代码块中加载db.properties数据库配置文件
InputStream in =
JdbcPool.class.getClassLoader().getResourceAsStream("db.properties");
Properties prop = new Properties();
try{
prop.load(in);
String driver = prop.getProperty("driver);
String url = prop.getProperty("url");
String username = prop.getProperty("username");
String password = prop.getProperty("password");
//初始化连接池的大小
int jdbcPoolInitSize = Interger.parseInt(prop.getProperty("JdbcInitialSize");
//加载数据库驱动
class.forName(driver);
for(int i = 0; i < jdbcPoolSize; i++){
Connection conn = Drivermanager.getConnection(url,username,password);
listConnections.add(conn);
}
}catch(Exception e){
throw new ExceptionInInitializerError(e);
}
}
@Override
58 public PrintWriter getLogWriter() throws SQLException {
59 // TODO Auto-generated method stub
60 return null;
61 }
62
63 @Override
64 public void setLogWriter(PrintWriter out) throws SQLException {
65 // TODO Auto-generated method stub
66
67 }
68
69 @Override
70 public void setLoginTimeout(int seconds) throws SQLException {
71 // TODO Auto-generated method stub
72
73 }
74
75 @Override
76 public int getLoginTimeout() throws SQLException {
77 // TODO Auto-generated method stub
78 return 0;
79 }
80
81 @Override
82 public <T> T unwrap(Class<T> iface) throws SQLException {
83 // TODO Auto-generated method stub
84 return null;
85 }
86
87 @Override
88 public boolean isWrapperFor(Class<?> iface) throws SQLException {
89 // TODO Auto-generated method stub
90 return false;
91 }
//获取数据库连接
@Override
public Connection getConnection() throws SQLExcepion{
//如果数据库连接池中的连接对象的个数大于零
if(listconnection.size()>0){
final Connection conn = listConnections.removeFirst();
System.out.println("listConnections连接池中还有”+listConnections.size();
//返回Connection对象的代理对象
return (Connection) Proxy.newProxyInstance(Jdbc.calss.getClassLoader(),
conn.getClass().getInterfaces(),new InvocationHandler(){
@Overrite
pulbic Object invoke(Object proxy, Method method,Object[] args)throws Throwables{
if(!method.getName().equals("close")){
return method.invoke(conn,args); }else{
//如果调用的是connection对象的close方法,就把conn还给数据库连接池
listConnections.add(conn);
System.out.println("listConnections对象个数”+listConnections.seze());
return null;
}
}
});
}else{
throw new RuntimeException("对不起,数据库库忙”);
}
@Overrite
public Connection getConnection(String username,String password)
throws SQLException{
return null;
}
}
}
1driver=com.mysql.jdbc.Driver
2 url=jdbc:mysql://localhost:3306/jdbcStudy
3 username=root
4 password=XDP
5
6 jdbcPoolInitSize=10
3 import java.sql.Connection;
4 import java.sql.ResultSet;
5 import java.sql.SQLException;
6 import java.sql.Statement;
7 import me.gacl.demo.JdbcPool;
8
9 public class JdbcUtil {
10
11 /**
12 * @Field: pool
13 * 数据库连接池
14 */
15 private static JdbcPool pool = new JdbcPool();
24 public static Connection getConnection() throws SQLException{
25 return pool.getConnection();
26 }
38 public static void release(Connection conn,Statement st,ResultSet rs){
39 if(rs!=null){
40 try{
41 //关闭存储查询结果的ResultSet对象
42 rs.close();
43 }catch (Exception e) {
44 e.printStackTrace();
45 }
46 rs = null;
47 }
48 if(st!=null){
49 try{
50 //关闭负责执行SQL命令的Statement对象
51 st.close();
52 }catch (Exception e) {
53 e.printStackTrace();
54 }
55 }
56
57 if(conn!=null){
58 try{
59 //关闭Connection数据库连接对象
60 conn.close();
61 }catch (Exception e) {
62 e.printStackTrace();
63 }
64 }
65 }
66 }
二、支持数据库连接的开源库
1.DBCP和C3P0
现在很多WEB服务器(Weblogic, WebSphere, Tomcat)都提供了DataSoruce的实现,即连接池的实现。通常我们把DataSource的实现,按其英文含义称之为数据源,数据源中都包含了数据库连接池的实现。
也有一些开源组织提供了数据源的独立实现:
1.DBCP数据库连接池
2.C3P0数据库连接池
在使用了数据库连接池之后,在项目的实际开发中就不需要编写连接数据库的代码了,直接从数据源获得数据库的连接。
①DBCP数据源
BCP 是 Apache 软件基金组织下的开源连接池实现,要使用DBCP数据源,需要应用程序应在系统中增加如下两个 jar 文件:
Commons-dbcp.jar:连接池的实现
Commons-pool.jar:连接池实现的依赖库;
Tomcat 的连接池正是采用该连接池来实现的。该数据库连接池既可以与应用服务器整合使用,也可由应用程序独立使用。
2.DBCP和C3P0的实现
①导入相关jar包
comons-dbcp.jar、commons-pool.jar
在类目录下假如dbcp的配置文件:dbcpconfig.properties;
#连接设置
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/jdbcstudy
username=root
password=XDP #<!-- 初始化连接 -->
initialSize=10 #最大连接数量
maxActive=50 #<!-- 最大空闲连接 -->
maxIdle=20 #<!-- 最小空闲连接 -->
minIdle=5 #<!-- 超时等待时间以毫秒为单位 6000毫秒/1000等于60秒 -->
maxWait=60000 #JDBC驱动建立连接时附带的连接属性属性的格式必须为这样:[属性名=property;]
#注意:"user" 与 "password" 两个属性会被明确地传递,因此这里不需要包含他们。
connectionProperties=useUnicode=true;characterEncoding=UTF8 #指定由连接池所创建的连接的自动提交(auto-commit)状态。
defaultAutoCommit=true #driver default 指定由连接池所创建的连接的只读(read-only)状态。
#如果没有设置该值,则“setReadOnly”方法将不被调用。(某些驱动并不支持只读模式,如:Informix)
defaultReadOnly= #driver default 指定由连接池所创建的连接的事务级别(TransactionIsolation)。
#可用值为下列之一:(详情可见javadoc。)NONE,READ_UNCOMMITTED, READ_COMMITTED, REPEATABLE_READ, SERIALIZABLE
defaultTransactionIsolation=READ_UNCOMMITTED
②在获取数据库连接的工具类(jdbcUTILS)的静态代码块中创建池
import java.io.InputStream;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Properties;
import java.sql.DataSources;
import javax.sql.DataSource;
import org.apache.commons.dbcp.BasicDataSourceFactory; public class JdbcUtils_DBCP{
private static DataSource ds = null;
//在静态代码块中创建连接池
static{
try{
InputStram in = JdbcUtils_DBCP.class.getClassLoader()
.getResourceAsStream("dbcpconfig.properties");
Properties prop = new Properties();
prop.load(in);
//创建数据源
ds = BasicDataSourceFactory.createDataSource(prop);
}catch(Exception e){
throw new ExceptionInitialixerError(e);
}
}
public static Connection getConnection() throws SQLException{
//从数据源中获得连接对象connectino
return ds.getConnection();
}
//释放资源:ResultSet,Statement,Connection;
public static void release(Connection conn,Statement st,ResultSet rs)
if(rs!=null){
try{
re.close();
}catch(Exception e){
e.printStackTrace();
}
rs = null;
}
if(sta!=null){
try{
re.close();
}catch(Exception e){
e.printStackTrace();
}
sta= null;
}
if(conn!=null){
try{
re.close();
}catch(Exception e){
e.printStackTrace();
}
conn= null;
}
}
}
}
测试数据源
import JdbcUtils_DBCP; public class DataSourceTest{
@Test
public void dbcpDataSourceTest(){
Connection conn = null;
PreparedStatement st = null;
ResultSet rs = null;
try{
Connection conn = JdbcUtils_DBCP.getConnection();
String sql = "insert into test1(name) values(?)";
st = conn.getPreparedStatement(sql);
st.setString(1,"values");
//获取数据库自动生成的主键
re = st.getGeneratedkeys();
if(rs.next()){
SysO(rs.getInt(1));
}
}catch(Exception e){
e.printStackTrace();
}fianlly{
JdbcUtils_CBCP.release(conn,st,re);
}
}
}
③C3P0数据源
C3P0是一个开源的JDBC连接池,它实现了数据源和JNDI绑定,支持JDBC2的标准扩展
目前使用它的开源项目有Hibernate.Spring等。C3P0数据源在项目开发中使用的比较多。
c3p0与dbcp的区别是:dbcp没有自动回收空闲连接的功能,C3P0有自动回收空闲连接的功能。
④C3P0数据源的实现
1.导入相关jar包:c3p0-0.9.2-pre1.jar、mchange-commons-0.2.jar,
如果是操作的是Oracle数据库,还需要导入:c3p0-oracle-thin-extras-0.9.2-pre1.jar
2.在类目录下假如C3P0的配置文件:c3p0-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<!--
c3p0-config.xml必须位于类路径下面
private static ComboPooledDataSource ds;
static{
try {
ds = new ComboPooledDataSource("MySQL");
} catch (Exception e) {
throw new ExceptionInInitializerError(e);
}
}
--> <c3p0-config>
<!--
C3P0的缺省(默认)配置,
如果在代码中“ComboPooledDataSource ds = new ComboPooledDataSource();”这样写就表示使用的是C3P0的缺省(默认)配置信息来创建数据源
-->
<default-config>
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/jdbcstudy</property>
<property name="user">root</property>
<property name="password">XDP</property> <property name="acquireIncrement">5</property>
<property name="initialPoolSize">10</property>
<property name="minPoolSize">5</property>
<property name="maxPoolSize">20</property>
</default-config> <!--
C3P0的命名配置,
如果在代码中“ComboPooledDataSource ds = new ComboPooledDataSource("MySQL");”这样写就表示使用的是name是MySQL的配置信息来创建数据源
-->
<named-config name="MySQL">
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/jdbcstudy</property>
<property name="user">root</property>
<property name="password">XDP</property> <property name="acquireIncrement">5</property>
<property name="initialPoolSize">10</property>
<property name="minPoolSize">5</property>
<property name="maxPoolSize">20</property>
</named-config> </c3p0-config>
import java.sql.connection;
import java.sql.Statement;
import java.sql.SQLException;
import com.mchange.v2.c3p0.ComboPooledDataSource;
public class JdbcUtils_C3P0 { private static ComboPooledDataSource ds = null;
//在静态代码块中创建数据库连接池
static{
try{
//通过代码创建C3P0数据库连接池
/*ds = new ComboPooledDataSource();
ds.setDriverClass("com.mysql.jdbc.Driver");
ds.setJdbcUrl("jdbc:mysql://localhost:3306/jdbcstudy");
ds.setUser("root");
ds.setPassword("XDP");
ds.setInitialPoolSize(10);
ds.setMinPoolSize(5);
ds.setMaxPoolSize(20);*/ //通过读取C3P0的xml配置文件创建数据源,C3P0的xml配置文件c3p0-config.xml必须放在src目录下
//ds = new ComboPooledDataSource();//使用C3P0的默认配置来创建数据源
ds = new ComboPooledDataSource("MySQL");//使用C3P0的命名配置来创建数据源 }catch (Exception e) {
throw new ExceptionInInitializerError(e);
}
} /**
* @Method: getConnection
* @Description: 从数据源中获取数据库连接
* @Anthor:孤傲苍狼
* @return Connection
* @throws SQLException
*/
public static Connection getConnection() throws SQLException{
//从数据源中获取数据库连接
return ds.getConnection();
} /**
* @Method: release
* @Description: 释放资源,
* 释放的资源包括Connection数据库连接对象,负责执行SQL命令的Statement对象,存储查询结果的ResultSet对象
* @Anthor:孤傲苍狼
*
* @param conn
* @param st
* @param rs
*/
public static void release(Connection conn,Statement st,ResultSet rs){
if(rs!=null){
try{
//关闭存储查询结果的ResultSet对象
rs.close();
}catch (Exception e) {
e.printStackTrace();
}
rs = null;
}
if(st!=null){
try{
//关闭负责执行SQL命令的Statement对象
st.close();
}catch (Exception e) {
e.printStackTrace();
}
} if(conn!=null){
try{
//将Connection连接对象还给数据库连接池
conn.close();
}catch (Exception e) {
e.printStackTrace();
}
}
}
}
测试,包括获取数据源和释放资源
import java.sql.connection;
import java.sql.statement;
import java.sql.ResultSet;
import org.junit.Test;
import c3p0,Dbcp;
public class DataSourceTest { @Test
public void c3p0DataSourceTest() {
Connection conn = null;
PreparedStatement st = null;
ResultSet rs = null;
try{
//获取数据库连接
conn = JdbcUtils_C3P0.getConnection();
String sql = "insert into test1(name) values(?)";
st = conn.prepareStatement(sql);
st.setString(1, "gacl");
st.executeUpdate();
//获取数据库自动生成的主键
rs = st.getGeneratedKeys();
if(rs.next()){
System.out.println(rs.getInt(1));
}
}catch (Exception e) {
e.printStackTrace();
}finally{
//释放资源
JdbcUtils_C3P0.release(conn, st, rs);
}
}
}
三、配置tomcat数据源
1.在实际开发中,我们有时候还会使用服务器提供给我们的数据库连接池,比如我们希望Tomcat服务器在启动的时候可以帮我们创建一个数据库连接池,那么我们在应用程序中就不需要手动去创建数据库连接池,直接使用Tomcat服务器创建好的数据库连接池即可。要想让Tomcat服务器在启动的时候帮我们创建一个数据库连接池,那么需要简单配置一下Tomcat服务器。
Tomcat服务器创建的数据源是以JNDI资源的形式发布的,所以说在Tomat服务器中配置一个数据源实际上就是在配置一个JNDI资源,通过查看Tomcat文档,我们知道使用如下的方式配置tomcat服务器的数据源:
<Context>
<Resource name = "jdbc/datasource" auth="Container"
type = "javax.sql.DataSource" usernaem="root" password= "XDP"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/jdbcs..."
maxActive="8" maxIdle="4"/>
</Context>
服务器创建好数据源之后,我们的应用程序又该怎么样得到这个数据源呢,Tomcat服务器创建好数据源之后是以JNDI的形式绑定到一个JNDI容器中的,我们可以把JNDI想象成一个大大的容器,我们可以往这个容器中存放一些对象,一些资源,JNDI容器中存放的对象和资源都会有一个独一无二的名称,应用程序想从JNDI容器中获取资源时,只需要告诉JNDI容器要获取的资源的名称,JNDI根据名称去找到对应的资源后返回给应用程序。我们平时做javaEE开发时,服务器会为我们的应用程序创建很多资源,比如request对象,response对象,服务器创建的这些资源有两种方式提供给我们的应用程序使用:第一种是通过方法参数的形式传递进来,比如我们在Servlet中写的doPost和doGet方法中使用到的request对象和response对象就是服务器以参数的形式传递给我们的。第二种就是JNDI的方式,服务器把创建好的资源绑定到JNDI容器中去,应用程序想要使用资源时,就直接从JNDI容器中获取相应的资源即可。
对于上面的name="jdbc/datasource"数据源资源,在应用程序中可以用如下的代码去获取
Context initCtx = new Initialcontext();
Context envCtx = (Context)initCtx.lookup("java:comp/env");
dataSource = (DataSource)envCtx.lookup("jdbc/datasource"):
此种配置下,数据库的驱动jar文件需放置在tomcat的lib下
2.配置tomcat数据源的实现
①在Web项目的WebRoot目录下的META-INF目录创建一个context.xml文件
如下图所示:
配置Context.xml文件如下
1 <Context>
2 <Resource
3 name="jdbc/datasource"
4 auth="Container"
5 type="javax.sql.DataSource"
6 username="root"
7 password="XDP"
8 driverClassName="com.mysql.jdbc.Driver"
9 url="jdbc:mysql://localhost:3306/jdbcstudy"
10 maxActive="8"
11 maxIdle="4"/>
12 </Context>
导入数据库驱动的jar文件
获取数据库连接的工具类(如jdbcUtils)的静态代码块中获取JNDI容器中的数据源
package me.gacl.util; import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.sql.DataSource; /**
* @ClassName: JdbcUtils_DBCP
* @Description: 数据库连接工具类
* @author: 孤傲苍狼
* @date: 2014-10-4 下午6:04:36
*
*/
public class JdbcUtils_JNDI { private static DataSource ds = null;
//在静态代码块中创建数据库连接池
static{
try{
//初始化JNDI
Context initCtx = new InitialContext();
//得到JNDI容器
Context envCtx = (Context) initCtx.lookup("java:comp/env");
//从JNDI容器中检索name为jdbc/datasource的数据源
ds = (DataSource)envCtx.lookup("jdbc/datasource");
}catch (Exception e) {
throw new ExceptionInInitializerError(e);
}
} /**
* @Method: getConnection
* @Description: 从数据源中获取数据库连接
* @Anthor:孤傲苍狼
* @return Connection
* @throws SQLException
*/
public static Connection getConnection() throws SQLException{
//从数据源中获取数据库连接
return ds.getConnection();
} /**
* @Method: release
* @Description: 释放资源,
* 释放的资源包括Connection数据库连接对象,负责执行SQL命令的Statement对象,存储查询结果的ResultSet对象
* @Anthor:孤傲苍狼
*
* @param conn
* @param st
* @param rs
*/
public static void release(Connection conn,Statement st,ResultSet rs){
if(rs!=null){
try{
//关闭存储查询结果的ResultSet对象
rs.close();
}catch (Exception e) {
e.printStackTrace();
}
rs = null;
}
if(st!=null){
try{
//关闭负责执行SQL命令的Statement对象
st.close();
}catch (Exception e) {
e.printStackTrace();
}
} if(conn!=null){
try{
//将Connection连接对象还给数据库连接池
conn.close();
}catch (Exception e) {
e.printStackTrace();
}
}
}
}
测试配置和数据源
package me.gacl.test; import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import me.gacl.util.JdbcUtils_JNDI; public class JNDITest extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
Connection conn = null;
PreparedStatement st = null;
ResultSet rs = null;
try{
//获取数据库连接
conn = JdbcUtils_JNDI.getConnection();
String sql = "insert into test1(name) values(?)";
st = conn.prepareStatement(sql);
st.setString(1, "gacl");
st.executeUpdate();
//获取数据库自动生成的主键
rs = st.getGeneratedKeys();
if(rs.next()){
System.out.println(rs.getInt(1));
}
}catch (Exception e) {
e.printStackTrace();
}finally{
//释放资源
JdbcUtils_JNDI.release(conn, st, rs);
}
} public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
} }
数据库——JavaWEB数据库连接的更多相关文章
- JavaWeb -JDBC使用(数据库-javaweb连接)
使用JDBC四个大类 1. DriverManager:管理jdbc驱动 2. Connection:连接(通过DriverManager产生) 3. Statement/PreparedStatem ...
- java连数据库和数据库连接池踩坑日记(一)-------oracle连接的一些问题
最近接触oracle有点多,同时也在配置数据库连接池,坑也就踩多了,记录下. 事情还没有结束,没时间记录问题,很多事情都忘了,过了国庆再写的话可能就真的全忘了吧……而且不单单是数据库问题,还有一些数据 ...
- Qt数据库之数据库连接池
前面的章节里,我们使用了下面的函数创建和取得数据库连接: void createConnectionByName(const QString &connectionName) { QSql ...
- javaWeb 数据库连接池连接数据库
需要的公共jar包 mysql-connector-java-5.0.8-bin.jar(mysql数据库) ojdbc14.jar(oracle数据库) A.DBCP 需要jar包: commo ...
- 20160409 javaweb 数据库连接池
1.自己编写数据库连接池: package com.dzq.pool; import java.io.PrintWriter; import java.lang.reflect.InvocationH ...
- java web中jsp连接mysql数据库 以及数据库连接池的使用
将mysql-connector-java-5.1.6-bin.jar导入到tomcat的lib目录下. 在java项目中,只需要引入mysql-connector-java-5.1.6-bin.ja ...
- 9-21 调试javaweb 数据库连接感想
如何找bug 一步步调试 数据库链接写一个简单的 test 数据库操作 sql语句 写一个类 测试一下 不要忽略细节 最后页面的显示 html "/head"少一个"/& ...
- java连数据库和数据库连接池踩坑日记(二)-------数据库连接池c3p0
关于数据库连接池,我觉得有些沮丧,因为最后被毙掉了说不用考虑多线程的问题…… 数据库连接池的推荐:https://www.cnblogs.com/nuccch/p/8120349.html 我最终选择 ...
- JavaWeb连接MySQL数据库
JavaWeb连接MySQL数据库 JavaWeb连接MySQL数据库的方式有很多,首先我们讲解JDBC的配置方法 一.JDBC的配置方法 1.什么是JDBC 什么是JDBC嘞?JDBC代表Java数 ...
随机推荐
- 【转载】C#通过StartWith和EndWith方法判断字符串是否以特定字符开始或者结束
C#开发过程中针对字符串String类型的操作是常见操作,有时候业务需要判断某个字符串是否以特定字符开头或者特定字符结束,此时就可使用StartsWith方法来判断目标字符串是否以特定字符串开头,通过 ...
- arm的基本介绍
2440是arm9核,是基于v4 架构 6410是arm11核 基于v6架构 210是a8的核 基于v7架构 前面的是经典阵营,比较老.Arm11之后改为contex系列. Arm7的水准和M3相 ...
- 张量(tensor)的广播
在使用numpy 对张量(数组)进行操作时,两个形状相同的张量进行加减等运算很容易理解,那么不同形状的张量之间的运算是通过广播来实现的.广播实际上很简单,但是弄清楚是也花了不小功夫,这里记录一下. 广 ...
- 【fiddler】fiddler基础
一.浏览器设置 一般情况下,fiddler会自动修改IE浏览器的设置,捕捉到IE浏览器的搜有通讯.其他浏览器需要手动设置 如chrome 打开chrome->设置->高级->系统-& ...
- MySQL处理达到百万级数据时,如何优化?
1.两种查询引擎查询速度(myIsam 引擎 ) InnoDB 中不保存表的具体行数,也就是说,执行select count(*) from table时,InnoDB要扫描一遍整个表来计算有多少行. ...
- Windows10 临时将线程绑定至指定CPU的方法
本文首发:https://www.somata.work/2019/WindowsThreadBind.html 将线程绑定至指定CPU,这个应该时很多管理员需要了解认知的操作了吧,这样可以在一定程度 ...
- 更改和配置本地yum源
查看yum 存放位置 [root@web01 yum.repos.d]# ll /etc/yum.repos.d/ total -rw-r--r--. root root Jun CentOS-Bas ...
- PAT基础级-钻石段位样卷2-7-1 心理阴影面积 (5 分)
这是一幅心理阴影面积图.我们都以为自己可以匀速前进(图中蓝色直线),而拖延症晚期的我们往往执行的是最后时刻的疯狂赶工(图中的红色折线).由红.蓝线围出的面积,就是我们在做作业时的心理阴影面积. 现给出 ...
- k8s的pod的资源调度
1.常用的预选策略 2.优选函数 3.节点亲和调度 3.1.节点硬亲和性 3.2.节点软亲和性 4.Pod资源亲和调度 4.1.Pod硬亲和度 4.2.Pod软亲和度 4.3.Pod反亲和度 5.污点 ...
- P1417 烹调方案[背包]
题目背景 由于你的帮助,火星只遭受了最小的损失.但gw懒得重建家园了,就造了一艘飞船飞向遥远的earth星.不过飞船飞到一半,gw发现了一个很严重的问题:肚子饿了~ gw还是会做饭的,于是拿出了储藏的 ...