1.JDBC介绍
1.什么是JDBC?
JDBC(Java DataBase Connectivity)就是Java数据库连接,说白了就是用Java语言来操作数据库。原来我们操作数据库是在控制台使用SQL语句来操作数据库,JDBC是用Java语言向数据库发送SQL语句。
对于初学者刚开始用java操作数据库时,我们在进行数据库的增删改查时,每一个方法都需要重复的connection去连接数据库进行操作,然后用完后进行关流操作,这对于我们程序员来说重复写同样的代码工作效率会降低,JDBC简单点说就是一款方便操作数据库操作的一款小工具,当我们使用增删改查时,只需要调里面对应的方法即可。
2 JDBC原理
JDBC是Sun公司制定的一个可以用Java语言连接数据库的技术。
是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java语言编写的类和接口组成。JDBC为数据库开发人员提供了一个标准的API,据此可以构建更高级的工具和接口,使数据库开发人员能够用纯 Java API 编写数据库应用程序,并且可跨平台运行,并且不受数据库供应商的限制。
2.JDBC实现步骤
1.工程结构
创建一个java工程,until包下放两个类,JDBCTools里面放连接和关流的方法,MyJDBCUntil里面写增删改查的方法,db.properties写数据库的连接地址,端口号,用户名,密码,lib里面放我们需要导入的connector.jar包
2.properties里面的日志信息
3.1JDBCTools
public static Connection getConnection() {
// 1.读配置文件参数
Properties properties = new Properties();
Connection conn = null;
try {
InputStream in = JDBCTools.class.getClassLoader().getResourceAsStream("db.properties");
properties.load(in);
String user = properties.getProperty("user");
String password = properties.getProperty("password");
String url = properties.getProperty("url");
String dirver = properties.getProperty("driver");
//通过反射获取dirver驱动加载
Class.forName(dirver);
conn = DriverManager.getConnection(url, user, password);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
return conn;
}
3.2关流操作
/**
* 关闭连接
*
* @param rs
* @param ps
* @param connection
*/
public static void close(ResultSet rs, PreparedStatement ps, Connection connection) {
try {
if (rs != null) {
rs.close();
}
if (ps != null) {
ps.close();
}
if (connection != null) {
connection.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
3.3方法的重载关流,调用的方法不同所关闭的流也不同,所以我们进行重载就行
public static void close(PreparedStatement ps, Connection connection) {
close(null, ps, connection);
}
public static void close(Connection connection) {
close(null, null, connection);
}
public static void main(String[] args) {
JDBCTools.getConnection();
}
4.MyJDBCUntil
4.1 更新数据的方法
/**
* 数据库的更新操作,包括增加,修改,删除不包括查询
* @param sql
* @param params 这里用的动态数组 ...表示动态数组,即可以传入多个参数,有动态数组传参必须放在最后
* @return 返回受影响行数
*/
public static int executeUpdate(String sql,Object...params) {
//获取连接
Connection conn=JDBCTools.getConnection();
PreparedStatement ps = null;
int id = -1;
try {
ps = conn.prepareStatement(sql);
if (params != null) {
for (int i = 1; i <= params.length; i++) {
ps.setObject(i, params[i - 1]);
}
}
id = ps.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}
return id;
}
4.2查询
/**
* String sql = "SELECT number,username,age FROM student WHERE number = ?";
*
* @param sql
* @param params Class<T> cla 类类型 查询返回对象的类型,如查询Student对象,cla:学生类类型 Student.class
* @return
*/
public static <T> T executeQueryObj(Class<T> cla, String sql, Map<String, String> columParams, Object... params) {
Connection conn = JDBCTools.getConnection();
PreparedStatement ps = null;
ResultSet rs = null;
T obj = null; // 查询返回的对象
try {
ps = conn.prepareStatement(sql);
// 设置参数
if (params != null) {
for (int i = 1; i <= params.length; i++) {
ps.setObject(i, params[i - 1]);
}
}
rs = ps.executeQuery();
// 处理查询结果集
ResultSetMetaData rsmd = rs.getMetaData(); // 返回结果集元数据
int count = rsmd.getColumnCount(); // 返回字段个数
if (rs.next()) {
Map<String, Object> columMap = new HashMap<String, Object>();
obj = cla.newInstance(); // new Student() //通过反射实例化对象时一定要有默认构造方法
for (int k = 0; k < count; k++) {
String columLable = rsmd.getColumnLabel(k + 1); // 字段名称 number,username,password
Object columValue = rs.getObject(columLable); // 字段值 1001 admin 123456
columMap.put(columLable, columValue);
}
Set<String> keySets = columMap.keySet();
for (String key : keySets) {
if (columParams == null) {
BeanUtils.setProperty(obj, key, columMap.get(key));
} else {
BeanUtils.setProperty(obj, getPropertyByKey(columParams, key), columMap.get(key));
}
}
}
} catch (SQLException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} finally {
JDBCTools.close(rs, ps, conn);
}
return obj;
}
注:上面的beanutil是一个依赖包,需要导入
属性名与字段名不同的查询
/**
* 属性名与字段名不一样 Object... 可变数组 {1,2} {1,2,3,4} Object[] obj = new Object[3]
*/
public static <T> List<T> executeQueryList(Class<T> clazz, String sql, Map<String, String> parameterMap,
Object... args) {
List<T> list = new ArrayList<>();
Connection conn = JDBCTools.getConnection();
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
pstmt = conn.prepareStatement(sql);
if (args != null) {
for (int i = 0; i < args.length; i++) {
pstmt.setObject(i + 1, args[i]);
}
}
rs = pstmt.executeQuery();
// 1.通过SQL语句得到查询了多少列
ResultSetMetaData rsmd = rs.getMetaData();
// Map<String, Object> map = new HashMap<>();
List<Map<String, Object>> values = new ArrayList<>();
Map<String, Object> map = null;
while (rs.next()) {
map = new HashMap<>();
// 通过反射获取对象的实例
for (int i = 0; i < rsmd.getColumnCount(); i++) {
// 2.哪些列
String columnLabel = rsmd.getColumnLabel(i + 1);
// 3.每一列对应的值是什么
Object value = rs.getObject(i + 1);
// System.out.println(columnLabel+"------"+value);
map.put(columnLabel, value);
}
values.add(map);
}
T entity = null;
// 4.将值赋给对象的属性
if (values.size() > 0) {
if (parameterMap == null) { // 字段名称和属性相同情况
for (int i = 0; i < values.size(); i++) {
entity = clazz.newInstance();// 通过反射实例化对象
for (String key : values.get(i).keySet()) {
BeanUtils.setProperty(entity, key, values.get(i).get(key));
}
list.add(entity);
}
} else {
for (int i = 0; i < values.size(); i++) {
entity = clazz.newInstance();// 通过反射实例化对象
for (String key : values.get(i).keySet()) {
BeanUtils.setProperty(entity, getPropertyByKey(parameterMap, key), values.get(i).get(key));
}
list.add(entity);
}
}
}
} catch (SQLException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return list;
}
/**
*
* @param columParams 字段与属性映射 columParams.put("username", "userName");
* @param field 字段名
* @return 对象属性名
*/
public static String getPropertyByKey(Map<String, String> columParamsMap, String field) {
for (String key : columParamsMap.keySet()) {
if (field.equals(key)) {
return columParamsMap.get(key);
}
}
return field;
}