jdbc相关知识点



Jdbc概述
Jdbc是什么:
Java Data Base Connectivity, java数据库连接。
Jdbc有什么用:
数据库的种类很多,而且可能还有新的数据库出现。这不同的数据库实现的机制不同,暴露给外部的调用方法也不同,如果java语言给每种数据库类型都提供一个接入的工具,那么java的工作量那就无法估计了,我们总说一句话就是:一流的公司做标准,二流的公司做技术,三流的公司做产品,四流的公司服务。那么作为一流的公司,他出了一套标准,也就是定义了接口方法,然后由各个厂商自己去实现接口,然后对于软件工程师来说只需要关注java提供的标准接口即可,在接入不同的数据库时使用不同的实现即可。简而言之,jdbc就是java程序用来执行sql语句的。
JDBC实际上是java定义的一套关于数据库操作的通用接口interface

Jdbc结构原理

顶层是我们java程序,项目业务代码.
第二层是java定义的标准接口api,里面是一些标准的操作数据库的方法。
第三层是java提供的数据库大管家。负责加载数据库驱动等等。
第四层是各个数据库厂商提供接口实现包
最后是我们的底层数据库软件
Jdbc有关的内容都在java.sql包下

ResultSet游标理解;

1.ORACLE数据库
Class.forName("oracle.jdbc.driver.OracleDriver").newInstance();
String url="jdbc:oracle:thin:@localhost:1521:orcl";
//orcl为数据库的SID
String user="test";
String password="test";
Connection conn= DriverManager.getConnection(url,user,password);
2、DB2数据库
Class.forName("com.ibm.db2.jdbc.app.DB2Driver ").newInstance();
String url="jdbc:db2://localhost:5000/sample";
//sample为你的数据库名
String user="admin";
String password="";
Connection conn= DriverManager.getConnection(url,user,password);
3、Sql Server7.0/2000数据库
Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver").newInstance();
String url="jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=mydb";
//mydb为数据库
String user="sa";
String password="";
Connection conn= DriverManager.getConnection(url,user,password);
4、Sybase数据库
Class.forName("com.sybase.jdbc.SybDriver").newInstance();
String url =" jdbc:sybase:Tds:localhost:5007/myDB";
//myDB为你的数据库名
Properties sysProps = System.getProperties();
SysProps.put("user","userid");
SysProps.put("password","user_password");
Connection conn= DriverManager.getConnection(url, SysProps);
5、Informix数据库
Class.forName("com.informix.jdbc.IfxDriver").newInstance();
String url =
"jdbc:informix-sqli://123.45.67.89:1533/myDB:INFORMIXSERVER=myserver;
user=testuser;password=testpassword";
//myDB为数据库名
Connection conn= DriverManager.getConnection(url);
6、MySQL数据库
Class.forName("org.gjt.mm.mysql.Driver").newInstance();
String url ="jdbc:mysql://localhost/myDB?user=soft&password=soft1234&useUnicod
e=true&characterEncoding=8859_1"
//myDB为数据库名
Connection conn= DriverManager.getConnection(url);
7、PostgreSQL数据库
Class.forName("org.postgresql.Driver").newInstance();
String url ="jdbc:postgresql://localhost/myDB"
//myDB为数据库名
String user="myuser";
String password="mypassword";
Connection conn= DriverManager.getConnection(url,user,password);


实现过程
1、加载JDBC驱动程序。
2、创建数据库的连接 。
3、创建一个Statement 。
4、执行SQL语句。
5、处理结果
6、关闭资源

查询方法:executeQuery
返回查询额结果集,遍历结果集取到我们的数据
使用类似游标的方式循环读取数据。
修改和删除:executeUpdate
返回影响的数据条数。
通用的方式:execute

Statement方式执行数据库sql
需要手动拼接sql语句,组装好sql语句之后执行。
PreparedStatement 方式执行数据库sql
指定参数,由statement来为我们拼接sql
事务

一个业务逻辑操作,需要一系列的数据库操作,要么这些动作完全执行,要么完全不执行。事务处理确保操作成功完成,(想想银行转账的例子)。
1.原子性:一件事有多个对数据库的操作,这些操作不可分割的,只要是成功就都成功,失败就都失败。
2.一致性:需要考虑数据库的约束要求,比如外键这些数据约束。
3.隔离性:事务与事务之间是隔离的,互不可见的。A事务对数据库的操作在提交之前B事务是看不到的。
4.持久性:事务一经提交就在数据库中生效,不能再回滚。

不自动提交:con.setAutoCommit(false);
提交事务:con.commit();
回滚:con.rollback();
当操作发生异常的时候,回滚所有对数据库的操作,主要是释放对数据库的锁。


当两个线程同时向一个账户转账
转账的动作是这样的
没有锁:Update 存款表 set 余额=之前的余+转账金额
这张执行两个线程会同时拿到一样之前的余额
当第一个线程执行Update 存款表 set 余额=之前的余+转账金额 这个条转账语句的时候,把账户余额已经修改。
但是第二个线程还是拿着当时拿到 老的余额(实际库里面的余额已经被增加)
他拿着老的余额执行这个转账动作 Update 存款表 set 余额=之前的余+转账金额
相当于第一个执行的动作白干了,
为了避免这种情况我们可以使用悲观锁,强制让他进行排他操作。我锁住账户之后别的线程你连读都读不到。
乐观锁:使用乐观锁是给账户加一个版本号。当两个线程同时拿到账户余额的还会拿到一个相同版本号,然后在执行转账的时候会判断我拿到的版本号和数据库里面版本号是否一致,如果一直允许修改,并且提高版本。


数据库锁
悲观锁
当我们使用悲观锁更新或删除一行数据表记录时,数据库会锁住整个一行,排他性地用于读操作和写操作,这能够确保这一行记录不会同时被其它用户锁住。
乐观锁
这样定义,假设有很少概率出现同时两个用户更新同样的记录,在这种情况下如果万一发生,提供一种健壮的检测方式。你可加入一个额外的列如版本号 "version"到数据表结构中,每次update-sql 语句执行时,附加条件"and version = X" 限制. 此外,每次你更新一行记录,你需要逐个增加版本号,以表明这行记录已经更新了。


封装自己的DbUtil
为了简化一些重复的代码,我们要对代码进行重构.根据我们的观察,获取Connection和后边的关闭资源都是固定的,那么我们可以把这些固定的代码部分抽取出来,总结归纳成方法,供其他方法调用,这样的好处是:减少了代码量,逻辑清晰,当需要改动时候不用改无数个方法。这就是代码重构的好处。
public class DBUtil {
/**
* 释放资源
* @param conn
* @param ps
*/
public static void releaseResouse(Connection conn,PreparedStatement ps){
if(conn!=null){
try {
conn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(ps!=null){
try {
ps.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}


/**
* 释放资源
* @param conn
* @param ps
*/
public static void releaseResouse(Connection conn,PreparedStatement ps,ResultSet rs){
if(conn!=null){
try {
conn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(ps!=null){
try {
ps.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(rs!=null){
try {
rs.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

}

/**
* 释放资源
* @param conn
* @param ps
*/
public static void releaseResouse(Connection conn,Statement statement){
if(conn!=null){
try {
conn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(statement!=null){
try {
statement.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}


/**
* 释放资源
* @param conn
* @param ps
*/
public static void releaseResouse(Connection conn,Statement statement,ResultSet rs){
if(conn!=null){
try {
conn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(statement!=null){
try {
statement.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

if(rs!=null){
try {
rs.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

}
}

数据库连接池
首先池是一个容器,池能盛放很多个东西,数据库连接池就是能盛放一堆数据库连接的一个容器。
数据库连接池,有什么用?
经观察我们打开Connection建立连接的过程是需要一段时间的,虽然对于人类感觉不到长,但是对于计算机程序来说是超长的,计算机里都是毫秒级的。那么我们使用预先建立一堆Connection的方式来避免这个动作带来时间延误。

装饰器设计模式
用另一个类来包装原始的类,为我们提供更方便,更强大的功能。棒子和狼牙棒。

自定义的数据库连接池
根据分析我们知道我们在一个DataSource中放一个List来存放Connection,当有程序想用到连接是,从list里面取出来,用完在放回去。频繁的存和取根据数据结构知识我们使用LinkedList来提高我们的效率。
实现过程:1.DataSource 里面有个连接池
2.定义增强型的Connection,修改close方法,不是真的关闭资源,而是将连接归还到池里。
public class MyConnection implements Connection{
private Connection conn;
public MyConnection(Connection conn){
this.conn = conn;
}

@Override
public void close() throws SQLException {
//增强原来的Connection 关闭时候不是直接关闭资源而是归还到资源池中
DataSource.releaseConnection(this.conn);
System.out.println("将资源归还到链接池中");
}
}

public class DataSource {
private static LinkedList<Connection> pool = new LinkedList<Connection>();
static{
try {
Class.forName("com.mysql.jdbc.Driver");
String urlLink = "jdbc:mysql://localhost:3306/mydata?useUnicode=true&characterEncoding=UTF-8";
String userName = "root";
String pwd = "mysql";
//一次性初始化10个链接
for(int i=0;i<20;i++){
Connection connT = DriverManager.getConnection(urlLink,userName,pwd);
MyConnection mc = new MyConnection(connT);
pool.add(mc);
}
} catch (Exception e) {
e.printStackTrace();
}

}
public static Connection getConnection(){
Connection conn = pool.getFirst();
pool.removeFirst();
return conn;
}
public static void releaseConnection(Connection conn) {
pool.add(conn);
}
}


别人做好的连接池
主流的链接池:dbcp,c3p0,BoneCP 。其中BoneCP性能比较好。
DBCP
知识点读取properties配置文件。
.Properties文件:是用来存放一些经常变化的一些配置信息,比如驱动类型,数据库链接地址,数据库用户名,密码,数据库连接池的配置信息。
Properties dbProperties = new Properties(); dbProperties.load(DBManager.class.getClassLoader()
.getResourceAsStream(configFile));
DBCP数据库连接池使用property配置文件来初始化:
driverClassName=com.jdbc.mysql.Driver
url=jdbc:mysql://localhost:3306/mydata?useUnicode=true&characterEncoding=UTF-8
username=root
password=mysql
initialSize=5//初始化连接个数
maxIdle=10
minIdle=5
maxActive=30
//获取dbcp 数据源
public static BasicDataSource getDbcpDataSource(){

Properties dbProperties = new Properties();
try {
dbProperties.load(DBUtil.class.getClassLoader()
.getResourceAsStream("dbcp.properties"));
BasicDataSource ds = BasicDataSourceFactory.createDataSource(dbProperties);
return ds;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}


C3P0
public static ComboPooledDataSource getC3p0DataSource(){
ComboPooledDataSource cpds =new ComboPooledDataSource(true);
return cpds;
}
<?xml version="1.0"encoding="UTF-8"?>
<c3p0-config>
<default-config>
<property name="initialPoolSize">5</property>
<property name="maxPoolSize">20</property>
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/mydata?useUnicode=true$amp;characterEncoding=UTF-8</property>
<property name="user">root</property>
<property name="password">mysql</property>
<property name="checkoutTimeout">30000</property>
<property name="idleConnectionTestPeriod">30</property>
<property name="initialPoolSize">10</property>
<property name="maxIdleTime">30</property>
<property name="maxPoolSize">100</property>
<property name="minPoolSize">10</property>
<property name="maxStatements">200</property>
</default-config>
</c3p0-config>

BoneCp连接池
public static BoneCP getBoneCpDataSource(){
try {
Class.forName("com.mysql.jdbc.Driver");
//设置连接池配置信息
BoneCPConfig config = new BoneCPConfig();
//数据库的JDBC URL
config.setJdbcUrl("jdbc:mysql://localhost:3306/mydata?useUnicode=true&characterEncoding=UTF-8");
//数据库用户名
config.setUsername("root");
//数据库用户密码
config.setPassword("mysql");
//数据库连接池的最小连接数
config.setMinConnectionsPerPartition(5);
//数据库连接池的最大连接数
config.setMaxConnectionsPerPartition(10);
//
config.setPartitionCount(1);
BoneCP connectionPool = new BoneCP(config);
return connectionPool;
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}

return null;
}


JavaBean:java豆
他是用来封装我们从现实业务中抽象出来的实体用的。一般javabean是指只有一些属性的贫血对象,Pojo。


Common- dbutil使用
Apache公司做的一个方便的数据库操作工具包,把我们从繁琐的connection中解脱出来,让我们更关注业务逻辑。
DBUtils提供了很多个ResultSetHandler接口的实现,这些实现已经基本够用了。
l MapHandler:单行处理器!把结果集转换成Map<String,Object>,其中列名为键!
l MapListHandler:多行处理器!把结果集转换成List<Map<String,Object>>;
l BeanHandler:单行处理器!把结果集转换成Bean,该处理器需要Class参数,即Bean的类型;
l BeanListHandler:多行处理器!把结果集转换成List<Bean>;
ScalarHandler:单行单列处理器!把结果集转换成Object。一般用于聚集查询,例如


QueryRunner qr = new QueryRunner(DBUtil.getC3p0DataSource());


java.lang.NullPointerException
当调用空对象的方法时,会抛出这个异常。Jdbc概述
Jdbc是什么:
Java Data Base Connectivity, java数据库连接。
Jdbc有什么用:
数据库的种类很多,而且可能还有新的数据库出现。这不同的数据库实现的机制不同,暴露给外部的调用方法也不同,如果java语言给每种数据库类型都提供一个接入的工具,那么java的工作量那就无法估计了,我们总说一句话就是:一流的公司做标准,二流的公司做技术,三流的公司做产品,四流的公司服务。那么作为一流的公司,他出了一套标准,也就是定义了接口方法,然后由各个厂商自己去实现接口,然后对于软件工程师来说只需要关注java提供的标准接口即可,在接入不同的数据库时使用不同的实现即可。简而言之,jdbc就是java程序用来执行sql语句的。
JDBC实际上是java定义的一套关于数据库操作的通用接口interface
 
Jdbc结构原理

顶层是我们java程序,项目业务代码.
第二层是java定义的标准接口api,里面是一些标准的操作数据库的方法。
第三层是java提供的数据库大管家。负责加载数据库驱动等等。
第四层是各个数据库厂商提供接口实现包
最后是我们的底层数据库软件
Jdbc有关的内容都在java.sql包下

ResultSet游标理解;
 
1.ORACLE数据库
   Class.forName("oracle.jdbc.driver.OracleDriver").newInstance();
    String url="jdbc:oracle:thin:@localhost:1521:orcl";
    //orcl为数据库的SID
    String user="test";
    String password="test";
    Connection conn= DriverManager.getConnection(url,user,password);
    2、DB2数据库
    Class.forName("com.ibm.db2.jdbc.app.DB2Driver ").newInstance();
    String url="jdbc:db2://localhost:5000/sample";
    //sample为你的数据库名
    String user="admin";
    String password="";
    Connection conn= DriverManager.getConnection(url,user,password);
    3、Sql Server7.0/2000数据库
    Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver").newInstance();
    String url="jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=mydb";
    //mydb为数据库
    String user="sa";
    String password="";
    Connection conn= DriverManager.getConnection(url,user,password);
    4、Sybase数据库
    Class.forName("com.sybase.jdbc.SybDriver").newInstance();
    String url =" jdbc:sybase:Tds:localhost:5007/myDB";
    //myDB为你的数据库名
    Properties sysProps = System.getProperties();
    SysProps.put("user","userid");
    SysProps.put("password","user_password");
    Connection conn= DriverManager.getConnection(url, SysProps);
    5、Informix数据库
    Class.forName("com.informix.jdbc.IfxDriver").newInstance();
    String url =
    "jdbc:informix-sqli://123.45.67.89:1533/myDB:INFORMIXSERVER=myserver;
    user=testuser;password=testpassword";
    //myDB为数据库名
    Connection conn= DriverManager.getConnection(url);
    6、MySQL数据库
    Class.forName("org.gjt.mm.mysql.Driver").newInstance();
    String url ="jdbc:mysql://localhost/myDB?user=soft&password=soft1234&useUnicod
    e=true&characterEncoding=8859_1"
    //myDB为数据库名
    Connection conn= DriverManager.getConnection(url);
    7、PostgreSQL数据库
    Class.forName("org.postgresql.Driver").newInstance();
    String url ="jdbc:postgresql://localhost/myDB"
    //myDB为数据库名
    String user="myuser";
    String password="mypassword";
    Connection conn= DriverManager.getConnection(url,user,password);
 
 
实现过程
1、加载JDBC驱动程序。
2、创建数据库的连接 。
3、创建一个Statement 。
4、执行SQL语句。
5、处理结果
6、关闭资源
 
查询方法:executeQuery
返回查询额结果集,遍历结果集取到我们的数据
使用类似游标的方式循环读取数据。
修改和删除:executeUpdate
返回影响的数据条数。
通用的方式:execute
 
Statement方式执行数据库sql
需要手动拼接sql语句,组装好sql语句之后执行。
PreparedStatement 方式执行数据库sql
指定参数,由statement来为我们拼接sql
事务
 
一个业务逻辑操作,需要一系列的数据库操作,要么这些动作完全执行,要么完全不执行。事务处理确保操作成功完成,(想想银行转账的例子)。
1.原子性:一件事有多个对数据库的操作,这些操作不可分割的,只要是成功就都成功,失败就都失败。
2.一致性:需要考虑数据库的约束要求,比如外键这些数据约束。
3.隔离性:事务与事务之间是隔离的,互不可见的。A事务对数据库的操作在提交之前B事务是看不到的。
4.持久性:事务一经提交就在数据库中生效,不能再回滚。
 
不自动提交:con.setAutoCommit(false);
提交事务:con.commit();
回滚:con.rollback();
当操作发生异常的时候,回滚所有对数据库的操作,主要是释放对数据库的锁。

 
当两个线程同时向一个账户转账
转账的动作是这样的
没有锁:Update 存款表 set 余额=之前的余+转账金额
这张执行两个线程会同时拿到一样之前的余额
当第一个线程执行Update 存款表 set 余额=之前的余+转账金额 这个条转账语句的时候,把账户余额已经修改。
但是第二个线程还是拿着当时拿到 老的余额(实际库里面的余额已经被增加)
他拿着老的余额执行这个转账动作 Update 存款表 set 余额=之前的余+转账金额
相当于第一个执行的动作白干了,
为了避免这种情况我们可以使用悲观锁,强制让他进行排他操作。我锁住账户之后别的线程你连读都读不到。
乐观锁:使用乐观锁是给账户加一个版本号。当两个线程同时拿到账户余额的还会拿到一个相同版本号,然后在执行转账的时候会判断我拿到的版本号和数据库里面版本号是否一致,如果一直允许修改,并且提高版本。
 
 
数据库锁
悲观锁
当我们使用悲观锁更新或删除一行数据表记录时,数据库会锁住整个一行,排他性地用于读操作和写操作,这能够确保这一行记录不会同时被其它用户锁住。
乐观锁
这样定义,假设有很少概率出现同时两个用户更新同样的记录,在这种情况下如果万一发生,提供一种健壮的检测方式。你可加入一个额外的列如版本号 "version"到数据表结构中,每次update-sql 语句执行时,附加条件"and version = X" 限制. 此外,每次你更新一行记录,你需要逐个增加版本号,以表明这行记录已经更新了。
 
 
封装自己的DbUtil
为了简化一些重复的代码,我们要对代码进行重构.根据我们的观察,获取Connection和后边的关闭资源都是固定的,那么我们可以把这些固定的代码部分抽取出来,总结归纳成方法,供其他方法调用,这样的好处是:减少了代码量,逻辑清晰,当需要改动时候不用改无数个方法。这就是代码重构的好处。
public class DBUtil { 
    /**
     * 释放资源
     * @param conn
     * @param ps
     */
    public static void releaseResouse(Connection conn,PreparedStatement ps){
        if(conn!=null){
            try {
                conn.close();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        if(ps!=null){
            try {
                ps.close();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
  
 
    /**
     * 释放资源
     * @param conn
     * @param ps
     */
    public static void releaseResouse(Connection conn,PreparedStatement ps,ResultSet rs){
        if(conn!=null){
            try {
                conn.close();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        if(ps!=null){
            try {
                ps.close();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        if(rs!=null){
            try {
                rs.close();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        } 
      
    }
  
    /**
     * 释放资源
     * @param conn
     * @param ps
     */
    public static void releaseResouse(Connection conn,Statement statement){
        if(conn!=null){
            try {
                conn.close();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        if(statement!=null){
            try {
                statement.close();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
  
  
    /**
     * 释放资源
     * @param conn
     * @param ps
     */
    public static void releaseResouse(Connection conn,Statement statement,ResultSet rs){
        if(conn!=null){
            try {
                conn.close();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        if(statement!=null){
            try {
                statement.close();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
      
        if(rs!=null){
            try {
                rs.close();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
      
    }
}
 
数据库连接池
首先池是一个容器,池能盛放很多个东西,数据库连接池就是能盛放一堆数据库连接的一个容器。
数据库连接池,有什么用?
经观察我们打开Connection建立连接的过程是需要一段时间的,虽然对于人类感觉不到长,但是对于计算机程序来说是超长的,计算机里都是毫秒级的。那么我们使用预先建立一堆Connection的方式来避免这个动作带来时间延误。

装饰器设计模式
用另一个类来包装原始的类,为我们提供更方便,更强大的功能。棒子和狼牙棒。
 
自定义的数据库连接池
根据分析我们知道我们在一个DataSource中放一个List来存放Connection,当有程序想用到连接是,从list里面取出来,用完在放回去。频繁的存和取根据数据结构知识我们使用LinkedList来提高我们的效率。
实现过程:1.DataSource  里面有个连接池
2.定义增强型的Connection,修改close方法,不是真的关闭资源,而是将连接归还到池里。
public class MyConnection implements Connection{
     private Connection conn;
     public MyConnection(Connection conn){
         this.conn = conn;
     }
   
     @Override
     public void close() throws SQLException {
         //增强原来的Connection 关闭时候不是直接关闭资源而是归还到资源池中
         DataSource.releaseConnection(this.conn);
         System.out.println("将资源归还到链接池中");
     }
}
 
public class DataSource { 
    private static LinkedList<Connection> pool = new LinkedList<Connection>();
    static{
        try {
            Class.forName("com.mysql.jdbc.Driver");
            String urlLink = "jdbc:mysql://localhost:3306/mydata?useUnicode=true&characterEncoding=UTF-8";
            String userName = "root";
            String pwd = "mysql";
            //一次性初始化10个链接
            for(int i=0;i<20;i++){
                Connection connT = DriverManager.getConnection(urlLink,userName,pwd);
                MyConnection mc = new MyConnection(connT);
                pool.add(mc);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
      
    } 
    public static Connection getConnection(){
        Connection conn = pool.getFirst();
        pool.removeFirst();
        return conn;
    } 
    public static void releaseConnection(Connection conn) {
        pool.add(conn);
    }
}
 
 
别人做好的连接池
主流的链接池:dbcp,c3p0,BoneCP 。其中BoneCP性能比较好。
DBCP
知识点读取properties配置文件。
.Properties文件:是用来存放一些经常变化的一些配置信息,比如驱动类型,数据库链接地址,数据库用户名,密码,数据库连接池的配置信息。
Properties dbProperties = new Properties();      dbProperties.load(DBManager.class.getClassLoader()
                    .getResourceAsStream(configFile));
DBCP数据库连接池使用property配置文件来初始化:
driverClassName=com.jdbc.mysql.Driver
url=jdbc:mysql://localhost:3306/mydata?useUnicode=true&characterEncoding=UTF-8
username=root
password=mysql
initialSize=5//初始化连接个数
maxIdle=10
minIdle=5
maxActive=30
//获取dbcp 数据源
public static BasicDataSource  getDbcpDataSource(){
       
         Properties dbProperties = new Properties(); 
         try {
              dbProperties.load(DBUtil.class.getClassLoader()
                      .getResourceAsStream("dbcp.properties"));
              BasicDataSource ds = BasicDataSourceFactory.createDataSource(dbProperties);
              return ds;
         } catch (Exception e) {
              e.printStackTrace();
              return null;
         }      
     }
 
 
C3P0
public static ComboPooledDataSource getC3p0DataSource(){
        ComboPooledDataSource cpds =new ComboPooledDataSource(true); 
        return cpds;
}
<?xml version="1.0"encoding="UTF-8"?>
<c3p0-config>
    <default-config>
       <property name="initialPoolSize">5</property>
       <property name="maxPoolSize">20</property>
       <property name="driverClass">com.mysql.jdbc.Driver</property>
       <property name="jdbcUrl">jdbc:mysql://localhost:3306/mydata?useUnicode=true$amp;characterEncoding=UTF-8</property>
       <property name="user">root</property>
       <property name="password">mysql</property>
       <property name="checkoutTimeout">30000</property>
       <property name="idleConnectionTestPeriod">30</property>
       <property name="initialPoolSize">10</property>
       <property name="maxIdleTime">30</property>
       <property name="maxPoolSize">100</property>
       <property name="minPoolSize">10</property>
       <property name="maxStatements">200</property>
    </default-config>
</c3p0-config>
 
BoneCp连接池
public static BoneCP getBoneCpDataSource(){
           try {
                 Class.forName("com.mysql.jdbc.Driver");
                 //设置连接池配置信息
              BoneCPConfig config = new BoneCPConfig();
              //数据库的JDBC URL
              config.setJdbcUrl("jdbc:mysql://localhost:3306/mydata?useUnicode=true&characterEncoding=UTF-8"); 
              //数据库用户名
              config.setUsername("root"); 
              //数据库用户密码
              config.setPassword("mysql");
              //数据库连接池的最小连接数
              config.setMinConnectionsPerPartition(5);
              //数据库连接池的最大连接数
              config.setMaxConnectionsPerPartition(10);
              //
              config.setPartitionCount(1);
              BoneCP connectionPool = new BoneCP(config);
                 return connectionPool;
           } catch (Exception e1) {
                 // TODO Auto-generated catch block
                 e1.printStackTrace();
           }
      
           return null;
      }
 
 
JavaBean:java豆
他是用来封装我们从现实业务中抽象出来的实体用的。一般javabean是指只有一些属性的贫血对象,Pojo。
 
 
Common- dbutil使用
Apache公司做的一个方便的数据库操作工具包,把我们从繁琐的connection中解脱出来,让我们更关注业务逻辑。
DBUtils提供了很多个ResultSetHandler接口的实现,这些实现已经基本够用了。
l MapHandler:单行处理器!把结果集转换成Map<String,Object>,其中列名为键!
l MapListHandler:多行处理器!把结果集转换成List<Map<String,Object>>;
l BeanHandler:单行处理器!把结果集转换成Bean,该处理器需要Class参数,即Bean的类型;
l BeanListHandler:多行处理器!把结果集转换成List<Bean>;
 ScalarHandler:单行单列处理器!把结果集转换成Object。一般用于聚集查询,例如
 
 
QueryRunner qr = new QueryRunner(DBUtil.getC3p0DataSource());
 
 
java.lang.NullPointerException
当调用空对象的方法时,会抛出这个异常。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值