JDBC和连接池知识点

1. JDBC介绍

JDBC全称为:Java DataBase Connectivity(java数据库连接)。SUN公司为了简化、统一对数据库的操作,定义了一套Java操作数据库的规范,称之为JDBC。见图:

 

2.JDBC开发步骤

@Test
public void testJDBC() {

  Connection conn = null;
  PreparedStatement prestmt = null;
  ResultSet rs = null;

  try {
    // 注册驱动
    Class.forName("com.mysql.jdbc.Driver");
    // 获取连接
    conn = DriverManager.getConnection("jdbc:mysql:///day17", "root","admin");
    //执行SQL语句
    prestmt = conn.prepareStatement("select * from user where id = ?");
    prestmt.setString(1, "1");
    rs = prestmt.executeQuery();
    while (rs.next()) {
      System.out.println(rs);
      String name = rs.getString("name");
      System.out.println("name = " + name);
    }
  } catch (Exception e) {
  e.printStackTrace();
  } finally {
  //释放资源
  if (rs != null) {
  try {
      rs.close();
     } catch (SQLException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
  }
  if (prestmt != null) {
    try {
      prestmt.close();
        } catch (SQLException e) {
      // TODO Auto-generated catch block
    e.printStackTrace();
    }
  }
  if (conn != null) {
    try {
      conn.close();
      } catch (SQLException e) {
      // TODO Auto-generated catch block
        e.printStackTrace();
      }
    }
  }

}

3. 事务具有什么特性?

原子性:事务事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生
一致性:事务前后数据的完整性必须保持一致
隔离性:事务的隔离性是指多个用户并发访问数据库时,一个用户的事务不能被其它用户的事务所干扰,多个并发事务的数据要相互隔离.
持久性:持久性一个事务一旦被提交,它的数据库中数据的改变就是永久性的,然后即使数据库发生故障也不对其他有任何影响.

4. 事物操作的关键字

l  手动的开启事务: start transaction           

l  手动提交事务:  commit   ----- 表示确认 开启事务后 的若干步操作, 在commit 之后, 那么数据就真的持久化到硬盘上了

l  手动回滚事务:  rollback --------- 表示在开启事务后, 中间进行了若干步操作, 如果出现时了异常, 那么回滚事务,这个时候数据不会真的持久化到硬盘上

这几个特性中,最最重要的, 是隔离性, 通常会有程序的多线程并发, 那么在并发访问的时候,最终操作了数据库中的数据,

如果同时操作的是同一张表的同一行记录, 就肯定事务的隔离性问题了.

5. 什么是事务的隔离性? 如果不考虑隔离性,会引发哪几类问题?

事务的隔离性:是指多个用户并发访问数据库时,一个用户的事务不能被其它用户的事务所干扰,多个并发事务的数据要相互隔离.
会发生三类问题:
第一类:脏读,一个事务读到其它事务未提交的数据
第二类:不可重复读,一个事务读到其他事务已经提交的数据,强调的是使用update语句对原有的记录进行更改
第三类:虚读,幻读.一个事务读到其他事务已经提交的数据,强调的是使用insert语句对表格的数据插入操作,发生概率较小.

不可重复读:是指在一个事务内,多次读同一数据。在这个事务还没有结束时,另外一个事务也访问该同一数据。那么,在第一个事务中的两次读数据之间,由于第二个事务的修改,那么第一个事务两次读到的的数据可能是不一样的。这样在一个事务内两次读到的数据是不一样的,因此称为是不可重复读。
e.g.
1.在事务1中,Mary 读取了自己的工资为1000,操作并没有完成
2.在事务2中,这时财务人员修改了Mary的工资为2000,并提交了事务.
3.在事务1中,Mary 再次读取自己的工资时,工资变为了2000
解决办法:如果只有在修改事务完全提交之后才可以读取数据,则可以避免该问题。

幻读 : 是指当事务不是独立执行时发生的一种现象,例如第一个事务对一个表中的数据进行了修改,这种修改涉及到表中的全部数据行。同时,第二个事务也修改这个表中的数据,这种修改是向表中插入一行新数据。那么,以后就会发生操作第一个事务的用户发现表中还有没有修改的数据行,就好象发生了幻觉一样。
e.g. 
目前工资为1000的员工有10人。
1.事务1,读取所有工资为1000的员工。
2.这时事务2向employee表插入了一条员工记录,工资也为1000
3.事务1再次读取所有工资为1000的员工 共读取到了11条记录, 
解决办法:如果在操作事务完成数据处理之前,任何其他事务都不可以添加新数据,则可避免该问题

6. 为什么要使用数据库连接池?

一次性批量的制造一些连接Connection对象放到连接池中, 要使用的时候就从这个池子中取出一个连接使用,当用完不再需要使用的时候,
再将连接放回到池子中, 这样就可以在其他的程序要使用连接的时候可以达到复用连接,避免了不断的创建连接,关闭连接, 从而达到了优化.

7. 请列举出至少两种开源的数据库连接池技术?

C3P0 

C3P0是一个开源的JDBC连接池,它实现了数据源和JNDI绑定,支持JDBC3规范和JDBC2的标准扩展。目前使用它的开源项目有Hibernate,Spring等。

c3p0所需jar:c3p0-0.9.2.1.jar mchange-commons-java-0.2.3.4.jar

DBCP  

DBCP(DataBase connection pool),数据库连接池。是 apache 上的一个 java 连接池项目,也是 tomcat 使用的连接池组件。

使用dbcp需要2个包:commons-dbcp.jar,commons-pool.jar由于建立数据库连接是一个非常耗时耗资源的行为,所以通过连接池预先同数据库建立一些连接,放在内存中,应用程序需要建立数据库连接时直接到连接池中申请一个就行,用完后再放回去。

Proxool   

Proxool是一种Java数据库连接池技术。sourceforge下的一个开源项目,这个项目提供一个健壮、易用的连接池,最为关键的是这个连接池提供监控的功能,方便易用,便于发现连接泄漏的情况。

  Hibernate官方宣布由于Bug太多不再支持DBCP,而推荐使用 Proxool或C3P0。

  从性能和出错率来说,proxool稍微比前两种好些,但是使用者貌似较少。

  c3p0与dbcp区别

  dbcp没有自动回收空闲连接的功能

  c3p0有自动回收空闲连接功能

8. JNDI

NDI(Java Naming and Directory Interface),Java命名和目录接口,它对应于J2SE中的javax.naming包,这 套API的主要作用在于:它可以把Java对象放在一个容器中(JNDI容器),并为容器中的java对象取一个名称,以后程序想获得Java对象,只需 通过名称检索即可。其核心API为Context,它代表JNDI容器,其lookup方法为检索容器中对应名称的对象。

原文地址:https://www.cnblogs.com/xumaodun/p/4899822.html