这次有个任务,需要用java的图形用户界面来实现一个后台管理系统。我大概在网上随便找了一个类似于这个后台管理的框架(真的只是框架,一个登陆的窗口,一个用户管理的非常简单的页面),然后内部的事务逻辑均属原创。
下面,就来简单介绍一下这个后台管理系统是如何实现的,以及我制作时候的内部逻辑是如何的。
- 首先,为我们的数据库连接建立一个JDBC工具类
这个工具类比较简单,其作用就是可以使得直接通过这个工具类,可以直接获得数据库链接,这样在后面不同的类去获取连接时,不需要写重复代码,只需要通过工具类就可以直接获得。
代码如下:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class JDBCUtils {
private JDBCUtils(){}
private static Connection con ;
static{
try{
Class.forName("com.mysql.jdbc.Driver"); //注册驱动,之所以用反射,这里不多解释
String url = "jdbc:mysql://localhost:3306/数据库名";
String username="数据库管理员名";
String password="数据库管理员密码";
con = DriverManager.getConnection(url, username, password); //获取数据库连接
}catch(Exception ex){
throw new RuntimeException(ex+"数据库连接失败");
}
}
/*
* 定义静态方法,返回数据库的连接对象
*/
public static Connection getConnection(){
return con;
}
/*
这个方法是用来释放资源的,原则是先得到的后关闭
因为对数据库的操作不同,所以可能会产生两种关闭的情况,所以为了以防万一需要写两种关闭的方法,后来在具体项目的实践中我发现,查询这种情况是实时存在的,所以只需要写一种方法就可以了
*/
public static void close(Connection con,Statement stat){
if(stat!=null){
try{
stat.close();
}catch(SQLException ex){}
}
if(con!=null){
try{
con.close();
}catch(SQLException ex){}
}
}
public static void close(Connection con,Statement stat , ResultSet rs){
if(rs!=null){
try{
rs.close();
}catch(SQLException ex){}
}
if(stat!=null){
try{
stat.close();
}catch(SQLException ex){}
}
if(con!=null){
try{
con.close();
}catch(SQLException ex){}
}
}
}
- 然后,我们就需要思考如何在后台管理系统中进行操作
这个过程才是真正的核心,你需要明确你的后台管理系统中包括哪些功能,在此我先将我的后台管理系统的截图发上来,咱们在好好说道这个思考的过程。
首先需要想想这个后台管理系统该是什么样子的,也就是所谓的设计一个简单的UI,然后我们看着眼前的UI在来一步步去思考该如何实现。
1)第一步,我们需要实现好查询功能,也就是上面的“公司部门”、“公司员工”等几个按钮,每一个按钮内部都包含了一个查询操作,查询的是对应的我的那个数据库的表。这里的第一行,我写的是固定的,每一个选项,对应的是不同的数值,这个数值决定了我采用那个一维字符串数组作为头部。然后就是重头戏了,我们需要决定好下面的表的内容,也就是将数据库中的表的内容呈现到这个表中。结合java Swing中表的特征,我选择了二维数组赋值的方法,为此,我在针对数据库操作的方法中,需要得到一个二维数组。
因为查询的时候,我无法获得resultset的长度,所以我采用了一个笨方法,赋值两个resultset,一个用来获取行数,一个用来给二维数组的每一个具体列赋值。其方法实现如下:
public static String[][] resultSet(int k) { //这是一个方法,可以返回一个二维数组
PreparedStatement pst = null; //声明一个预处理对象
ResultSet rs = null; //第一个resultset
ResultSet rs1 = null;
if (k == 1) { //这个针对的是第一个按钮,也就是上面的"公司部门"
int count = 1; //用来记录二维数组的行数,从而实现动态赋值
int colum = 0; //这个是来记录多少行的,但是单词好像写错了,多多担待
String sql = "select * from departments"; //查询"公司部门"对应的数据库表
try {
pst = con.prepareStatement(sql); //对sql语句进行预编译
rs = pst.executeQuery(); //执行查询语句,并得到Resultset结果集
while (rs.next()) {
colum++;
}
items = new String[colum][4]; //获取一个行数可变的二维数组
rs1 = pst.executeQuery();
while (rs1.next()) {
items[count - 1][0] = rs1.getString("department_id");
items[count - 1][1] = rs1.getString("department_name");
items[count - 1][2] = rs1.getString("manager_id");
items[count - 1][3] = rs1.getString("location_id");
count++;
}
} catch (SQLException e) {
e.printStackTrace();
}
}
这是针对第一个按钮所写的查询代码,后面的三个按钮相同,只需要该部分内容就行。
2)现在我们来实现添加功能,这个添加功能就是简单的获取四个对话框里的文本内容,然后对应查看数据库中对应的数据类型,将类型转换正确后,在进行插入操作,然后按下添加按钮后,更新图形用户界面就可以了。
public static int insert(int k, String str1, String str2, String str3, String str4) { //我设置返回值为int是为了调用这个方法时,能够判断出是否执行成功
int line = 0;
PreparedStatement stat = null;
if (k == 1) {
String sql = "insert into departments(department_id,department_name,manager_id,location_id) values(?,?,?,?)"; //利用占位符,
try {
stat = con.prepareStatement(sql);
int did = Integer.parseInt(str1); //经过数据库中表的列的类型查询得知,这三个列的类型是int类型,因此需要在替换占位符前,先替换数据类型
int mid = Integer.parseInt(str3);
int lid = Integer.parseInt(str4);
stat.setInt(1, did); //替换占位符
stat.setString(2, str2);
stat.setInt(3, mid);
stat.setInt(4, lid);
// 5执行SQL语句
line = stat.executeUpdate(); //执行sql语句,如果执行成功,会返回影响的行数(代表插入了几行),肯定会是1,这是你就可以判断自己的数据插入成功了
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
3)下面,我们再来执行修改操作,这个操作会涉及到一定的Swing中的方法,就是获取你所点击的行的数据,并赋值给下面的几个text框中,当然,你也可以根据第一列的id号直接修改,因为你的sql操作可以做到运行这样修改。
在此,我先将那个获取点击行的内容的代码po出来:
table.addMouseListener(new MouseAdapter() { //鼠标事件
public void mouseClicked(MouseEvent e) {
int selectedRow = table.getSelectedRow(); //获得选中行索引
Object oa = tableModel.getValueAt(selectedRow, 0);
Object ob = tableModel.getValueAt(selectedRow, 1);
Object oc = tableModel.getValueAt(selectedRow, 2);
Object od = tableModel.getValueAt(selectedRow, 3);
try {
aTextField.setText(oa.toString()); //给文本框赋值
bTextField.setText(ob.toString());
cTextField.setText(oc.toString());
}catch (NullPointerException ex){
cTextField.setText("");
throw new RuntimeException(ex+"遇到了空字符串");
}finally {
dTextField.setText(od.toString());
}
}
});
大家或许会对我这几行代码中的try、catch、finally这个用法不太理解,其实他们不具有通用性,它是针对我第一个截图中的有几行第三列数据为空的情况而存在的。
这段获取值的方法写完后,可以直接在文本框内修改其值,但是注意id号千万不能修改,它是我们SQL语句中执行修改的关键,sql相关操作的代码如下:
public static int update(int k, String str1, String str2, String str3, String str4) {
int line = 0;
PreparedStatement stat = null;
if (k == 1) {
String sql = "update departments set department_name=?,manager_id=?,location_id=? where department_id=?";
try {
stat = con.prepareStatement(sql);
int did = Integer.parseInt(str1);
int mid = Integer.parseInt(str3);
int lid = Integer.parseInt(str4);
stat.setString(1, str2);
stat.setInt(2, mid);
stat.setInt(3, lid);
stat.setInt(4, did);
// 5执行SQL语句
line = stat.executeUpdate();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
这里的代码就不做过多解释了,基本和上面的重复,注意占位符的位置就行。
4)好,现在我们来执行最后一个事务,那就是删除,我认为这个是最简单最轻松的了,直接获取第一个id号,然后执行sql语句进行删除就可以了,代码和上面的几乎都差不多,只会更简单,在此不再过多赘述了。
5)最后的最后,我在简单放一下我的信息统计的页面,他这个其实也要查询,但是需要单独写一段查询代码,但是本质还是一样的!
这个其实代码写起来十分简单,只是查询的次数相对来说比较多而已。
if (k == 5) {
String sql = "SELECT count(*) departments FROM departments";
try {
pst = con.prepareStatement(sql);
rs = pst.executeQuery();
items = new String[1][4];
while (rs.next()) {
items[0][0] = rs.getString("departments");
}
sql = "SELECT count(*) jobs FROM jobs";
pst = con.prepareStatement(sql);
rs = pst.executeQuery();
while (rs.next()) {
items[0][1] = rs.getString("jobs");
}
sql = "SELECT count(*) employees FROM employees";
pst = con.prepareStatement(sql);
rs = pst.executeQuery();
while (rs.next()) {
items[0][2] = rs.getString("employees");
}
sql = "SELECT count(*) locations FROM locations";
pst = con.prepareStatement(sql);
rs = pst.executeQuery();
while (rs.next()) {
items[0][3] = rs.getString("locations");
}
} catch (SQLException e) {
e.printStackTrace();
}
}
6)嗯,还有个最后,不要忘记关闭资源哦,最好在后台管理系统窗口关闭的时候调用,不然提前关闭会出错。