使用JDBC连接数据库

使用JDBC连接数据库 

 一准备

1、 数据库服务是否开启

2、 连接的数据库是否是远程的

是检查远程连接的服务是否开启,或者用户是否有远程登录的权限

3、 检查客户机与数据库服务器之间是否能ping

 

4、 准备要连接的数据库的驱动包

注意:请根据自己的数据库版本和jdk选择jar

 

Oracle ojdbc6.jar

SQLServer :sqljdbc4.jar

MySql:mysql-connector-java-5.1.44-bin.jar

编写BaseDao要用到的jar

dom4j-2.1.1.jar 用于xml解析

jstl.jar   Result对象需要用到jstl支持

 

数据库连接文件的配置

 

1、 使用属性文件(.properties)配置

 

#Oracle配置

#driver=oracle.jdbc.driver.OracleDriver

#connStr=jdbc:oracle:thin:@192.168.11.111:1521:orcl

#userName=scott

#userPwd=scott

 

#MySql 配置

userName=root

userPwd=root

connStr=jdbc:mysql://192.168.11.111:3306/PetDB

driver=com.mysql.jdbc.Driver

 

#SQL Server配置

#userName=sa

#userPwd=sasa

#connStr=jdbc:sqlserver://localhost:1433;databaseName=PetDB

#driver=com.microsoft.sqlserver.jdbc.SQLServerDriver

 

2、 使用xml配置

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE configuration SYSTEM "DBConfig.dtd">

<!--

Oracle配置

<configuration>

<driver>oracle.jdbc.driver.OracleDriver</driver>

<connStr>jdbc:oracle:thin:@192.168.11.111:1521:orcl</connStr>

<userName>scott</userName>

<userPwd>scott</userPwd>

</configuration>

 -->

 

<!--

SQLServer 配置

<configuration>

<driver>com.microsoft.sqlserver.jdbc.SQLServerDriver</driver>

<connStr>jdbc:sqlserver://localhost:1433;databaseName=PetDB</connStr>

<userName>sa</userName>

<userPwd>sasa</userPwd>

 

</configuration>

 

 -->

 

 

 

<configuration>

<driver>com.mysql.jdbc.Driver</driver>

<connStr>jdbc:mysql://192.168.11.111/PetDB</connStr>

<userName>root</userName>

<userPwd>root</userPwd>

 

</configuration>

  BaseDao的编写和测试

1、 BaseDao的编写

package com.hx.basedao;

 

import java.io.File;

import java.io.FileWriter;

import java.io.IOException;

import java.io.InputStream;

import java.lang.reflect.Field;

import java.math.BigDecimal;

import java.sql.Connection;

import java.sql.DriverManager;

import java.sql.PreparedStatement;

import java.sql.ResultSet;

import java.sql.ResultSetMetaData;

import java.sql.Statement;

import java.util.ArrayList;

import java.util.HashMap;

import java.util.List;

import java.util.Map;

import java.util.Properties;

 

import javax.servlet.jsp.jstl.sql.Result;

import javax.servlet.jsp.jstl.sql.ResultSupport;

 

import org.dom4j.Document;

import org.dom4j.DocumentException;

import org.dom4j.Element;

import org.dom4j.io.OutputFormat;

import org.dom4j.io.SAXReader;

import org.dom4j.io.XMLWriter;

public class BaseDao {

 

private static final String USER_PWD = "userPwd";

private static final String USER_NAME = "userName";

private static final String CONN_STR = "connStr";

private static final String DRIVER = "driver";

private static String driver = "";

private static String connStr = "";

private static String userName = "";

private static String userPwd = "";

 

static {

try {

getDBConfigByXML();

} catch (Exception e) {

e.printStackTrace();

}

}

 

public static void getDBConfigPro() {

// 创建属性文件对象

Properties p = new Properties();

// 获取要读取的属性文件的输入流

 

// 注意属性文件的路径

// 路径只能以/开头,表示根目录

// 不能以./或../开头

// 或者其他目录开头

// 参考网址:https://blog.csdn.net/cyxinda/article/details/78254057

InputStream is = BaseDao.class.getResourceAsStream("/DBConfig.properties");

// 获取BaseDao的路径

// System.out.println(BaseDao.class.getClassLoader().getResource("").getPath());

// 输出此代码,获取到路径,对比配置文件

 

try {

// 把流加载到属性文件,读取对象

p.load(is);

} catch (Exception ex) {

ex.printStackTrace();

} finally {

try {

is.close();

} catch (IOException e) {

e.printStackTrace();

}

}

driver = p.getProperty(DRIVER);

connStr = p.getProperty(CONN_STR);

userName = p.getProperty(USER_NAME);

userPwd = p.getProperty(USER_PWD);

 

}

 

public static void getDBConfigByXML() throws Exception {

SAXReader reader = new SAXReader();

// 通过read方法读取一个文件 转换成Document对象

// System.out.println(BaseDao.class.getClassLoader().getResource("OracleConn.xml").getPath());

/// E:/WorkSpace/Utils/bin/OracleConn.xml

Document doc = reader.read(new File(BaseDao.class.getClassLoader().getResource("DBConfig.xml").getPath()));

 

// 获取根节点

Element root = doc.getRootElement();// configuration

 

// 获取根节点的子节点

List<Element> es = root.elements();

 

for (Element e : es) {

if (e.getName().equals(DRIVER)) {

driver = e.getText().trim();

// System.out.println(driver);

} else if (e.getName().equals(CONN_STR)) {

connStr = e.getText().trim();

} else if (e.getName().equals(USER_NAME)) {

userName = e.getText().trim();

} else if (e.getName().equals(USER_PWD)) {

userPwd = e.getText().trim();

}

}

 

}

 

/**

 * 获取数据库连接的方法

 *

 * @return 数据库连接对象

 */

public static Connection getConn() {

// 创建连接对象

Connection conn = null;

try {

// 1、加载驱动

Class.forName(DRIVER);

// 2、获取连接

conn = DriverManager.getConnection(CONN_STR, USER_NAME, USER_PWD);

} catch (Exception ex) {

ex.printStackTrace();

 

}

return conn;// 返回连接对象

}

 

/**

 * 关闭所有资源

 *

 * @param conn 连接对象

 * @param stmt 命令对象

 * @param rs   结果集

 */

public static void closeAll(Connection conn, Statement stmt, ResultSet rs) {

try {

if (rs != null) {

rs.close();

}

} catch (Exception ex) {

ex.printStackTrace();

 

}

try {

if (stmt != null) {

stmt.close();

}

} catch (Exception ex) {

ex.printStackTrace();

 

}

try {

if (conn != null) {

conn.close();

}

} catch (Exception ex) {

ex.printStackTrace();

 

}

}

 

/**

 * 参数赋值的方法

 *

 * @param pstmt  命令对象

 * @param params 参数数组

 * @throws Exception

 */

public static void setParams(PreparedStatement pstmt, Object[] params) throws Exception {

// 判断sql语句是否有参数

if (params != null && params.length > 0) {

// 循环给sql语句的参数赋值

for (int i = 0; i < params.length; i++) {

pstmt.setObject(i + 1, params[i]);

}

}

}

 

/**

 * 执行增、删、改sql语句的通用方法

 *

 * @param sql    要执行的sql语句

 * @param params sql语句需要的参数,为null时表示sql语句没有参数

 * @return 受影响的行数

 * @throws Exception

 */

public static int update(String sql, Object[] params) {

int row = 0;// 保存执行后受影响的行数

Connection conn = null;// 连接对象

PreparedStatement pstmt = null;// 命令对象,预编译

try {

// 1、获取连接对象(调用ConnectionUtil类中的getConn()方法)

conn = getConn();

// 2、获取命令对象

pstmt = conn.prepareStatement(sql);

// 判断sql语句是否需要设置参数

if (params != null) {

setParams(pstmt, params);

}

// 3、执行sql语句

row = pstmt.executeUpdate();

} catch (Exception ex) {

ex.printStackTrace();

 

} finally {

// 关闭资源

closeAll(conn, pstmt, null);

}

return row;

}

 

/**

 * 查询的通用方法

 *

 * @param sql    要执行的sql语句

 * @param params sql语句需要的参数数组

 * @return result对象

 */

public static Result getResult(String sql, Object[] params) {

 

Connection conn = null;// 连接对象

PreparedStatement pstmt = null;// 命令对象

ResultSet rs = null;// 结果集

Result result = null;

try {

// 获取连接对象

conn = getConn();

// 根据连接对象获取命令对象

pstmt = conn.prepareStatement(sql);

// 判断sql语句是否需要设置参数

if (params != null) {

setParams(pstmt, params);

}

// 执行命令

rs = pstmt.executeQuery();

// 把结果集转换为result对象

result = ResultSupport.toResult(rs);

 

} catch (Exception ex) {

ex.printStackTrace();

} finally {

// 关闭资源

closeAll(conn, pstmt, rs);

}

 

return result;

}

/**

 * -查询的通用方法 - 这个方法容易报错

 *

 * @param sql    要执行的sql语句

 * @param params sql语句需要的参数数组

 * @return result对象

 */

public static List<?> queryByResultSet(String sql, Object[] params, Class<?> clz) {

List list = null;// 保存查询结果

Connection conn = null;// 连接对象

PreparedStatement pstmt = null;// 命令对象

ResultSet rs = null;// 结果集

 

try {

// 获取连接对象

conn = getConn();

// 根据连接对象获取命令对象

pstmt = conn.prepareStatement(sql);

// 判断sql语句是否需要设置参数

if (params != null) {

setParams(pstmt, params);

}

// 执行命令

rs = pstmt.executeQuery();

// 判断是否存在记录

if (rs != null) {// 有数据

// rs.next()

// 存在记录 rs就要向上移一条记录 因为rs.next会滚动一条记录了

// rs.previous();

 

// 在执行while 循环

list = new ArrayList();

while (rs.next()) {

// 结果集的元数据,结果集是由数据库表中一行行数据组成的

// 这里获取的是一行数据

ResultSetMetaData metaData = rs.getMetaData();

int count = metaData.getColumnCount();// 获取总列数;

// System.out.println("总列数"+count);

Object obj = clz.newInstance();// 获取类对象的实例;

for (int i = 0; i < count; i++) {

Object value = rs.getObject(i + 1);// 获取对应列所对应的字段值

// System.out.println("对应列所对应的字段值"+value);

String colname = metaData.getColumnName(i + 1).toLowerCase();// 获取对应列名;

// System.out.println("列名:"+colname);

// oracle 不管你建表时字段是大写还是小写,它一律帮你转换成大写

// 建议所有java类的属性都小写

 

// ①没有对应字段;②属性为私有时获取Field用的方法不是getDeclaredField。否则会报错

Field field = clz.getDeclaredField(colname);// 通过列名获取到字段对象,就是我们所说的属性;

field.setAccessible(true);

 

// 此处调用了Field类的set方法,就是给封装类对象所对应的字段赋值操作,

// 这样数据表对应的封装类的对象类就有值了,相当于查询到了理想的结果。

 

// 判断字段的数据类型

// Oracle 中 number类型 通过ResultSet 的 getObject() 返回的是 BigDecimal 类型

if (value instanceof BigDecimal) {

// System.out.println("bigdecimal");

int num = ((BigDecimal) value).intValue();

field.set(obj, num);

} else {

field.set(obj, value);// 将指定对象变量上此 Field 对象表示的字段设置为指定的新值

}

 

}

 

// 因为考虑到查询的结果不止一条,用集合进行操作

 

// 然后返回该结果集对象

list.add(obj);

}

 

}

 

} catch (Exception ex) {

ex.printStackTrace();

} finally {

// 关闭资源

closeAll(conn, pstmt, rs);

}

 

return list;

}

 

/**

 * 查询的通用方法 将表中的一行数据保存到一个map对象中,key为列(字段)的下标,value为该列(字段)的值 返回保存map的泛型集合

 *

 * @param sql    要做执行的 sql语句

 * @param params SQL语句需要的参数

 * @return

 */

public static List<Map> QueryByResultSet(String sql, Object[] params) {

Connection conn = null;

PreparedStatement pstmt = null;

ResultSet rs = null;

try {

// 1.获取conn

conn = getConn();

// 2.获取Statement

pstmt = conn.prepareStatement(sql);

if (params != null) {

setParams(pstmt, params);

}

// 4.执行查询,得到ResultSet

rs = pstmt.executeQuery(sql);

// 5.处理ResultSet

List<Map> list = new ArrayList<Map>();

ResultSetMetaData metaData = rs.getMetaData();

int columnCount = metaData.getColumnCount();

while (rs.next()) {

Map rowData = new HashMap();

for (int i = 1; i < columnCount; i++) {

rowData.put(metaData.getColumnName(i).toLowerCase(), rs.getObject(i));

 

}

list.add(rowData);

}

 

return list;

} catch (Exception e) {

e.printStackTrace();

 

} finally {

// 6.关闭数据库相应的资源

closeAll(conn, pstmt, rs);

}

 

return null;

}

}

 

测试

在数据库创建表,没有数据库的先创建数据库

在项目中创建表对应的类

接下来进行单元测试

 

1.1 Oracle服务器 的ORCL中创建表

 

/*

id;神兽的编号

masterId;所属的世界之主编号

name;神兽的昵称

health;健康值

lover;亲密度

type;类型

grade;// 神兽青龙所特有的

*/

 

drop table Dragon;

create table dragon(

id number(5) primary key not null,

masterid number(5) ,

name varchar2(10) ,

health number(3),

lover number(3),

type varchar2(10),

grade varchar(10)

)

--插入数据

insert into(id,masterid,name,health,lover,type,grade) values()

--创建序列

create sequence dragonid_sequ

increment by 1

start with 10000

nomaxvalue

nocycle

cache 10;

 

 

--查询表

select * from dragon

 

--删除表

drop table   dragon

 

1.2 SQL Server 中创建PetDB数据库 和 Dragon

 

--创建PetDB数据库

create database StudentDB

on primary--主文件组

(

--数据库文件的逻辑名称,不能重复

name='PetDB',

--数据库物理文件名(绝对路径)

filename='E:\PetDB.mdf',

--数据库文件初始大小

size=10MB,

--数据文件增长量

filegrowth=1MB

)

log on

(

--日志文件的逻辑名称,不能重复

name='PetDB_log',

--日志物理文件名(绝对路径)

filename='E:\PetDB_log.ldf',

--日志文件初始大小

size=3MB,

--日志文件增长量

filegrowth=1MB

)

go

--创建Dragon

create table Dragon(

id numeric(5, 0)identity(1,1)  primary key not null,

masterid numeric(5, 0) ,

name varchar(10) ,

health numeric(3, 0),

lover numeric(3, 0),

type varchar(10),

grade varchar(10)

)

 

1.3 MySql中创建PetDB数据库 和 Dragon

创建数据库

 CREATE DATABASE `PetDB`

创建表

CREATE TABLE `dragon` (

`id` int(11) NOT NULL AUTO_INCREMENT,  

`masterId` int(11) DEFAULT NULL,

`name` varchar(45) DEFAULT NULL,

`health` int(11) DEFAULT NULL,

`lover` int(11) DEFAULT NULL,

`type` varchar(45) DEFAULT NULL,

 `grade` varchar(45) DEFAULT NULL,

 PRIMARY KEY (`id`))

 ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf

1.4 java项目中创建Dragon

 

package com.hx.entity;

 

public class Dragon {

 

/**

 * 神兽的编号

 */

private int id;

/**

 * 所属的世界之主编号

 */

private int masterid;

/**

 * 神兽的昵称

 */

private String name;

/**

 * 健康值

 */

private int health;

 

/**

 * 亲密度

 */

private int lover;

 

/**

 * 类型

 */

private String type;

 

/**

 * 等级

 */

private  String grade;// 神兽青龙所特有的

 

public int getId() {

return id;

}

 

public void setId(int id) {

this.id = id;

}

 

public int getMasterid() {

return masterid;

}

 

public void setMasterId(int masterId) {

this.masterid = masterId;

}

 

public String getName() {

return name;

}

 

public void setName(String name) {

this.name = name;

}

 

public int getHealth() {

return health;

}

 

public void setHealth(int health) {

this.health = health;

}

 

public int getLover() {

return lover;

}

 

public void setLover(int lover) {

this.lover = lover;

}

 

public String getType() {

return type;

}

 

public void setType(String type) {

this.type = type;

}

 

public String getGrade() {

return grade;

}

 

public void setGrade(String grade) {

this.grade = grade;

}

 

@Override

public String toString() {

return "Dragon [id=" + id + ", masterId=" + masterid + ", name=" + name + ", health=" + health + ", lover="

+ lover + ", type=" + type + ", grade=" + grade + "]";

}

 

 

}

1.5 开始测试

测试比较简单只测了查询

有兴趣的话可以更改配置文件测试不同数据库之间的连接,和对表的其他操作

 

package com.hx.test;

 

import static org.junit.Assert.*;

import java.io.File;

import java.io.IOException;

import java.util.HashMap;

import java.util.List;

import java.util.Map;

import java.util.Map.Entry;

import java.util.Set;

import org.junit.Test;

import com.hx.basedao.BaseDao;

import com.hx.entity.Dragon;

 

public class TestJDBC {

public static void main(String[] args) throws IOException {

test();

}

 

@Test

public static void test() {

 

String sql = "select * from dragon";

 

List<Dragon> dList = (List<Dragon>) BaseDao.queryByResultSet(sql, null, Dragon.class);

 

for (Dragon dragon : dList) {

System.out.println(dragon.toString());

}

}

 

@Test

public static void test2() {

String sql = "select * from dragon";

List<Map> list = BaseDao.QueryByResultSet(sql, null);

for (Map m : list) {

System.out.println(m.get("id"));

}

}

}

 

 

 

 

 

 

 

<wiz_tmp_tag id="wiz-table-range-border" contenteditable="false" style="display: none;">





posted @ 2018-09-19 17:32  前行者鼠  阅读(1071)  评论(0编辑  收藏  举报