今天,接着上一篇( mysql 数据库 )的基础上,我就写一下 Java 怎样连接数据库,并且操作数据库。

  首先,我们先来准备一下数据库连接的驱动:

  mysql 的 jar 包下载地址:https://dev.mysql.com/downloads/connector/j/

  Oracle 的 jar 包下载地址:https://www.oracle.com/technetwork/cn/middleware/goldengate/downloads/index.html

  本文章还用到 c3p0 的数据库连接池

  c3p0 的 jar 包下载地址:https://sourceforge.net/projects/c3p0/

  接下来,我们就开始正式了解一下什么是 JDBC ,用 Java 怎样连接数据库,并且怎样操作数据库。

什么是JDBC

  JDBC(Java DataBase Connectivity,java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java语言编写的类和接口组成。JDBC提供了一种基准,据此可以构建更高级的工具和接口,使数据库开发人员能够编写数据库应用程序。

数据库驱动

  我们安装好数据库之后,我们的应用程序也是不能直接使用数据库的,必须要通过相应的数据库驱动程序,通过驱动程序去和数据库打交道。其实也就是数据库厂商的JDBC接口实现,即对Connection等接口的实现类的jar文件。

Driver接口

  Driver接口由数据库厂家提供,作为java开发人员,只需要使用Driver接口就可以了。在编程中要连接数据库,必须先装载特定厂商的数据库驱动程序,不同的数据库有不同的装载方法。如:

  装载MySql驱动:Class.forName("com.mysql.jdbc.Driver");

  装载Oracle驱动:Class.forName("oracle.jdbc.driver.OracleDriver");

Connection接口

  Connection与特定数据库的连接(会话),在连接上下文中执行sql语句并返回结果。DriverManager.getConnection(url, user, password)方法建立在JDBC URL中定义的数据库Connection连接上。

  连接MySql数据库:Connection conn = DriverManager.getConnection("jdbc:mysql://host:port/database", "user", "password");

  连接Oracle数据库:Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@host:port:database", "user", "password");

  连接SqlServer数据库:Connection conn = DriverManager.getConnection("jdbc:microsoft:sqlserver://host:port; DatabaseName=database", "user", "password");

  常用方法:

    • createStatement():创建向数据库发送sql的statement对象。
    • prepareStatement(sql) :创建向数据库发送预编译sql的PrepareSatement对象。
    • prepareCall(sql):创建执行存储过程的callableStatement对象。
    • setAutoCommit(boolean autoCommit):设置事务是否自动提交。
    • commit() :在链接上提交事务。
    • rollback() :在此链接上回滚事务。

使用JDBC的步骤

  加载JDBC驱动程序 → 建立数据库连接Connection → 创建执行SQL的语句Statement → 处理执行结果ResultSet → 释放资源

初始化驱动

  通过初始化驱动类com.mysql.jdbc.Driver,该类就在 mysql-connector-java-5.0.8-bin.jar中。如果你使用的是oracle数据库那么该驱动类将不同。

//加载数据库驱动程序(对应的 Driver 实现类中有注册驱动的静态代码块.)
String driver ="com.mysql.jdbc.Driver";
Class.forName(driver);

建立JDBC和数据库之间的Connection连接

//通过 DriverManager 的 getConnection() 方法获取数据库连接.
Connection conn = DriverManager.getConnection(url,user,password);

这里需要提供:url包括以下(jdbc:mysql://ip地址:端口号/需要连接的数据库名字),例如:jdbc:mysql://localhost:3306/db_database05

       数据库所处于的ip:127.0.0.1 (这里是本机,如果连接其他电脑上的数据库,请改变该ip)
                         数据库的端口号: 3306 (mysql专用端口号)
                         数据库名称: (根据你自己数据库中的名称填写)

       数据库连接的用户名:user

       数据库的登录密码:password

创建数据库连接的工具方法

/*
* 数据库连接工具类
*/
package com.hzc.util; import java.sql.Connection;
import java.sql.DriverManager; public class DataBaseUtil {
/**
* 获取数据库连接
* @return Connection 对象
*/
public static Connection getConnection(){
Connection conn = null;
try {
Class.forName("com.mysql.jdbc.Driver");
String url = "jdbc:mysql://localhost:3306/db_database05";
conn = DriverManager.getConnection(url,user,password);    //这里的user和password根据自己的数据库登录和密码填写
} catch (Exception e) {
e.printStackTrace();
}
return conn;
}
/**
* 关闭数据库连接
* @param conn Connection 对象
*/
public static void closeConnection(Connection conn){
//判断 conn 是否为空
if(conn != null){
try {
conn.close(); //关闭数据库连接
} catch (Exception e) {
e.printStackTrace();
}
}
}
}

  这里在提供 c3p0 数据库连接池的方法

C3P0 数据库连接池

package jdbc;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement; import javax.sql.DataSource; import com.mchange.v2.c3p0.ComboPooledDataSource; /*
* 操作JDBC的工具类,其中封装了一些工具方法
*/
public class JDBCTools { private static DataSource dataSource = null;
//数据库连接池应只初始化一次
static{
dataSource = new ComboPooledDataSource("helloc3p0");
} //数据库连接:通过读取配置文件从数据库服务器获取一个连接
public static Connection getConnection() throws Exception{ return dataSource.getConnection();
} //关闭 ResultSet、Statement 和 Connection
public static void release(ResultSet rs,Statement statement,Connection conn){
if(rs != null){
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(statement != null){
try {
statement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
//数据库连接池的 Connection 对象进行 close 时
//并不是真的进行关闭, 而是把该数据库连接会归还到数据库连接池中.
if(conn != null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
} /*
* 处理数据库的事务
*/ //提交事务
public static void commit(Connection conn){
if(conn != null){
try {
conn.commit();
} catch (SQLException e) {
e.printStackTrace();
}
}
} //回滚事务
public static void rollback(Connection conn){
if(conn != null){
try {
conn.rollback();
} catch (SQLException e) {
e.printStackTrace();
}
}
} //开始事务
public static void beginTx(Connection conn){
if(conn != null){
try {
conn.setAutoCommit(false);
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}

  C3P0 要在 src 目录下配置:创建一个名为 c3p0-config.xml ,并且记住要导入 c3p0 的 jar 包。

c3p0-config.xml 的配置

<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config> <named-config name="helloc3p0"> <!-- 指定连接数据源的基本属性 -->
<property name="user">登录名</property>
<property name="password">密码</property>
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/test</property> <!-- 若数据库中连接数不足时, 一次向数据库服务器申请多少个连接 -->
<property name="acquireIncrement">5</property>
<!-- 初始化数据库连接池时连接的数量 -->
<property name="initialPoolSize">5</property>
<!-- 数据库连接池中的最小的数据库连接数 -->
<property name="minPoolSize">5</property>
<!-- 数据库连接池中的最大的数据库连接数 -->
<property name="maxPoolSize">10</property> <!-- C3P0 数据库连接池可以维护的 Statement 的个数 -->
<property name="maxStatements">20</property>
<!-- 每个连接同时可以使用的 Statement 对象的个数 -->
<property name="maxStatementsPerConnection">5</property> </named-config> </c3p0-config>

Statement接口

  用于执行静态SQL语句并返回它所生成结果的对象。

  三种Statement类:

    • Statement:由createStatement创建,用于发送简单的SQL语句(不带参数)。
    • PreparedStatement :继承自Statement接口,由preparedStatement创建,用于发送含有一个或多个参数的SQL语句。PreparedStatement对象比Statement对象的效率更高,并且可以防止SQL注入,所以我们一般都使用PreparedStatement。
    • CallableStatement:继承自PreparedStatement接口,由方法prepareCall创建,用于调用存储过程。

  常用Statement方法:

    • execute(String sql):运行语句,返回是否有结果集
    • executeQuery(String sql):运行select语句,返回ResultSet结果集。
    • executeUpdate(String sql):运行insert/update/delete操作,返回更新的行数。
    • addBatch(String sql) :把多条sql语句放到一个批处理中。
    • executeBatch():向数据库发送一批sql语句执行。

ResultSet接口

  ResultSet提供检索不同类型字段的方法,常用的有:

    • getString(int index)、getString(String columnName):获得在数据库里是varchar、char等类型的数据对象。
    • getFloat(int index)、getFloat(String columnName):获得在数据库里是Float类型的数据对象。
    • getDate(int index)、getDate(String columnName):获得在数据库里是Date类型的数据。
    • getBoolean(int index)、getBoolean(String columnName):获得在数据库里是Boolean类型的数据。
    • getObject(int index)、getObject(String columnName):获取在数据库里任意类型的数据。

  ResultSet还提供了对结果集进行滚动的方法:

    • next():移动到下一行
    • Previous():移动到前一行
    • absolute(int row):移动到指定行
    • beforeFirst():移动resultSet的最前面。
    • afterLast() :移动到resultSet的最后面。

使用后依次关闭对象及连接:ResultSet → Statement → Connection

  这里就直接提供数据库通用的查询方法,自己写成一个公用类,需要用查询方法的时候,就可以继承它,调用里面的方法。

JDBC 的 Dao 方法

package jdbc;

/*
* JDBC的工具方法
*/
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.beanutils.BeanUtils; public class Dao { // 执行 SQL 语句,使用 PreparedStatement
public void update(String sql, Object... args) {
Connection conn = null;
PreparedStatement ps = null;
try {
conn = JDBCTools.getConnection();
ps = conn.prepareStatement(sql);
for (int i = 0; i < args.length; i++) {
ps.setObject(i + 1, args[i]);
}
ps.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
} finally {
JDBCTools.release(null, ps, conn);
}
} // 执行SQL的方法,使用 Statement:insert、update、delete,而不包含select
public void update(String sql) {
Connection conn = null;
Statement st = null;
try {
conn = JDBCTools.getConnection();
st = conn.createStatement();
st.executeUpdate(sql);
} catch (Exception e) {
e.printStackTrace();
} finally {
JDBCTools.release(null, st, conn);
}
} // 查询一条记录,返回对应的对象
public <T> T get(Class<T> clazz, String sql, Object... args)throws Exception {
List<T> result = getForList(clazz, sql, args);
if (result.size() > 0) {
return result.get(0);
}
return null;
} /*
* 传入 SQL 语句和 Class 对象,返回 SQL 语句查询的记录对应的 Class 类的对象的集合
*
* @param clazz: 对象的类型
*
* @param sql: SQL 语句
*
* @param args: 填充 SQL 语句的占位符的可变参数
*
* @return
*/
public <T> List<T> getForList(Class<T> clazz, String sql, Object... args)throws Exception {
List<T> list = new ArrayList<>();
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
// 1、得到结果集
conn = JDBCTools.getConnection();
ps = conn.prepareStatement(sql);
for (int i = 0; i < args.length; i++) {
ps.setObject(i + 1, args[i]);
}
rs = ps.executeQuery(); // 2、处理结果集,得到 Map 的 List, 其中一个 Map 对象就是一条记录. Map 的 key 为 rs 中列的别名,
// Map 的 value 为列的值
List<Map<String, Object>> values = handleResultSetToMapList(rs); // 3、把 Map 的 List 转为 clazz 对应的 List, 其中 Map 的 key 即为 clazz 对应的对象的
// propertyName,
// 而 Map 的 value 即为 clazz 对应的对象的 propertyValue
list = transfterMapListToBeanList(clazz, values); } catch (Exception e) {
e.printStackTrace();
} finally {
JDBCTools.release(rs, ps, conn);
} return list;
} // 把 Map 的 List 转为 clazz 对应的 List
public <T> List<T> transfterMapListToBeanList(Class<T> clazz, List<Map<String, Object>> values)throws Exception {
List<T> result = new ArrayList<>();
T bean = null;
if (values.size() > 0) {
for (Map<String, Object> m : values) {
bean = clazz.newInstance();
for (Map.Entry<String, Object> entry : m.entrySet()) {
String propertyName = entry.getKey();
Object value = entry.getValue(); BeanUtils.setProperty(bean, propertyName, value);
}
// 把 Object 对象放入到 list 中
result.add(bean);
}
}
return result;
} /**
* 处理结果集, 得到 Map 的一个 List, 其中一个 Map 对象对应一条记
*
* @param resultSet
* @return
* @throws SQLException
*/
public List<Map<String, Object>> handleResultSetToMapList(ResultSet rs) throws Exception {
// 准备一个 List<Map<String, Object>>:键: 存放列的别名, 值: 存放列的值. 其中一个 Map
// 对象对应着一条记录
List<Map<String, Object>> values = new ArrayList<>();
List<String> columnLabels = getColumnLabels(rs);
Map<String, Object> map = null; // 处理 ResultSet, 使用 while 循环
while (rs.next()) {
map = new HashMap<>();
for (String columnLabel : columnLabels) {
Object value = rs.getObject(columnLabel);
map.put(columnLabel, value);
} // 把一条记录的一个 Map 对象放入 List 中
values.add(map);
}
return values;
} /**
* 获取结果集的 ColumnLabel 对应的 List
*
* @param rs
* @return
* @throws SQLException
*/
private List<String> getColumnLabels(ResultSet rs) throws Exception {
List<String> labels = new ArrayList<>();
ResultSetMetaData rsmd = rs.getMetaData();
for (int i = 0; i < rsmd.getColumnCount(); i++) {
labels.add(rsmd.getColumnLabel(i + 1));
}
return labels;
} // 返回某条记录的某一个字段的值 或 一个统计的值(一共有多少条记录等.)
@SuppressWarnings("unchecked")
public <E> E getForValue(String sql, Object... args) {
// 1. 得到结果集: 该结果集应该只有一行, 且只有一列
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
// 1. 得到结果集
conn = JDBCTools.getConnection();
ps = conn.prepareStatement(sql); for (int i = 0; i < args.length; i++) {
ps.setObject(i + 1, args[i]);
} rs = ps.executeQuery(); if (rs.next()) {
return (E) rs.getObject(1);
}
} catch (Exception ex) {
ex.printStackTrace();
} finally {
JDBCTools.release(rs, ps, conn);
}
// 2. 取得结果 return null;
}
}

  掌握好 JDBC 的连接,Java 写很多项目都要与数据库打交道。

  自己写的不是专业,希望大家提一下意见。自己也是在学习 Java 的小白。写一下博客记录一下自己的学习情况。写一下博客,能了解自己学习的水平。

Java_JDBC 连接的更多相关文章

  1. Java_jdbc 基础笔记之十四 数据库连接(元数据)数据库信息及连接信息

    public class MetaDatatest { /** * DatabaseMetaData 是描述 数据库的元数据对象 可以由Connection得到 */ @Test public voi ...

  2. 使用JDBC连接MySQL数据库的一个基本案例

    JDBC的概念(摘自百度百科) JDBC(Java DataBase Connectivity,java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一 ...

  3. nodejs进阶(6)—连接MySQL数据库

    1. 建库连库 连接MySQL数据库需要安装支持 npm install mysql 我们需要提前安装按mysql sever端 建一个数据库mydb1 mysql> CREATE DATABA ...

  4. SQL Server 无法连接到服务器。SQL Server 复制需要有实际的服务器名称才能连接到服务器。请指定实际的服务器名称。

    异常处理汇总-数据库系列  http://www.cnblogs.com/dunitian/p/4522990.html SQL性能优化汇总篇:http://www.cnblogs.com/dunit ...

  5. Linux 开机时网络自动连接

      简单版本: cd /etc/sysconfig/network-scripts/ vi ifcfg-enoXXX 输入:reboot重启 或者输入:service network restart ...

  6. 在ubuntu16.10 PHP测试连接MySQL中出现Call to undefined function: mysql_connect()

    1.问题: 测试php7.0 链接mysql数据库的时候发生错误: Fatal error: Uncaught Error: Call to undefined function mysqli_con ...

  7. 【初学python】使用python连接mysql数据查询结果并显示

    因为测试工作经常需要与后台数据库进行数据比较和统计,所以采用python编写连接数据库脚本方便测试,提高工作效率,脚本如下(python连接mysql需要引入第三方库MySQLdb,百度下载安装) # ...

  8. 一起学微软Power BI系列-使用技巧(1)连接Oracle与Mysql数据库

    说起Oracle数据库,以前没用过Oracle不知道,但是这1年用Oracle后,发现真的是想狂吐槽,特别是那个.NET驱动和链接字符串,特别奇葩.总归是和其他数据库不一样,标新立异,不知道为何.另外 ...

  9. 使用SecureCRT连接虚拟机(ubuntu)配置记录

    这种配置方法,可以非常方便的操作虚拟机里的Linux系统,且让VMware在后台运行,因为有时候我直接在虚拟机里操作会稍微卡顿,或者切换速度不理想,使用该方法亲测本机效果确实ok,特此记录. Secu ...

随机推荐

  1. base64转图片、图片转base64、图片拼接、加水印(水印角度可设置)

    /** * @Description: 将base64编码字符串转换为图片 * @param imgStr * base64编码字符串 * @param path * 图片路径-具体到文件 * @re ...

  2. Oracle触发器用法--基础教学

    1.触发器简介 触发器的定义就是说某个条件成立的时候,触发器里面所定义的语句就会被自动的执行.因此触发器不需要人为的去调用,也不能调用.然后,触发器的触发条件其实在你定义的时候就已经设定好了.这里面需 ...

  3. 解决 Docker Hadoop ssh "Connection to * closed".问题

    Docker 最近很火, 可以快速轻量级地虚拟出多个node,所以打算在Docker中跑Hadoop伪分布式应用. 其实要做出个简单的版本倒是不难,主要在 建立ssh无密码登录本机时,出现刚登录上去, ...

  4. 一道时间复杂度为O(N)空间复杂度为O(1)的排序问题

    题目:对1, 2, ... , n的一个无序数组,排序,要求时间复杂度为O(N),空间复杂度为O(1). 思路:该题利用数组元素和数组下标相差1的关系,Java代码如下: import java.ut ...

  5. hibernate查询方式(三)

    QBC查询 (Query By Criteria) *****QBC查询有三个特点 **查询时不写sql语句 而是用方法来查询 **操作实体类和属性 **通过criteria对象来实现 1.查询所有 ...

  6. sass 安装过程中的坑

    1,需要在项目中使用sass/scss 功能需要先在项目中安装,安装方法: cnpm install node-sass --save-dev //安装node-sass cnpm install s ...

  7. 利用Mitmproxy抓包

    http://mrpeak.cn/blog/mitmproxy/   和Charles同样强大的免费抓包软件. 它是在终端操作的,界面没有Charles那么可视化.不过也很好用,通过各种快捷键操作,效 ...

  8. 线性规划VB求解

    线性规划VB求解 Rem 定义动态数组 Dim a() As Single, c() As Single, b() As Single, cb() As Single Dim aa() As Sing ...

  9. LightOJ 1344 Aladdin and the Game of Bracelets

    It's said that Aladdin had to solve seven mysteries before getting the Magical Lamp which summons a ...

  10. AI Boot Camp 分享之 ML.NET 机器学习指南

    今天在中国七城联动,全球134场的AI BootCamp胜利落幕,广州由卢建晖老师组织,我参与分享了一个主题<ML.NET 机器学习指南和Azure Kinect .NET SDK概要>, ...