题目要求
数据库表结构(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 (?,?,?,?,?,?)”;要查询数量和?的数量匹配。