现在做的项目基本上只要上线就挂,无论多么强悍的服务器,都不行。主要是因为当用户在获得数据库连接的时候,这个数据库连接的数目是有限的,当一个数据库有1000个连接的时候,当有1001个用户来访问的时候,由于没有了数据库连接,数据库就会抛出一个TooManyCoonections的异常。因此这种应用只要正式上线就会瘫痪。并且当每次获得数据库连接的时候这种过程是非常耗时的。降低了用户体验和损失了服务器的性能。就好像厕所一样,之前的应用时每次获得一个连接,使用完成只会就销毁(close)。就好像有人要上厕所一样,每次上厕所的时候都要先建一个厕所,用完厕所之后拆掉。这个是非常耗时的。现在的一种解决方式就是先建立一个数据库连接池,也就是建立一个厕所,当有人要用数据库连接的时候就直接从数据库连接池里面获得连接,然后使用就可以了,就好像有人要上厕所,直接去厕所就行了,不用自己再建一个厕所。但是这又会导致一个问题,就是世界上到处都是厕所。因此我们规定这种类型的厕所成为公厕。只存在一份就可以了。在一个应用中,数据库连接池只用存在一份。所有的数据库连接都从这个池子里面拿就行了。同样的这样还会导致一个问题,当一个数据库连接池只有1000个连接的时候,第1001个人来访问,这时候没有连接,这时候数据库连接池应该可以自动补充数据库连接来弹性的补充数据库连接不够的情况,当请求数目减少的时候,这份数据库连接也自动被受贿。但是当扩充的这份数据库连接也不够使用的时候,就样用户在在后面排队,当等待了一定时间之后还没有获得链接就要通知用户不要再等了,让用户重新回去。设置用户等待时间。等多久就不用等了。
数据库连接中的常数写死的问题。
当应用提交给用户的时候用户的数据库连接地址和用户名密码在生产环境中的配置时不一样的,交付给用户的是class文件,无法在修改,因此要将数据库中的这些配置文件写成一个单独的并且在编译的时候不会被编译成字节码文件的配置文件。
在工程上右击选择属性----java build path -external floder ----etc
在etc文件夹下面家里一个后缀为.properties的配置文件。这个文件中的配置是以键值对的形式存在的,左边是键,右边是值,中间用等号来分隔。
一个键对应一个值,
一个键值对独占一行
不能使用中文
注释使用#开头
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/tianyu
jdbc.username=root
jdbc.password=123456
当数据库的用户名是中文的时候,手边又没有IDE开发环境的时候,可以使用jdk目录下面的native2ascii.exe将中文转换成Unicode字符。
连接池组件:
DBCP(Database Connection Pool)
C3P0
在获得数据库连接之前先要创建一个数据库连接池(数据源)
DataSource
由于整个数据源在整个应用中只存在一份。因此将其用private修饰
并且将数据库连接声明放在静态快中,这样就只声明一份并且在任何程序执行之前已经执行一次,且只执行一次。
private static BasicDataSource dataSource;
static{
//在静态块中读取properties配置文件
Properties prop = new Properties() ----java.util.Properties
try{
prop.load(DbHelp.class.getClassLoader().getResourceAsStream("db.properties");
DRIVER = prop.getProperty("jdbc.driver");
URL = prop.getProperty("jdbc.url");
USERNAME = prop.getProperty("jdbc.username");
PASSWORD = prop.getProperty("jdbc.password");
} catch( Exception e) {
}
/
设置数据源的属性
/
//设置Driver
dataSource.setDriverClassName(DRIVER);
//设置URL
dataSource.setUrl(URL);
//设置USERNAME
dataSource.setUsername(USERNAME);
//设置密码
dataSource.setPassword(PASSWORD);
//设定初始的链接数
dataSource.setInitialSize(10);
//设定最大的连接数
dataSource.setMaxActive(20);
//设定最长的等待时间
dataSource.setMaxWait(5000);
}
//获得数据库连接池中的连接
datasource.getConnection();
释放连接的时候不用太关心,当用完连接close的时候,会自动将连接放在数据库连接池中。