本代码,分别使用了 “单例模式“ (其中涉及多线程问题)、 “泛型”。
PS:此项目需要手动导入以下四个jar包。
classes12.jar
commons-beanutils-1.9.2.jar
commons-collections.jar
commons-logging-1.2.jar
1、定义了一个 JDBCTool类
package com.yan.jdbc;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import org.apache.commons.beanutils.BeanUtils;
public class JDBCTool {
private static Connection conn = null;
private static PreparedStatement pres = null;
private static ResultSet rst = null;
/*
* 单例模式(懒汉式===涉及多线程问题) 1:私有的构造方法 2:私有静态的对象 3:公有的静态get方法,让对象进行实例化
*/
private JDBCTool() {
}
private static JDBCTool jdbc = null;
public static JDBCTool getJDBC() {
if (jdbc == null) {
synchronized (Class.class) {
jdbc = new JDBCTool();
}
}
return jdbc;
}
// 建立连接(运用“流”的方式从外部导入文本参数)
private Connection getConn() throws SQLException {
String driver = "";
String url = "";
String user = "";
String password = "";
File file = new File("jdbc.properties");
FileInputStream fis;
try {
fis = new FileInputStream(file);
Properties ppt = new Properties();
ppt.load(fis);
// 用properties对象从“流”中获取到各个参数的值
driver = ppt.getProperty("driver");
url = ppt.getProperty("url");
user = ppt.getProperty("user");
password = ppt.getProperty("psw");
Class.forName(driver);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return DriverManager.getConnection(url, user, password);
}
// select查询 :用“泛型”
public <T> T jdbcSelect(Class<T> clazz, String sql, Object... args) {
T entity = null;
try {
// preparedStatement方式的JDBC连接
conn = jdbc.getConn();
pres = conn.prepareStatement(sql);
for (int i = 0; i < args.length; i++) {
pres.setObject(i + 1, args[i]);
}
rst = pres.executeQuery();
/*
* 利用ResultSet的getMetaData的方法可以获得ResultSetMetaData对象,
* 而ResultSetMetaData存储了 ResultSet的MetaData。
* 所谓的MetaData在英文中的解释为“Data about Data”,直译成中文则为“有关数据的数据”或者“描述数据的数据”,
* 实际上就是描述及解释含义的数据。以Result的MetaData为例,ResultSet是以表格的形式存在,
* 所以getMetaData就包括了数据的字段名称、类型以及数目等表格所必须具备的信息。
*/
ResultSetMetaData rsmt = rst.getMetaData();
HashMap<String, Object> map = new HashMap<String, Object>();
while (rst.next()) {
// 从ResultSetMetaData对象里面获取rst结果集中的列名,跟值
for (int i = 0; i < rsmt.getColumnCount(); i++) {
String columnLableName = rsmt.getColumnLabel(i + 1);
Object columnLableValue = rst.getObject(columnLableName);
map.put(columnLableName, columnLableValue);
}
if (map.size() > 0) {
// newInstance等同于entity=new T();只是在泛型中T类是一个虚拟的,不能用new去进行实例化
entity = clazz.newInstance();
// 对map对象进行遍历(加强for循环的方式遍历)
for (Map.Entry<String, Object> entry : map.entrySet()) {
String name = entry.getKey();
Object value = entry.getValue();
BeanUtils.setProperty(entity, name, value);
}
}
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
// 释放对象
jdbc.relasedJDBC(conn, pres, rst);
}
return entity;
}
// insert delete update 增 删 改
public void jdbcUpdate(String sql, Object... args) {
try {
conn = jdbc.getConn();
pres = conn.prepareStatement(sql);
for (int i = 0; i < args.length; i++) {
pres.setObject(i + 1, args[i]);
}
pres.executeUpdate();
System.out.println("操作成功!");
} catch (Exception e) {
// TODO Auto-generated catch block
System.out.println("操作失败!请重新操作。");
} finally {
jdbc.relasedJDBC(conn, pres);
}
}
// 注销 conn,prs ,rst
private void relasedJDBC(Connection conn, PreparedStatement pres,
ResultSet rst) {
try {
if (rst != null) {
rst.close();
rst = null;
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
if (pres != null) {
pres.close();
pres = null;
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
if (conn != null) {
conn.close();
conn = null;
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// 注销 conn,prs
private void relasedJDBC(Connection conn, PreparedStatement pres) {
try {
if (pres != null) {
pres.close();
pres = null;
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
if (conn != null) {
conn.close();
conn = null;
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
2、定义一个Student类(作为实现“泛型”的例子使用)
package com.yan.jdbc;
public class Student {
private int flowID;// 流水号
private int type;// 四级/六级
private String idCard;// 身份证号码
private String examCard;// 准考证号码
private String studentName;// 学生姓名
private String location;// 区域
private int grade;// 成绩
public Student() {
super();
// TODO Auto-generated constructor stub
}
public Student(int flowID, int type, String idCard, String examCard,
String studentName, String location, int grade) {
super();
this.flowID = flowID;
this.type = type;
this.idCard = idCard;
this.examCard = examCard;
this.studentName = studentName;
this.location = location;
this.grade = grade;
}
public int getFlowID() {
return flowID;
}
public void setFLOWID(int flowID) {
this.flowID = flowID;
}
public int getType() {
return type;
}
public void setTYPE(int type) {
this.type = type;
}
public String getIdCard() {
return idCard;
}
public void setIDCARD(String idCard) {
this.idCard = idCard;
}
public String getExamCard() {
return examCard;
}
public void setEXAMCARD(String examCard) {
this.examCard = examCard;
}
public String getStudentName() {
return studentName;
}
public void setSTUDENTNAME(String studentName) {
this.studentName = studentName;
}
public String getLocation() {
return location;
}
public void setLOCATION(String location) {
this.location = location;
}
public int getGrade() {
return grade;
}
public void setGRADE(int grade) {
this.grade = grade;
}
@Override
public String toString() {
return "Student [flowID=" + flowID + ", type=" + type + ", idCard="
+ idCard + ", examCard=" + examCard + ", studentName="
+ studentName + ", location=" + location + ", grade=" + grade
+ "]";
}
}
3、测试类(其中包含一个在控制台输入相关信息的方法)
package com.yan.jdbc;
import java.util.Scanner;
import org.junit.Test;
public class JDBCTest {
@Test
public void test() {
String sql = "";
Student stu = new Student();
JDBCTool jdbc = JDBCTool.getJDBC();
JDBCTest.scannerInfo(stu);
//新增语句
sql = "insert into examstudent values(?,?,?,?,?,?,?)";
jdbc.jdbcUpdate(sql, stu.getFlowID(), stu.getType(), stu.getIdCard(),
stu.getExamCard(), stu.getStudentName(), stu.getLocation(),
stu.getGrade());
//华丽的分割线
System.out.println("===========================================");
//条件查询语句
sql ="select flowId,type,idCard,studentName,location from examStudent where flowId=?";
stu=jdbc.jdbcSelect(Student.class, sql, 23);
System.out.println(stu);
}
//控制台录入信息的方法
private static Student scannerInfo(Student stu) {
System.out.println("==========请输入录入的学生信息==========");
Scanner scan = new Scanner(System.in);
System.out.println("flowID");
stu.setFLOWID(scan.nextInt());
System.out.println("type");
stu.setTYPE(scan.nextInt());
System.out.println("idCard");
stu.setIDCARD(scan.next());
System.out.println("examCard");
stu.setEXAMCARD(scan.next());
System.out.println("studentName");
stu.setSTUDENTNAME(scan.next());
System.out.println("location");
stu.setLOCATION(scan.next());
System.out.println("grade");
stu.setGRADE(scan.nextInt());
return stu;
}
}