本文主要关于java连接不同库的操作
一.JDBC
最简单的入门demo
public void demo1() throws SQLException{
// 1.加载驱动
DriverManager.registerDriver(new Driver());
// 2.获得连接.
Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/web017", "root", "123");
// 3.编写SQL并且执行SQL.
String sql = "select * from user";
Statement statement = connection.createStatement();
// 结果集:查询后的数据的封装.
ResultSet rs = statement.executeQuery(sql);
// 遍历:
while(rs.next()){
int id = rs.getInt("id");
String username = rs.getString("username");
String password = rs.getString("password");
System.out.println(id+" "+username+" "+password);
}
// 4.释放资源.
rs.close();
statement.close();
connection.close();
}
1.DriverManager:驱动的管理类.
一、注册驱动:(加载驱动)
registerDriver(Driver driver); //普通方式
但是在实际开发中很少使用registerDriver注册驱动?
1.使用这个方法注册驱动,使程序依赖了具体的驱动.
import com.mysql.jdbc.Driver;
2.这个方法会导致驱动被注册两次:
//---查看Driver类的源码.
//查看源码可以看到:在静态代码块中注册了驱动.
//静态代码块何时执行?--------------在类加载的时候.
static {
try {
java.sql.DriverManager.registerDriver(new Driver());
} catch (SQLException E) {
throw new RuntimeException("Can't register driver!");
}
}
解决这两个问题:
--使用反射的方式获得:
MySql驱动:Class.forName("com.mysql.jdbc.Driver");
Oracle驱动:Class.forName("oracle.jdbc.driver.OracleDriver");
二、获得连接:
getConnection(String url,String username,String password);
url :数据库连接的路径.
username :连接数据库用户名.
password :连接数据库密码.
//url的写法:
jdbc:mysql://localhost:3306/web017
jdbc :连接数据库协议.
mysql :JDBC协议的一个子协议.
localhost :数据库服务器主机名.
3306 :mysql数据库服务器的端口号.
web017 :数据库名称.
url简写为 :jdbc:mysql//localhost:3306/web017默认连接本地的mysql服务器默认的端口号3306.
简写 :jdbc:mysql:///web017
2.Connection:连接对象.
Connection由DriverManager创建的.代表的是一个连接的对象.
主要有两个作用:
一、创建执行SQL语句的对象.
Statement createStatement(int resultSetType, int resultSetConcurrency)//创建Statement.
PreparedStatement prepareStatement(String sql)//创建PreparedStatement,对SQL进行预编译.
CallableStatement prepareCall(String sql)//创建CallableStatement.用来执行数据库中存储过程.
二、进行事务的管理:
void setAutoCommit(boolean autoCommit)//设置事务不自动提交.
void commit()//事务提交.
void rollback()//事务回滚.
3.Statement:执行SQL的对象.
Statement对象由Connection对象创建的.代表是可以运行SQL的类.
主要有两个作用:
一、执行SQL语句.
ResultSet executeQuery(String sql)
//执行查询语句.
//执行select语句.返回了一个ResultSet对象.
//代表查询结果的表格数据.
int executeUpdate(String sql)
//执行更新语句.
//执行update、insert、delete语句的时候.返回int类型数据.
//int类型的数据代表的是影响的行数.
boolean excute(String sql)
//执行SQL语句.
//执行select、insert、update、delete语句.返回的是boolean值.
//如果返回的结果为ResultSet.那么boolean值为true.如果返回的是更新的记录数.那么boolean就为false.
二、执行批处理.
void addBatch(String sql)
//将SQL添加到批处理中.
void cleatBatch()
//清空批处理.
int[] executeBatch()
//执行批处理.
4.ResultSet:结果集.
ResultSet对象由Statement对象中executeQuery(String sql);
返回的.ResultSet对象代表的是select查询后的结果.
在ResultSet内部维护了一个指向表格数据行的游标Cursor,初始化时候,游标在第一行之前的位置.
调用ResultSet中next()方法.可以使游标指向具体的数据行,进而调用方法获得该行的数据.
//方法:
boolean next()// 向下移动光标.
//获得结果集中整形数据.
int getInt(int columnIndex)
int getInt(String columnLabel)
//获得结果集中字符串类型的数据.
String getString(int columnIndex)
String getString(String columnLabel)
//获得结果集中Object 类型的数据.
Object getObject(int columnIndex)
Object getObject(String columnLabel)
//遍历结果集:
while(rs.next()){
int id = rs.getInt("id");
String username = rs.getString("username");
String password = rs.getString("password");
System.out.println(id+" "+username+" "+password);
}
//获得结果集中的数据:
int id = rs.getInt("id");
String username = rs.getString("username");
String password = rs.getString("password");
//如果结果集中只有一条记录:
if(rs.next()){
...
}
5.滚动结果集
结果集默认的情况下只能向下而且不可以在结果集上进行修改记录.
* MYSQL数据库结果集可以滚动.
* 在Statement被创建的时候:
Statement createStatement(int resultSetType,int resultSetConcurrency);
// resultSetType :结果集类型
// TYPE_FORWARD_ONLY :结果集只能向下.
// TYPE_SCROLL_INSENSITIVE :结果集可以滚动.不允许进行修改结果集
// TYPE_SCROLL_SENSITIVE :结果集可以滚动.允许在修改结果集.
// resultSetConCurrency :结果集并发策略.
// CONCUR_READ_ONLY :结果集不可以修改
// CONCUR_UPDATABLE :结果集可以修改.
// 组合:
// TYPE_FORWARD_ONLY CONCUR_READ_ONLY :结果集只能向下而且不可以进行修改.(默认值)
// TYPE_SCROLL_INSENSITIVE CONCUR_READ_ONLY :结果集可以滚动,但是不可以修改结果集.
// TYPE_SCROLL_SENSITIVE CONCUR_UPDATABLE :结果集可以滚动,而且可以修改结果集.
案例
public void demo2() throws ClassNotFoundException, SQLException {
// 1.加载驱动
Class.forName("com.mysql.jdbc.Driver");
// 2.获得连接
Connection conn = DriverManager.getConnection("jdbc:mysql:///web017","root", "123");
// 3.执行SQL.
String sql = "select * from user";
Statement stmt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);
ResultSet rs = stmt.executeQuery(sql);
// 直接定位到某一行:
rs.absolute(3);
rs.updateString("username", "eee");
rs.updateRow();
// 4.释放资源
rs.close();
stmt.close();
conn.close();
}
6.资源释放:
资源的释放是非常重要,我们写的资源释放的代码,是非常不规范!!!
尤其Connection对象是非常稀有!代表的是数据库连接对象.安装MYSQL的数据库时候,MYSQL有最大连接数量.
如果达到MYSQL的最大连接数量,而且Connection都没有被释放.其他人连接不到数据库.
如果Connection不能及时,正确关闭.极易导致系统宕机.
Connection的使用原则:尽量要晚创建,尽量早释放!!!
为了确保释放的代码能够得到执行,资源释放的代码一定要放在finally代码块.
资源释放的一段标准代码:
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
rs = null; // 为了让JVM垃圾回收更早回收该对象.
}
if (stmt != null) {
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
stmt = null;
}
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
conn = null;
}
二.JDBCUtils
JDBC工具类的抽取:
ClassLoader getClassLoader() //返回该类的类加载器。
InputStream getResourceAsStream(String name) //返回读取指定资源的输入流。
String getProperty(String key) //用指定的键在此属性列表中搜索属性。
void load(InputStream inStream) //从输入流中读取属性列表(键和元素对)。
static ResourceBundle getBundle(String baseName)
//使用指定的基本名称、默认的语言环境和调用者的类加载器获取资源包。
String getString(String key)
//从此资源包或它的某个父包中获取给定键的字符串。
public class JDBCUtils {
private static final String DRIVERCLASS;
private static final String URL;
private static final String USERNAME;
private static final String PASSWORD;
static {
// 解析属性文件:Properties.
Properties properties = new Properties();
// 获得代表属性文件的输入流:
// 使用类的加载器获得属性文件的输入流:
InputStream is = JDBCUtils.class.getClassLoader().getResourceAsStream("jdbc.properties");
// 加载属性文件:
try {
properties.load(is);
} catch (IOException e) {
e.printStackTrace();
}
DRIVERCLASS = properties.getProperty("jdbc.driverClass");
URL = properties.getProperty("jdbc.url");
USERNAME = properties.getProperty("jdbc.username");
PASSWORD = properties.getProperty("jdbc.password");
}
/**
* 注册驱动的方法:
*/
public static void loadDriver() {
try {
Class.forName(DRIVERCLASS);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
/**
* 获得连接的方法
*/
public static Connection getConnection() {
Connection conn = null;
try {
// 加载驱动
loadDriver();
conn = DriverManager.getConnection(URL, USERNAME, PASSWORD);
} catch (Exception e) {
e.printStackTrace();
}
return conn;
}
/**
* 释放资源的代码
*/
public static void release(Statement stmt, Connection conn) {
if (stmt != null) {
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
stmt = null;
}
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
conn = null;
}
}
public static void release(ResultSet rs, Statement stmt, Connection conn) {
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
rs = null;
}
if (stmt != null) {
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
stmt = null;
}
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
conn = null;
}
}
}
三.JDBC连接池
一.DBCP:DataBase connection pool
1.什么是DBCP:
DBCP:DBCP(DataBase connection pool),数据库连接池。
是 apache 上的一个 java 连接池项目,也是 tomcat 使用的连接池组件。
单独使用dbcp需要2个包:commons-dbcp.jar,commons-pool.jar
由于建立数据库连接是一个非常耗时耗资源的行为,所以通过连接池预先同数据库建立一些连接,
放在内存中,应用程序需要建立数据库连接时直接到连接池中申请一个就行,用完后再放回去。
2.使用DBCP
//步骤一:下载DBCP的开发包.
commons-dbcp-1.4.jar
commons-pool-1.5.6.jar
//步骤二:了解DBCP的核心API:
BasicDataSource //用于手动配置DBCP连接池.
BasicDataSourceFactory //使用配置文件的方式配置连接池.
3.手动方式配置连接池:
@Test
/**
* DBCP的测试类:
* 手动方式配置连接池:
*/
public void demo1() {
Connection conn = null;
PreparedStatement stmt = null;
ResultSet rs = null;
try {
// 创建连接池:
BasicDataSource dataSource = new BasicDataSource();
// 手动设置参数:
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql:///web018");
dataSource.setUsername("root");
dataSource.setPassword("123");
// 获得连接:
conn = dataSource.getConnection();
// 编写SQL:
String sql = "select * from account";
// 预编译SQL:
stmt = conn.prepareStatement(sql);
// 执行SQL:
rs = stmt.executeQuery();
// 遍历结果集:
while (rs.next()) {
System.out.println(rs.getInt("id") + " "
+ rs.getString("name") + " " + rs.getDouble("money"));
}
} catch (Exception e) {
e.printStackTrace();
} finally {
JDBCUtils.release(rs, stmt, conn);
}
}
4.通过配置文件的方式配置连接池:
//步骤一:在src下提供一个属性文件:dbcp.properties
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql:///web018
username=root
password=123
//步骤二:使用DBCP的连接池:
@Test
/**
* DBCP的测试类:
* * 测试配置文件的方式配置连接池
*/
public void demo2() {
Connection conn = null;
PreparedStatement stmt = null;
ResultSet rs = null;
try {
// 创建属性文件对象
Properties properties = new Properties();
// 获得代表属性文件的输入流;
InputStream is = DBCPDemo1.class.getClassLoader()
.getResourceAsStream("dbcp.properties");
properties.load(is);
// 创建连接池:
DataSource dataSource = BasicDataSourceFactory
.createDataSource(properties);
// 获得连接:
conn = dataSource.getConnection();
// 编写SQL:
String sql = "select * from account";
// 预编译SQL:
stmt = conn.prepareStatement(sql);
// 执行SQL:
rs = stmt.executeQuery();
// 遍历结果集:
while (rs.next()) {
System.out.println(rs.getInt("id") + " "
+ rs.getString("name") + " " + rs.getDouble("money"));
}
} catch (Exception e) {
e.printStackTrace();
} finally {
JDBCUtils.release(rs, stmt, conn);
}
}
二.C3P0:
1.什么是C3P0:
C3P0是一个开源的JDBC连接池,它实现了数据源和JNDI绑定,支持JDBC3规范和JDBC2的标准扩展。
目前使用它的开源项目有Hibernate,Spring等。
2.使用C3P0连接池:
//步骤一:下载C3P0开发包:
c3p0-0.9.1.2.jar
//步骤二:了解C3P0的API:
ComboPooledDataSource
3.手动方式配置C3P0连接池:
@Test
/**
* 手动配置C3P0连接池:
*/
public void demo1() {
Connection conn = null;
PreparedStatement stmt = null;
ResultSet rs = null;
try {
// 创建连接池:
ComboPooledDataSource dataSource = new ComboPooledDataSource();
// 设置连接池的基本参数:
dataSource.setDriverClass("com.mysql.jdbc.Driver");
dataSource.setJdbcUrl("jdbc:mysql:///web018");
dataSource.setUser("root");
dataSource.setPassword("123");
// 获得连接:
conn = dataSource.getConnection();
// 编写SQL:
String sql = "select * from account";
// 预编译SQL:
stmt = conn.prepareStatement(sql);
// 执行SQL;
rs = stmt.executeQuery();
while (rs.next()) {
System.out
.println(rs.getInt("id") + " " + rs.getString("name")
+ " " + rs.getDouble("money"));
}
} catch (Exception e) {
e.printStackTrace();
} finally {
JDBCUtils.release(rs, stmt, conn);
}
}
4.配置文件的方式配置C3P0连接池:
@Test
/**
* 配置文件的方式配置C3P0连接池:
*/
public void demo2(){
Connection conn = null;
PreparedStatement stmt = null;
ResultSet rs = null;
try {
// 创建连接池:
ComboPooledDataSource dataSource = new ComboPooledDataSource();
// 获得连接:
conn = dataSource.getConnection();
// 编写SQL:
String sql = "select * from account";
// 预编译SQL:
stmt = conn.prepareStatement(sql);
// 执行SQL;
rs = stmt.executeQuery();
while (rs.next()) {
System.out
.println(rs.getInt("id") + " " + rs.getString("name")
+ " " + rs.getDouble("money"));
}
} catch (Exception e) {
e.printStackTrace();
} finally {
JDBCUtils.release(rs, stmt, conn);
}
}
5.使用C3P0连接池改造JDBC的工具类:
public class JDBCUtils2 {
private static ComboPooledDataSource dataSource = new ComboPooledDataSource();
/**
* 获得连接的方法
*/
public static Connection getConnection(){
Connection conn = null;
try {
conn = dataSource.getConnection();
} catch (SQLException e) {
e.printStackTrace();
}
return conn;
}
/**
* 提供释放资源的方法
*/
public static void release(Statement stmt, Connection conn) {
if (stmt != null) {
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
stmt = null;
}
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
conn = null;
}
}
public static void release(ResultSet rs, Statement stmt, Connection conn) {
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
rs = null;
}
if (stmt != null) {
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
stmt = null;
}
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
conn = null;
}
}
}
三.JNDI:
1.什么是JNDI:
JNDI(Java Naming and Directory Interface,Java命名和目录接口)
是SUN公司提供的一种标准的Java命名系统接口,JNDI提供统一的客户端API,
通过不同的访问提供者接口JNDI服务供应接口(SPI)的实现,由管理者将JNDI API映射
为特定的命名服务和目录系统,使得Java应用程序可以和这些命名服务和目录服务之间进行交互。
将一个对象与一个名称进行绑定,通过名称查找到指定的对象.
2.Tomcat内置连接池:
需要进行一个配置:配置一个<Context>标签.完成一个类与名称的绑定.
<Context>标签配置的位置:
tomcat/conf/context.xml --- 配置连接池.可以被tomcat下的所有虚拟主机和所有的虚拟路径访问.
tomcat/conf/Catalina/localhost/context.xml --- 配置连接池.可以tomcat下的localhost虚拟主机下的所有应用访问.
工程/META-INF/context.xml --- 配置连接池.只能够被当前的工程所访问.
3. 配置JNDI连接池:
步骤一:配置context.xml.在META-INF/context.xml
<Context>
<Resource name="jdbc/EmployeeDB" auth="Container"
type="javax.sql.DataSource" username="root" password="123"
driverClassName="com.mysql.jdbc.Driver" url="jdbc:mysql:///web018"
maxActive="8" maxIdle="4"/>
</Context>
步骤二:连接池由Tomcat服务器进行维护的.启动Tomcat的时候,需要获得连接.需要创建连接池.能够获得MYSQL驱动.需要将MYSQL驱动交给Tomcat进行管理.
- 需要将mysql的驱动包copy到tomcat/lib
步骤三:定义个能够运行在Tomcat内部的类访问到连接池:
- Servlet!!!
public class JNDIServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
Connection conn = null;
PreparedStatement stmt = null;
ResultSet rs = null;
try {
Context initCtx = new InitialContext();
Context envCtx = (Context) initCtx.lookup("java:comp/env");
// 通过名称查询类对象.
DataSource dataSource = (DataSource) envCtx
.lookup("jdbc/EmployeeDB");
conn = dataSource.getConnection();
// 编写SQL
String sql = "select * from account";
// 预编译SQL
stmt = conn.prepareStatement(sql);
// 执行SQL:
rs = stmt.executeQuery();
// 遍历结果集:
while (rs.next()) {
System.out.println(rs.getInt("id") + " "
+ rs.getString("name") + " " + rs.getDouble("money"));
}
} catch (Exception e) {
e.printStackTrace();
}finally{
JDBCUtils2.release(rs, stmt, conn);
}
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
四.PhoenixUtils
PhoenixUtils是Java用Phoenix的客户端连接数据库Hbase的工具类,主要内容和JDBCUtils相似.
DataSchedule.properties文件内容
phoenixDriver=org.apache.phoenix.jdbc.PhoenixDriver
phoenixZookeeper=jdbc:phoenix:node1,node2,node4:2181
工具类
package cn.gilight.utils;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.sql.Connection;
import java.sql.DriverManager;
import java.util.Properties;
import org.apache.log4j.Logger;
import org.apache.phoenix.jdbc.PhoenixConnection;
import org.apache.phoenix.jdbc.PhoenixDriver;
public class PhoenixUtils {
private static Logger logger = Logger.getLogger(PhoenixUtils.class);
private static String connectionString = null;
private static String dirverClass = null;
static {
try {
Properties prop = new Properties();
InputStream is = PhoenixUtils.class.getClassLoader().getResourceAsStream("DataSchedule.properties");
prop.load(is);
connectionString = prop.getProperty("phoenixZookeeper");
dirverClass = prop.getProperty("phoenixDriver");
} catch (IOException e) {
e.printStackTrace();
}
}
public static Connection getConnection() throws Throwable {
Class.forName(dirverClass);
return DriverManager.getConnection(connectionString);
}
public static PhoenixConnection getPhoenixConnection() throws Throwable {
Class.forName(dirverClass);
logger.info("phoenix connection " + connectionString);
return (PhoenixConnection) PhoenixDriver.INSTANCE.connect(connectionString, null);
}
}