這次課設(shè)題目自選,我選擇學(xué)生管理系統(tǒng)。今天主要做數(shù)據(jù)庫(kù)和表的建立。首先第一步,是建立數(shù)據(jù)庫(kù)用戶(hù):設(shè)置用戶(hù)和密碼,并且建立數(shù)據(jù)庫(kù)studentmanager,在工程中導(dǎo)入驅(qū)動(dòng):mysql-connector-java-版本號(hào)-bin.jar(導(dǎo)入驅(qū)動(dòng)jar包的方式是:工程屬性->java build path->libraries->add external jar)
JDBC(Java DataBase Connectivity,java數(shù)據(jù)庫(kù)連接)是執(zhí)行sql語(yǔ)句的java API。我們可以通過(guò)加載驅(qū)動(dòng)和連接數(shù)據(jù)庫(kù),執(zhí)行sql語(yǔ)句對(duì)表進(jìn)行增、刪、查、改。首先驅(qū)動(dòng)的加載是通過(guò):
Class.forName("com.mysql.jdbc.Driver");
數(shù)據(jù)庫(kù)的連接:
Connection c = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/studentmanager?characterEncoding=UTF-8","root","admin");
參考博客:
瘋狂JavaJDBC:加載數(shù)據(jù)庫(kù)驅(qū)動(dòng)、連接數(shù)據(jù)庫(kù)
創(chuàng)建studentmanager數(shù)據(jù)庫(kù),建立9個(gè)表:

為了方便以后插入中文字符,將字符集修改為UTF-8的格式:

數(shù)據(jù)表創(chuàng)建成功后,數(shù)據(jù)庫(kù)中還沒(méi)有實(shí)際的數(shù)據(jù)。為了保證外部鍵能使用,數(shù)據(jù)需要提前輸入,如院系編號(hào),班級(jí)編號(hào),學(xué)籍變更代碼和獎(jiǎng)懲級(jí)別等等。下面是change_code(學(xué)籍變更代碼)表:

reward_leves獎(jiǎng)勵(lì)級(jí)別代碼表:

處罰級(jí)別代碼表:

班級(jí)表:

院系表:

在已有的表中添加外鍵時(shí)出現(xiàn)下面問(wèn)題:

解決辦法:
出現(xiàn)錯(cuò)誤的原因是,兩個(gè)表的字段之間的屬性不一致.
參考資料:
使用mysql-front添加外鍵 失敗
環(huán)境弄好了,下面來(lái)實(shí)現(xiàn)一些基本的數(shù)據(jù)庫(kù)操作,包括增刪差改.先新建一個(gè)student類(lèi),包含很多屬性:學(xué)號(hào)(即ID號(hào)),姓名,生日,籍貫,院系代碼,班級(jí)編號(hào).

整個(gè)student表有關(guān)操作,通過(guò)TestDAO類(lèi)實(shí)現(xiàn):

數(shù)據(jù)庫(kù)的增:
public void add(Student h) {
String sql = "insert into hero Values(?,?,?,?,?,?,?)";
try (Connection c = getConnection();
PreparedStatement s = c.prepareStatement(sql);
){
String ID = h.studentID;
String name = h.name;
String sex = h.sex;
String birthday = h.birthday;
String department = h.department;
String native_place = h.native_place;
String Class = h.Class;
//設(shè)置參數(shù)
s.setString(2, name);
s.setString(1, ID);
s.setString(3, sex);
s.setString(4, Class);
s.setString(5, department);
s.setString(6, birthday);
s.setString(7, native_place);
//執(zhí)行語(yǔ)句
s.execute();
System.out.println("數(shù)據(jù)插入成功!");
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
- 其中,preparedstatement是預(yù)編譯語(yǔ)句,我們可以用他來(lái)執(zhí)行sql語(yǔ)句.例如上面的
insert into hero Values(?,?,?,?,?,?,?),然后我們依次將各字段的值通過(guò)preparedstatement指定插入的位置.例如ID插入一個(gè)位置,name插入第二個(gè)位置......這樣就把要增加的學(xué)生(student)對(duì)象插入到了student表中.這里順便說(shuō)下preparedstatement比statement的優(yōu)點(diǎn)在于,可以在以后很方便的根據(jù)位置進(jìn)行插入數(shù)據(jù). - 使用try-with-catch的形式,
try (Connection c = getConnection(); PreparedStatement s = c.prepareStatement(sql); )可以實(shí)現(xiàn)自動(dòng)關(guān)閉連接,就不用手動(dòng)的關(guān)閉,非常方便.
插入代碼:
TestDAO test = new TestDAO();
Student stu = new Student();
stu.birthday="19970409";
stu.studentID = "1605050217";
stu.department="1";
stu.native_place="衡陽(yáng)";
stu.sex="男";
stu.Class = "2";
stu.name = "蔣政濤";
test.add(stu);
結(jié)果:

如果外鍵的表中為空,則會(huì)出現(xiàn)插入錯(cuò)誤.所以一定要建立外鍵的表,先進(jìn)行賦值.
數(shù)據(jù)庫(kù)的刪:
//把這個(gè)student 對(duì)象對(duì)應(yīng)的數(shù)據(jù)刪除掉
public void delete(String id) {
String sql = "delete from hero where id = ?";
try(Connection c = getConnection();
PreparedStatement s = c.prepareStatement(sql);
) {
//設(shè)置參數(shù)
s.setString(1,id);
//System.out.println(h.id);
ResultSet rs = s.executeQuery("select id from student where id = "+id);
if(!rs.next()) {
System.out.println("數(shù)據(jù)庫(kù)中并沒(méi)有這個(gè)數(shù)據(jù)!");
return;
}
//執(zhí)行
s.execute();
System.out.println("數(shù)據(jù)刪除成功!");
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
這里在刪之前會(huì)進(jìn)行檢查,ResultSet rs = s.executeQuery("select id from student where id = "+id);根據(jù)id查找后如果發(fā)現(xiàn)rs為空則說(shuō)明表中沒(méi)有這個(gè)id,則提示:"數(shù)據(jù)庫(kù)中并沒(méi)有這個(gè)數(shù)據(jù)!",如果有則s.execute();刪除數(shù)據(jù).并且提示刪除成功!
然后通過(guò)next()方法遍歷這個(gè)set集合.
根據(jù)studentID刪除學(xué)生記錄:test.delete("1605050217");
結(jié)果:

查:
//根據(jù)id返回一個(gè)student對(duì)象
public Student get(String id) {
Student h = null;
try(Connection c = getConnection();
Statement s = c.createStatement();) {
ResultSet rs = s.executeQuery("select * from student where studentID = "+id);
if(rs.next()) {
h = new Student();
h.studentID = id;
h.name = rs.getString(2);
h.birthday = rs.getString(6);
h.Class = rs.getString(4);
h.department = rs.getString(5);
h.native_place = rs.getString(7);
h.sex = rs.getString(3);
}
else {
System.out.println("數(shù)據(jù)庫(kù)中沒(méi)有這個(gè)學(xué)生!");
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return h;
}
通過(guò)查找id號(hào),返回student對(duì)象,如果沒(méi)有則提示"數(shù)據(jù)庫(kù)中沒(méi)有這個(gè)學(xué)生" ,并且返回的是一個(gè)null空值.
改:為了適應(yīng)不同字段的更改,update方法的參數(shù)干脆就是一個(gè)student對(duì)象,通過(guò)學(xué)生的studentID找到記錄,然后通過(guò)update的sql語(yǔ)句對(duì)整條記錄進(jìn)行更新.
public void update(Student h) {
String sql = "update student set name = ?,sex = ?,class=? ,department=?,birthday = ?,native_place=? where studentID = ? ";
try(Connection c = getConnection();
PreparedStatement s = c.prepareStatement(sql);
) {
String id = h.studentID;
String name = h.name;
String sex = h.sex;
String birthday = h.birthday;
String department = h.department;
String Class = h.Class;
String native_place = h.native_place;
s.setString(7, id);
s.setString(1, name);
s.setString(2, sex);
s.setString(3, Class);
s.setString(4, department);
s.setString(5, birthday);
s.setString(6, native_place);
//執(zhí)行語(yǔ)句
s.execute();
System.out.println("數(shù)據(jù)更新成功!");
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
例如,
TestDAO test = new TestDAO();
Student stu = new Student();
stu.birthday="19980x0x";
stu.studentID = "1605050217";
stu.department="1";
stu.native_place="長(zhǎng)沙";
stu.sex="男";
stu.Class = "2";
stu.name = "xxy";
test.update(stu);
結(jié)果如下

再查
public List<Student> list(int start, int count) {
// TODO Auto-generated method stub
List<Student> students = new ArrayList<>();
String sql = "select * from student order by studentID asc limit ?,? ";
try(Connection c = getConnection();
PreparedStatement ps = c.prepareStatement(sql);
) {
ps.setInt(1, start);
ps.setInt(2, count);
ResultSet rs = ps.executeQuery();
while(rs.next()) {
Student h = new Student();
h.studentID = rs.getString(1);
h.name = rs.getString(2);
h.sex = rs.getString(3);
h.Class = rs.getString(4);
h.department = rs.getString(5);
h.birthday = rs.getString(6);
h.native_place = rs.getString(7);
students.add(h);
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return students;
}
以升序asc,從start個(gè)元組開(kāi)始,一共count個(gè)元組.并返回列表.這里要注意的是,元組下標(biāo)計(jì)數(shù)是從0開(kāi)始的.看下面的例子,從第二個(gè)元組開(kāi)始數(shù),一共4個(gè)元組:
TestDAO test = new TestDAO();
List<Student> list = test.list(2,4);
for(Student s:list) {
System.out.println(s.studentID);
}
結(jié)果如下:

參考資料:
How2j的java教程
后文
JDBC這部分,開(kāi)學(xué)那段時(shí)間擼了一下,時(shí)隔這么久了,有點(diǎn)忘記了. 鑒于學(xué)校機(jī)房各種卡,下午直接拿自己的電腦在機(jī)房擼,我的位置風(fēng)水很好,老師的水瓶啥東西都往我這放,時(shí)不時(shí)關(guān)心我的網(wǎng)速,(我的內(nèi)心是奔潰的..半天網(wǎng)頁(yè)也打不開(kāi)).我這部分估計(jì)幾天就可以擼完了,到時(shí)測(cè)試的時(shí)候,老師你別雞蛋里挑骨頭啊...
END

