背景知识:
什么是ConnectionPool,DataSource,JNDI
首先,普通的Connection的取得(getConnection)和关闭(close)的开销比较大,解决这个问题的方法是ConnectionPool(连接池),也就是事先获得一定数量的连接,程序执行的时候不需要新建Connection,而是从此连接池中获取已经准备好的Connection的使用权,提供连接池的技术叫DataSource,DataSource可以new出来,但一般是通过JNDI用lookup方法来获得。
什么是JNDI(Java Naming and Directory Interface)技术:
JNDI提供命名服务和目录服务:
命名服务即将人类更容易认识的值同计算机更容易认识的值进行映射。如域名和IP地址,你的身份证和姓名之间也是一种映射。
目录服务即有组织地访问散落在互联网中的资源,如通过电话簿查某人的电话:先找到这个人的名字,再看他的电话。
即,JNDI的作用是,将一个Java对象放在容器(JNDI容器)中,并为存储的这个对象取一个名称,如果某个程序的方法要想获得这个对象,则使用JNDI并通过存储的名称检索(lookup()方法)即可获得。
举个栗子:
没有JNDI时,我们使用JDBC的过程是:
//1.要求JVM查找并加载指定类并实例化
Class.forName("com.mysql.cj.jdbc.Driver").newInstance();
//2.链接本地MYSQL
Connection con = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/javaee?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC", "root", "password");
//3.创建声明
Statement stmt = con.createStatement();
//4.执行语句
stmt.executeUpdate("select * from studentinfo");
//5.关闭连接
stmt.close();
con.close();
而有了JNDI时,我们使用JDBC的过程是:
//1、初始化名称查找上下文
Context ctx = new InitialContext();
//2.通过JNDI名称找到DataSource,对名称进行定位java:comp/env是必须加的,后面跟的是DataSource名
//也可以分两步,先查找java:comp/env 返回一个Context,再用这个Context查找jdbc/javaee,返回一个DataSource
DataSource ds = (DataSource)ctx.lookup("java:comp/env/jdbc/javaee");
//3、通过DataSource取得一个连接
connMySQL = ds.getConnection();
//4、操作数据库
//5、关闭数据库,关闭的时候是将连接放回到连接池之中
connMySQL.close();
即,程序员不需要关心JDBC驱动程序的引用、服务器名称、用户名、密码,甚至没有数据库池和连接管理,而把这些交给J2EE容器来配置和管理,程序员要只需要引用即可。
那么,笨拙的计算机怎么知道连接数据库的信息呢?这就需要配置:
若在tomcat下,可以有三种方法:
1.将配置直接写入 tomcat目录\conf\server.xml下,这是改动tomcat全局配置信息,不推荐
2.将配置写入 tomcat目录\conf\Catalina\localhost\以你的工程名称命名.xml下,改变了tomcat局部配置信息,也不推荐
3.直接在工程目录下,如 你的工程\WebContent\META-INF\context.xml中(新建的xml文件必须命名为context.xml),推荐!
第三种方法下,tomcat会自动获取context.xml中的内容,以工程名称命名.xml写到tomcat目录\conf\Catalina\localhost\,即第二种方法
第三种方法下的配置文件(即context.xml)内容:
<?xml version="1.0" encoding="UTF-8"?>
<Context>
<Resource name="jdbc/javaee"--该项目的项目名为jdbc/javaee
auth="Container"--可以是Application或者Container
type="javax.sql.DataSource"--必须这么写
username="root"
password="password"
driverClassName="com.mysql.cj.jdbc.Driver"--数据库驱动名
url="jdbc:mysql://localhost:3306/javaee"
initialSize="10"
maxActive="20"--最大连接数
maxIdle="4"/>--最大空闲连接数 --还有maxWait 最大等待毫秒数,若为-1则无限等待
</Context>
在tomcat6.0以前,还需要在项目的web.xml中配置
<resource-ref>
<description>JNDI DataSource</description>
<res-ref-name>jdbc/javaee</res-ref-name> --这里的名字应该要和context.xml的名字一样
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
此外,如果碰到运行时报The server time zone value 'Öйú±ê׼ʱ¼ä' is unrecognized or represents more than one time zone,则在登录mysql后执行命令:
mysql> show variables like '%time_zone%';
mysql> set global time_zone='+8:00';
即可