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

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

全部评论

相关推荐

数学转码崽:一直给我推,投了又不理,理了又秒挂
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务