使用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;">