通过JDBC实现查询学生信息
创建配置文件减少程序的耦合性 , 把需要修改的数据封装进去 , 后面需要更改某些信息时更快的修改完成 , 而不需要直接修改类加粗样式
#配置文件
drivermanager=java.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/test?usecharacter=true&utd-8
user=root
password=1234
1.创建连接方法
- 调用类加载器getSystemClassLoader().getResourceAsStream()获得配置文件
- 创建new Properties()实例 , Load()加载配置文件
- 通过properties.getProperty();获取配置信息并存储在变量里
- 调用Class.forName创建驱动的反射类
- 通过DriverManager的getConnection方法连接数据库
public class JDBCUtils {
// 封装3个连接信息,1个驱动 给这个类
public static Connection getConnection() throws Exception{
//1.加载类,读取配置文件
InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream("properties");
//2.实例化properties,也可以通过反射创建
Properties properties = new Properties();
//3.读取加载类里面值
properties.load(is);
//4.获取值
String drivermanager = properties.getProperty("drivermanager");
String url = properties.getProperty("url");
String user = properties.getProperty("user");
String password = properties.getProperty("password");
//5.创建驱动类的反射
Class.forName(drivermanager);
java.sql.Connection connection = DriverManager.getConnection(url, user, password);
return connection;
}
//将关闭资源封装在当前类里
public static void closeResource(Connection conn, PreparedStatement ps, ResultSet rs){
if (conn!=null){
try {
conn.close();
}catch (SQLException e){
e.printStackTrace();
}
}
if (ps!=null){
try {
ps.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (rs!=null){
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
examStudent类
- ORM思想
- 一个数据表对应一个java类
- 表中的一条记录对应java类的一个对象
- 表中的一个字段对应java类的一个属性
public class examStudent {
private int flowid;
private int type;
private String idcard;
private String examcard;
private String studentname;
private String location;
private int grade;
@Override
public String toString() {
return "{"+
"流水号=" + flowid +"\n"+
", 等级=" + type +"\n"+
", 身份证号='" + idcard + '\'' +"\n"+
", 准考证号='" + examcard + '\'' +"\n"+
", 学生姓名='" + studentname + '\'' +"\n"+
", 地址='" + location + '\'' +"\n"+
", 分数='" + 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;
}
public examStudent() {
}
public examStudent(int flowid, int type, String idcard, String examcard, String studentname, String location, int grade) {
this.flowid = flowid;
this.type = type;
this.idcard = idcard;
this.examcard = examcard;
this.studentname = studentname;
this.location = location;
this.grade = grade;
}
}
2. 选择身份证号或者准考证号查询学生信息
- 创建方法返回值类型是examStudent类
- 使用Scanner方法获取控制台输入的内容
- 选择查询的类型
- 连接数据库,预编译语句,提交查询
- 如果结果集有下一行则执行遍历总字段数
- getObject 获取每个字段数,getColumnLabel获取每个字段名
- 获取后值返回给实例
如果要查询多行则不能用实例进行存储,需要使用ArrayList或者Vector
public class lesson03 {
public static void main(String[] args) {
examStudent examstudent = idCardQuery();
System.out.println("==========查询结果==========");
System.out.println(examstudent.toString()); //方式1:使用toString输出!
//System.out.println(examstudent); //方式2:直接调用实例输出
}
//题目: 选择身份证号或者准考证号查询学生信息
public static examStudent idCardQuery() {
//1.创建scanner实例
System.out.println("请选择您要查询的类型: ");
Scanner scann = new Scanner(System.in);
System.out.println("a: 准考证号");
System.out.println("b: 身份证号");
//扩大作用域,好让关闭资源调用
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
examStudent es;
try {
//使用while循环
while(true){
String card = scann.next();
//如果等于a
if (card.equals("a")){
System.out.print("请输入准考证号: ");
String examCard = scann.next(); //输入准考证号存入 examCard
conn = JDBCUtils.getConnection(); //链接sql数据库
//创建sql语法,(问号)代表着替换符,有几个就按几个迭代
String sql = "select flowid,`type`,idcard,examcard,studentname,location,grade from examstudent where examcard=?";
ps = conn.prepareStatement(sql); //预编译语句得到prepareStatement
ps.setObject(1,examCard); //有一个替换符那就是1的索引,填充的内容是 examCard输入的值
rs = ps.executeQuery(); //提交查询语句,获得结果集
ResultSetMetaData md = rs.getMetaData(); //通过结果集获得元数据,可以查询字段名/参数类型/长度
int columnCount = md.getColumnCount(); //获得字段的总数
es = new examStudent(); //新建一个 examStudent实例
//如果结果集有下一行
if (rs.next()){
//遍历
for (int i = 0; i < columnCount; i++) {
Object columnValue = rs.getObject(i + 1); //每次遍历1个字段值
String columnLabel = md.getColumnLabel(i + 1); //每次遍历字段i+1个字段的名字
//反射获取属性
Field field = examStudent.class.getDeclaredField(columnLabel); //这里数据库里的字段名要与examStudent匹配
field.setAccessible(true); //安全访问默认为:false,最好设置为:true
field.set(es,columnValue);
}
return es; //返回给实例
}else { //如果输入的不是数据库里的准考证号,返回到重新输入
System.out.println("查无此人!请重新输入");
continue;
}
}else if(card.equals("b")){
//something...
System.out.print("请输入身份证号: ");
String idCard = scann.next();
conn = JDBCUtils.getConnection();
String sql = "select flowid,`type`,idcard,examcard,studentname,location,grade from examstudent where idcard=?";
ps = conn.prepareStatement(sql);
ps.setObject(1,idCard);
rs = ps.executeQuery();
ResultSetMetaData md = rs.getMetaData();
int columnCount = md.getColumnCount();
es= new examStudent();
if (rs.next()){
for (int i = 0; i < columnCount; i++) {
Object columnValue = rs.getObject(i + 1);
String columnLabel = md.getColumnLabel(i + 1);
Field field = examStudent.class.getDeclaredField(columnLabel);
field.setAccessible(true);
field.set(es,columnValue);
}
return es;
}else {
System.out.println("查无此人!请重新输入");
continue;
}
}else {
System.out.println("您的输入有误!请重新启动程序!");
break;
}
}
} catch (Exception e) {
e.printStackTrace();
}finally {
JDBCUtils.closeResource(conn,ps,rs);
}
return null;
}
}
优化方案1:
- 把无需分离的代码合并成一块
- 如果不想通过其他方法填写实参,可以把sql语句放进if语句里
//优化查询方案1
public static examStudent idCardQuery1(){
//创建scanner实例
System.out.println("请选择您要查询的类型: ");
Scanner scann = new Scanner(System.in);
System.out.println("a: 准考证号");
System.out.println("b: 身份证号");
//扩大作用域,好让关闭资源调用
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
examStudent es;
String sql = null;
try {
//使用while循环
while(true){
String card = scann.next();
//如果等于a
if (card.equals("a")){
System.out.print("请输入准考证号: ");
sql = "select flowid,`type`,idcard,examcard,studentname,location,grade from examstudent where examcard=?";
}else if(card.equals("b")){
System.out.print("请输入身份证号: ");
sql = "select flowid,`type`,idcard,examcard,studentname,location,grade from examstudent where idcard=?";
}else {
System.out.println("您的输入有误!请重新启动程序!");
break;
}
conn = JDBCUtils.getConnection(); //链接sql数据库
ps = conn.prepareStatement(sql);
String Card = scann.next(); //输入号码存入 Card
ps.setObject(1,Card); //有一个替换符那就是1的索引,填充的内容是 Card输入的值
rs = ps.executeQuery(); //提交查询语句,获得结果集
ResultSetMetaData md = rs.getMetaData(); //通过结果集获得元数据,可以查询字段名/参数类型/长度
int columnCount = md.getColumnCount(); //获得字段的总数
es = new examStudent(); //新建一个 examStudent实例
//如果结果集有下一行
if (rs.next()){
//遍历
for (int i = 0; i < columnCount; i++) {
Object columnValue = rs.getObject(i + 1); //每次遍历1个字段值
String columnLabel = md.getColumnLabel(i + 1); //每次遍历字段i+1个字段的名字
//反射获取属性
Field field = examStudent.class.getDeclaredField(columnLabel); //这里数据库里的字段名要与examStudent匹配
field.setAccessible(true); //安全访问默认为:false,最好设置为:true
field.set(es,columnValue);
}
return es; //返回给实例
}else { //如果输入的不是数据库里的号码,返回到重新输入
System.out.println("查无此人!请重新输入");
continue;
}
}
} catch (Exception e) {
e.printStackTrace();
}finally {
JDBCUtils.closeResource(conn,ps,rs);//关闭资源
}
return null;
}
控制台实际操作: 优化方案1
情况1:输入错误查询字母
情况2:输入错误的准考证号会重新查询,但没有提升要输入查询的类型
把 System.out.println(“a: 准考证号”); System.out.println(“b: 身份证号”);写入while循环就可以解决
情况3: 输入正确的类型与号码