Java JDBC通用操作基类 (MySQL)数据库

6 篇文章 1 订阅

DBHelper.java

package MySQL;


import java.lang.reflect.*;
import java.sql.*;
import java.util.*;
import java.util.Map.Entry;




public class DBHelper {
	
	// 定义共用的连接对象

	private Connection conn;
	
	private boolean isAutoCommit = true;
	static final String JDBC_DRIVER = "com.mysql.cj.jdbc.Driver";
	static final String DB_URL = "jdbc:mysql://localhost:3306/aaa";


	// 数据库的用户名与密码,需要根据自己的设置
	static final String USER = "student";
	static final String PASS = "aaaaaaaa";
	/**
	 * 	类的代码块:
	 * 	静态块: 
	 * 		static {}
	 * 		特点: 会在类被加载到虚拟机时,执行一次(  例如: import 类)
	 * 	实例块
	 * 		{}
	 * 		特点: 会在对象被创建时执行一次, 在构造方法前
	 * 	块不是方法,不能抛出编译期异常
	 */
	static {
		try {
			Class.forName(JDBC_DRIVER);
		} catch (ClassNotFoundException e) {
			// 异常转型 ==> 异常链
			// 未捕获的运行期异常将导致程序的终止
			RuntimeException re = new RuntimeException("数据库驱动加载失败!", e);
			throw re;
		}
	}
	
	/**
	 * 使用 isAutoCommit 决定是否自动提交
	 * 
	 * 如果是自动提交, 则意味着每次执行 update 方法都要获取新的连接, 在执行之后关闭连接
	 * 否则, 不关闭连接
	 * @param isAutoCommit  自动提交  true
	 */
	public DBHelper(boolean isAutoCommit) {
		this.isAutoCommit = isAutoCommit;
		if(isAutoCommit == false) {
			conn = openConnection();
		}
	}
	
	/**
	 * JDBC 连接默认是自动提交, 也就是每次执行完增删改都会自动提交
	 * 无参的构造方法, 可以注释掉了
	 */
	public DBHelper() {
		// 在构造方法中创建连接
		//conn = openConnection();
	}
	
	// 关闭连接
	public void closeConnection() {
		IOHelper.close(conn);
	}
	
	// 返回连接对象
	public Connection getConn() {
		return conn;
	}

	/**
	 * 	获取连接
	 * @return
	 */
	public Connection openConnection() {

		try {
			if(isAutoCommit) {
				return DriverManager.getConnection(DB_URL,USER,PASS);
			} else {
				if(conn == null) {
					// 禁止自动提交
					conn = DriverManager.getConnection(DB_URL,USER,PASS);
					conn.setAutoCommit(isAutoCommit);
				}
				return conn;
			}
		} catch (SQLException e) {
			throw new RuntimeException("获取数据库连接失败!", e);
		}
	}

	/**
	 * 	执行修改数据库的语句
	 * sql = "update emp set ename = ? where empno=?"
	 * update(sql,2,3,)
	 * @param sql		执行的sql语句
	 * @param params	可变参数数组
	 * @return
	 */
	public int update(String sql, Object... params) {
		try {
			// 每次都会通过open方法获取连接
			conn = openConnection(); 
			System.out.println("SQL: " + sql);
			PreparedStatement ps = conn.prepareStatement(sql);
			// alrt + /
			System.out.println("参数: " + Arrays.toString(params));
			for (int i = 0; i < params.length; i++) {
				ps.setObject(i + 1, params[i]);
			}
			return ps.executeUpdate();
		} catch (SQLException e) {
			throw new RuntimeException("执行SQL语句失败!", e);
		} finally {
			if(isAutoCommit == true) {
				IOHelper.close(conn);
			}
		}
	}

	/**
	 * 	执行查询语句
	 * @param sql
	 * @param params
	 * @return
	 */
	public List<Map<String, Object>> query(String sql, Object... params) {
		try {
			conn = openConnection(); 
			System.out.println("SQL: " + sql);
			PreparedStatement ps = conn.prepareStatement(sql);
			// alrt + /
			System.out.println("参数: " + Arrays.toString(params));
			for (int i = 0; i < params.length; i++) {
				ps.setObject(i + 1, params[i]);
			}
			ResultSet rs = ps.executeQuery();

			// 获取结果集元数据对象, 元(Meta)数据(data): 描述数据的数据
			ResultSetMetaData rsmd = rs.getMetaData();
			// 创建返回结果对象
			List<Map<String, Object>> ret = new ArrayList<>();
			while (rs.next()) {
				// 创建 map 集合
				/**
				 * 1. HashMap   	无序不重复
				 * 2 LinkedHashMap, 有序不重复
				 * 3. TreeMap 		排序不重复
				 */
				Map<String, Object> row = new LinkedHashMap<>();
				// 获取每一个字段值, 设置到一个map中
				for (int i = 0; i < rsmd.getColumnCount(); i++) {
					String columnName = rsmd.getColumnName(i + 1);
					Object columnValue = rs.getObject(columnName);
					row.put(columnName, columnValue);
				}
				// 将 map 添加到 ret 中
				ret.add(row);
			}
			return ret;
		} catch (SQLException e) {
			throw new RuntimeException("执行SQL语句失败!", e);
		} finally {
			if(isAutoCommit == true) {
				IOHelper.close(conn);
			}
		}
	}
	
	/**
	 * 	返回值的类型是可变的类型, 所有的集合==> 泛型类
	 * 	query 方法改造成 泛型方法	: 语法的定义: 在方法前用 <E>
	 * 
	 * @param sql
	 * @param cls		类对象, 表示 E 类的类对象, Java 反射技术
	 * @param params
	 * @return
	 */
	public <E> List<E> query(String sql, Class<E> cls, Object... params) {
		try {
			conn = openConnection();
			System.out.println("SQL: " + sql);
			PreparedStatement ps = conn.prepareStatement(sql);
			// alrt + /
			System.out.println("参数: " + Arrays.toString(params));
			for (int i = 0; i < params.length; i++) {
				ps.setObject(i + 1, params[i]);
			}
			ResultSet rs = ps.executeQuery();

			// 获取结果集元数据对象, 元(Meta)数据(data): 描述数据的数据
			ResultSetMetaData rsmd = rs.getMetaData();
			// 创建返回结果对象
			List<E> ret = new ArrayList<>();
			while (rs.next()) {
				// 创建 实体对象集合( 通过反射机制创建实体对象  == new 实体类()   )
				E e;
				try {
					e = cls.newInstance();
				} catch (Exception e2) {
					// 异常转型
					throw new RuntimeException(e2);
				}
				
				// 通过反射进行属性值的设置
				for (int i = 0; i < rsmd.getColumnCount(); i++) {
					try {
						// 根据当前的列名找对应的属性
						String columnName = rsmd.getColumnName(i+1); // ID, NAME, AUTHER ...
						columnName = columnName.toLowerCase(); // 转小写
						// 获取该类定义的属性(包括私有)
						Field field = cls.getDeclaredField(columnName);
						// 获取当前列的值
						/**
						 *  ID ==> JDBC 数据类型 : BigDecimal 大实数 表示任意大小的数字
						 *  	  	    实体类类型: Long
						 *  .getType 获取属性的类型  ==> LONG  String  Integer
						 */
						// 从结果取出的数值
						//Object value = rs.getObject(i+1);  
						// 要转换的数值
						Object destValue = null;
						// 一定要判断非空, 否则会导致类型转换错误
//						if(value==null) {
//							continue;
//						}
						if(field.getType().equals(Long.class)) {
							destValue = rs.getLong(i+1);  
							//destValue = Long.valueOf(value + "");
						} else if(field.getType().equals(Integer.class)) {
							destValue = rs.getInt(i+1);  
							//destValue = Integer.valueOf(value + "");
						} else if(field.getType().equals(Double.class)) {
							destValue = rs.getDouble(i+1);  
							//destValue = Double.valueOf(value + "");
						} else if(field.getType().equals(Byte.class)) {
							destValue = rs.getByte(i+1);  
							//destValue = Byte.valueOf(value + "");
						} else if(field.getType().equals(Boolean.class)) {
							destValue = rs.getBoolean(i+1);  
							//destValue = Boolean.valueOf(value + "");
						} else if(field.getType().equals(Timestamp.class)) {
							destValue = rs.getTimestamp(i+1);  
							//destValue = Byte.valueOf(value + "");
							
						// 其他数据类型请自行添加
						} else {
							destValue = rs.getObject(i+1);  
						}
						// 设置强制访问私有属性
						field.setAccessible(true);
						// 将值设置到该属性中
						field.set(e, destValue);
					} catch (Exception e1) {
						e1.printStackTrace();
					}
				}
				// 将 map 添加到 ret 中
				ret.add(e);
			}
			return ret;
		} catch (SQLException e) {
			throw new RuntimeException("执行SQL语句失败!", e);
		} finally {
			if(isAutoCommit == true) {
				IOHelper.close(conn);
			}
		}
	}
	
	public List<Map<String, Object>> query1( String sql,Class<Map<String, Object>> cls, Object... params) {
		try {
			conn = openConnection();
			System.out.println("SQL: " + sql);
			PreparedStatement ps = conn.prepareStatement(sql);
			// alrt + /
			System.out.println("参数: " + Arrays.toString(params));
			for (int i = 0; i < params.length; i++) {
				ps.setObject(i + 1, params[i]);
			}
			ResultSet rs = ps.executeQuery();

			// 获取结果集元数据对象, 元(Meta)数据(data): 描述数据的数据
			ResultSetMetaData rsmd = rs.getMetaData();
			// 创建返回结果对象
			List<Map<String, Object>> ret = new ArrayList<>();
			while (rs.next()) {
				// 创建 实体对象集合( 通过反射机制创建实体对象  == new 实体类()   )
				Map<String, Object> e;
				try {
					e = cls.newInstance();
				} catch (Exception e2) {
					// 异常转型
					throw new RuntimeException(e2);
				}
				
				// 通过反射进行属性值的设置
				for (int i = 0; i < rsmd.getColumnCount(); i++) {
					try {
						// 根据当前的列名找对应的属性
						String columnName = rsmd.getColumnName(i+1);
						// ID, NAME, AUTHER ...
						columnName = columnName.toLowerCase();
						// 转小写
						// 获取该类定义的属性(包括私有)
						Field field = cls.getDeclaredField(columnName);
						// 获取当前列的值
						/**
						 *  ID ==> JDBC 数据类型 : BigDecimal 大实数 表示任意大小的数字
						 *  	  	    实体类类型: Long
						 *  .getType 获取属性的类型  ==> LONG  String  Integer
						 */
						// 从结果取出的数值
						//Object value = rs.getObject(i+1);  
						// 要转换的数值
						Object destValue = null;
						// 一定要判断非空, 否则会导致类型转换错误
//						if(value==null) {
//							continue;
//						}
						if(field.getType().equals(Long.class)) {
							destValue = rs.getLong(i+1);  

						} else if(field.getType().equals(Integer.class)) {
							destValue = rs.getInt(i+1);  

						} else if(field.getType().equals(Double.class)) {
							destValue = rs.getDouble(i+1);  

						} else if(field.getType().equals(Byte.class)) {
							destValue = rs.getByte(i+1);  

						} else if(field.getType().equals(Boolean.class)) {
							destValue = rs.getBoolean(i+1);  

						} else if(field.getType().equals(Timestamp.class)) {
							destValue = rs.getTimestamp(i+1);
						// 其他数据类型请自行添加
						} else {
							destValue = rs.getObject(i+1);  
						}
						// 设置强制访问私有属性
						field.setAccessible(true);
						// 将值设置到该属性中
						field.set(e, destValue);
					} catch (Exception e1) {
						e1.printStackTrace();
					}
				}
				// 将 map 添加到 ret 中
				ret.add(e);
			}
			return ret;
		} catch (SQLException e) {
			throw new RuntimeException("执行SQL语句失败!", e);
		} finally {
			if(isAutoCommit == true) {
				IOHelper.close(conn);
			}
		}
	}
}

IOHelper.java

package MySQL;


import java.io.Closeable;
import java.io.IOException;

/**
 * IO工具类
 */
public class IOHelper {

	/**
	 * 	关闭流的工具方法,  所有的流都实现了 Closeable 方法, 所以都有close 方法, 也就是说:
	 * 	Closeable 是所有流的父类,  这里使用的就是OOP多态性
	 * @param c
	 */
	public static void close(AutoCloseable c) {
		if (c != null) {
			/**
			 * 	关于如何打开错误解决窗口
			 * 	1, 鼠标停在 报错 点上, eclipse 会给出解决方案, 其中就包括 try
			 * 	2, 光标停在 报错 点上  ctrl + 1
			 */
			try {
				c.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

}

测试

建表语句

create table Student(
     Sno int not null auto_increment primary key,
     Sname varchar(10) not null,
     Sex char(1) not null,
     Sage tinyint(100) not null,
     Sdept char(4) not null)comment = '学生表';
		 

insert into Student (Sname, Sex, Sage, Sdept) values ('李勇', '男', 20, 'CS');
insert into Student (Sname, Sex, Sage, Sdept) values ('刘晨', '女', 19, 'CS');
insert into Student (Sname, Sex, Sage, Sdept) values ('王敏', '女', 18, 'MA');
insert into Student (Sname, Sex, Sage, Sdept) values ('张立', '男', 19, 'IS');

COMMIT;
SELECT * FROM Student;

结果
在这里插入图片描述

test.java

package MySQL;

import java.util.List;
import java.util.Map;

public class test {
    public static void main(String[] args) {
        DBHelper dbHelper = new DBHelper();
        //查询数据
        List<Map<String, Object>> list = dbHelper.query("select * from Student;");
        //UPDATE <表名> SET 字段 1=值 1 [,字段 2=值 2… ] [WHERE 子句 ]
        System.out.println(list);

        //修改数据
        String sql = "update Student set sex= ? where sno=?";
        dbHelper.update(sql,"女","1");
        List<Map<String, Object>> list2 = dbHelper.query("select * from Student;");
        System.out.println(list2);

        //增加数据INSERT INTO <表名> [ <列名1> [ , … <列名n>] ] VALUES (值1) [… , (值n) ];
        sql = "insert into Student (Sname, Sex, Sage, Sdept) values (?, ?, ?, ?)";
        dbHelper.update(sql,"蔡碧", "男", "12","CN");
        List<Map<String, Object>> list3 = dbHelper.query("select * from Student;");
        System.out.println(list3);

        //删除数据 DELETE FROM <表名> [WHERE 子句] [ORDER BY 子句] [LIMIT 子句]
        sql = "delete from Student where sno = ?";
        dbHelper.update(sql,2);
        List<Map<String, Object>> list4 = dbHelper.query("select * from Student;");
        System.out.println(list4);

    }

}

输出结果

SQL: select * from Student;
参数: []
[{Sno=1, Sname=李勇, Sex=男, Sage=20, Sdept=CS}, {Sno=2, Sname=刘晨, Sex=女, Sage=19, Sdept=CS}, {Sno=3, Sname=王敏, Sex=女, Sage=18, Sdept=MA}, {Sno=4, Sname=张立, Sex=男, Sage=19, Sdept=IS}]
SQL: update Student set sex= ? where sno=?
参数: [女, 1]
SQL: select * from Student;
参数: []
[{Sno=1, Sname=李勇, Sex=女, Sage=20, Sdept=CS}, {Sno=2, Sname=刘晨, Sex=女, Sage=19, Sdept=CS}, {Sno=3, Sname=王敏, Sex=女, Sage=18, Sdept=MA}, {Sno=4, Sname=张立, Sex=男, Sage=19, Sdept=IS}]
SQL: insert into Student (Sname, Sex, Sage, Sdept) values (?, ?, ?, ?)
参数: [蔡碧, 男, 12, CN]
SQL: select * from Student;
参数: []
[{Sno=1, Sname=李勇, Sex=女, Sage=20, Sdept=CS}, {Sno=2, Sname=刘晨, Sex=女, Sage=19, Sdept=CS}, {Sno=3, Sname=王敏, Sex=女, Sage=18, Sdept=MA}, {Sno=4, Sname=张立, Sex=男, Sage=19, Sdept=IS}, {Sno=5, Sname=蔡碧, Sex=男, Sage=12, Sdept=CN}]
SQL: delete from Student where sno = ?
参数: [2]
SQL: select * from Student;
参数: []
[{Sno=1, Sname=李勇, Sex=女, Sage=20, Sdept=CS}, {Sno=3, Sname=王敏, Sex=女, Sage=18, Sdept=MA}, {Sno=4, Sname=张立, Sex=男, Sage=19, Sdept=IS}, {Sno=5, Sname=蔡碧, Sex=男, Sage=12, Sdept=CN}]

Process finished with exit code 0

在这里插入图片描述

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值