JDBC—问题总结

题目要求

数据库表结构(Oracle 11g)

代码实现1:插入一个新的student 信息

请输入考生的详细信息
Type:IDCard:ExamCard:StudentName:Location:Grade:

代码实现2:在 eclipse中建立 java 程序:输入身份证号或准考证号可以查询到学生的基本信息。
  • 构建学生类
package OracleT;

public class student {
	private long FLOWID;
    private long TYPE;
    private String IDCARD;
    private String EXAMCARD;
    private String STUDENTNAME;
    private String LOCATION;
    private int GRADE;
	
    public student() {
		super();
	}
	public student(long fLOWID, long tYPE, String iDCARD, String eXAMCARD, String sTUDENTNAME, String lOCATION,
			int gRADE) {
		super();
		FLOWID = fLOWID;
		TYPE = tYPE;
		IDCARD = iDCARD;
		EXAMCARD = eXAMCARD;
		STUDENTNAME = sTUDENTNAME;
		LOCATION = lOCATION;
		GRADE = gRADE;
	}
	
	public Long getFLOWID() {
		return FLOWID;
	}
	public void setFLOWID(int fLOWID) {
		FLOWID = fLOWID;
	}
	public Long getTYPE() {
		return TYPE;
	}
	public void setTYPE(int tYPE) {
		TYPE = tYPE;
	}
	public String getIDCARD() {
		return IDCARD;
	}
	public void setIDCARD(String iDCARD) {
		IDCARD = iDCARD;
	}
	public String getEXAMCARD() {
		return EXAMCARD;
	}
	public void setEXAMCARD(String eXAMCARD) {
		EXAMCARD = eXAMCARD;
	}
	public String getSTUDENTNAME() {
		return STUDENTNAME;
	}
	public void setSTUDENTNAME(String sTUDENTNAME) {
		STUDENTNAME = sTUDENTNAME;
	}
	public String getLOCATION() {
		return LOCATION;
	}
	public void setLOCATION(String lOCATION) {
		LOCATION = lOCATION;
	}
	public int getGRADE() {
		return GRADE;
	}
	public void setGRADE(int gRADE) {
		GRADE = gRADE;
	}
	
	@Override
	public String toString() {
		return "Student [FLOWID=" + FLOWID + ", TYPE=" + TYPE + ", IDCARD=" + IDCARD + ", EXAMCARD=" + EXAMCARD
				+ ", STUDENTNAME=" + STUDENTNAME + ", LOCATION=" + LOCATION + ", GRADE=" + GRADE + "]";
	}
}
  • 构建工具类
package OracleT;

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.sql.*;
import java.sql.SQLException;
import java.util.Map;
import java.util.Properties;

import org.junit.Test;

import com.sun.org.apache.xml.internal.utils.IntVector;



public class oracleTool {
	@Test
	//连接方法
	public static Connection oracle() throws SQLException, IOException, ClassNotFoundException {
		InputStream in = oracleTool.class.getClassLoader().getResourceAsStream("jdbc.properties");
		Properties p = new Properties();
		p.load(in);
		
		String url = p.getProperty("oracle.url");
		String user = p.getProperty("oracle.user");
		String password = p.getProperty("oracle.password");
		String drivername = p.getProperty("oracle.driver");
		
		Class.forName(drivername);
        Connection conn = DriverManager.getConnection(url, user, password);
        System.out.println(conn);
		System.out.println("connection successful");

		in.close();
        
        return conn;
	}
	//查询方法
	public <T> T searchOracle(String ID, Class<T> clazz) throws Throwable {
		T t = null;
		String sql = "select * from examstudent where IDCard = ?";
		BigDecimal big = null;
		PreparedStatement psta = oracleTool.oracle().prepareStatement(sql);
		psta.setString(1, ID);
		ResultSet rs = psta.executeQuery();
		ResultSetMetaData rsmd = rs.getMetaData();
		while(rs.next()) {
		    t = clazz.newInstance();
		    for(int i = 1 ; i <= rsmd.getColumnCount();i++) {
			    String label = rsmd.getColumnLabel(i);
			    Field field = clazz.getDeclaredField(label);
			    field.setAccessible(true);
			    if(rs.getObject(i) instanceof BigDecimal) {
			    	big = (BigDecimal) rs.getObject(i);
			    	field.set(t, big.intValue()); 
			    }
			    else{
			    	field.set(t, rs.getObject(i)); 
			    }
			}	
		}
		rs.close();
		psta.close();
		return t;
	}
	//删除方法
	public void deleteOracle(String ID) throws Throwable, SQLException, IOException {
		String sql = "delete from examstudent where IDCard = ?";
		
		PreparedStatement psta = oracleTool.oracle().prepareStatement(sql);
		psta.setString(1, ID);
		if(psta.execute()) {
			System.out.println("delete successfully");
		}
		else {
			System.out.println("failed");
		}
	}
	//增添方法
	public void addOracle(Map<?, ?> map) throws Throwable, SQLException, IOException {
		String sql = "insert into examstudent(Type,IDCard,ExamCard,StudentName,Location,Grade) values (?,?,?,?,?,?)";
		
		PreparedStatement psta = oracleTool.oracle().prepareStatement(sql);

		psta.setObject(1, map.get("type"));
		psta.setObject(2, (String)map.get("idcard"));
		psta.setObject(3, (String)map.get("examcard"));
		psta.setObject(4, (String)map.get("studentname"));
		psta.setObject(5, (String)map.get("location"));
		psta.setObject(6, map.get("grade"));
		if(psta.executeUpdate() == 1) {
			System.out.println("add successfully");
		}
		else {
			System.out.println("failed");
		}
		psta.close();
	}
}
  • 测试类
package OracleT;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

public class tset {
	public static void main(String[] args) throws Throwable {
		Scanner sc = new Scanner(System.in);
		System.out.println("选择操作类型:a=查找,b=删除,c=添加");
		String choice = sc.next();
		switch(choice) {
			case "a" : {
				System.out.println("输入查询类型"+"\n"+"A:准考证号"+"\n"+"B:身份证号");
				String aim = sc.next(); 
				String ID = null;
				if(aim.toUpperCase().equals("A")) {
					System.out.println("请输入准考证号");
					ID = sc.next();
				}
				else if(aim.toUpperCase().equals("B")) {
					System.out.println("请输入身份证号");
					ID = sc.next();
				}
				else {
					System.out.println("输入错误");
				}
				oracleTool or = new oracleTool();
				student s = or.searchOracle(ID, student.class);
				if(s != null)
					System.out.println(s.toString());
				else
					System.out.println("NULL");

			};break;
			case "b":{
				System.out.println("请输入准考证号=");
				String ID = sc.next();
				oracleTool or = new oracleTool();
				or.deleteOracle(ID);
			};break;
			case "c":{
				Map<String, Object> map = new HashMap<String, Object>();
				System.out.println("请输入考试等级:");
				Long type=sc.nextLong();				
				map.put("type", type);
				System.out.println("请输入身份证号:");
				String idcard=sc.next();
				map.put("idcard", idcard);
				System.out.println("请输入考试证号:");
				String examcard=sc.next();
				map.put("examcard", examcard);
				System.out.println("请输入学生姓名:");
				String studentname=sc.next();
				map.put("studentname", studentname);
				System.out.println("请输入所在地:");
				String location=sc.next();
				map.put("location", location);
				System.out.println("请输入考生成绩:");
				int grade=sc.nextInt();
				map.put("grade", grade);
				oracleTool or = new oracleTool();
				or.addOracle(map);
			};break;
			default:break;
		}
		sc.close();
	}
}

在此程序最终程序之前遇到的错误编号:

  • Exception in thread “main” java.lang.IllegalArgumentException: Can not set long field OracleT.student.FLOWID to java.math.BigDecimal

具体问题出在返回值类型的转换上,当ResultSet返回的数据为多种类型时,我最初选择的是直接ResultSet.getObject();,将数据类型全部提升为父类,这样兼容了最大的类型,但失去了数据间的独特性,并且需要注意的是,数据库和客户端之间的数据传输存在着类型的变化,如下:
在这里插入图片描述题目中有数据库数据类型number长达是10,意味着传递回来的数据为BigDecial类型,方法将其类型升级为父类类型Object,为多态的表现(父类引用子类的对象),

  • Exception in thread “main” java.lang.NoSuchFieldException: FLOWID

这是反射问题,问题在于数据库的字段与定义类的相应数据名称不匹配,Java严格区分大小写,但数据库并不是,数据库中的相应数据字段无论在定义的时候是大小写,在输出时候(getColumnName(i))都会变为全部大写的格式,这意味我们需要在自定义类中将相应的部分大写,以此来匹配返回的字符段。或者使用列的别名来间接匹配字段,此时在反射中使用相应的方法(getColumnLabel(i))返回别名来匹配自定义类。我看网上还有说空格的,可能也会吧。
还可能是因为,在创建某一私有属性时未使用getDeclaredField()方法

  • ORA-04098 触发器无效且未通过验证

在自定义创表的时候,我并没有加入触发器和序列,

create table examstudent (
       FlowID number(10) primary key,
       TestType number(10) not null,
       IDCard varchar2(18) not null,
       ExamCard varchar2(15) not null,
       StudentName varchar2(20) not null,
       Location varchar2(20) not null,
       Grade number(10) not null    
);
//后加的触发器
create or replace trigger EXA_TIG
	  before insert on EXAMSTUDENT 
	  for each row
declare
  -- local variables here
begin
	  select EXA_SEQ.NEXTVAL into :NEW.FLOWID from dual;
end EXA_TIG;

新创建的触发器之后可能在列表中找不到,需要刷新列表或者对象列表里切换个用户,在Tigger或者对应用户文件下的Tigger里寻找触发器配置

  • ORA-01400 无法将NULL值插入

此问题我现在无法复现了,但原因为设置了非空约束后,传入的值未正确存在相应的位置,导致了向数据库传输的时候为NULL。

  • ORA-00904 标识符无效

此问题的原因在数据查询时字段的格式不正确。在数据库中查询一个varchar数据时,是否使用‘’都可以查询在这里插入图片描述在这里插入图片描述
对于在客户端的查询不需要考虑那么多,加上’'反而得不到结果
String sql = “select * from examstudent where IDCard = ?”;
BigDecimal big = null;
PreparedStatement psta = oracleTool.oracle().prepareStatement(sql);
psta.setString(1, “’”+ID+"’"); 没有意义的考虑,乱加反而可能导致本部分的错误,无效标识符

  • ORA-00913 too many values

此问题是因为在使用PreparedStatement 的时候,我们将需要查询的部分通过?占位符来替代,但可能由于数量超过了最大的定义数量,(主键是被序列和触发器来处理),所以注意
String sql = “insert into examstudent(Type,IDCard,ExamCard,StudentName,Location,Grade) values (?,?,?,?,?,?)”;要查询数量和?的数量匹配。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值