上次将PL/SQL实现的功能已经写完了,接下来要写的是利用Java连接Oracle数据库并且做出一些可视化的界面,实现用户的交互,用户可以通过用户名和密码登录到这个空间数据库管理系统,并且可以点击相应的功能按钮实现查询功能。
一、最终实现成果
采用Java高级语言实现可视化功能界面,并实现5个输入输出的交互功能,同时在地图上对相应的地点进行显示,设置的界面一共包含8个,分别为1个登录界面、1个主功能界面、5个子功能界面以及1个输出界面,并且每一个界面对应一个类,采用Eclipse以及Java的Swing包开发,结合ArcMap进行地图的可视化显示。主要的实现步骤如下:
1、登录界面与主功能界面实现
首先进行输入数据库的用户名和密码,如果用户名和密码匹配,则可以成功的登录到“安徽省宿州市空间数据库管理系统”,登录的界面如下:
当登录成功之后,点击确定按钮即可跳转到主功能列表界面,从界面可以看出一共有5个功能并分别对应5个按钮,当我们点击相应的功能按钮就会跳转到相应的功能界面。
2、功能1(房地产)
对于功能1,当点击主功能界面上的“房地产”功能按钮,就会弹出如下图所示的功能界面,接下来输入相应的参数,点击查询即可。
下图即为功能1查询结果的地图可视化显示:
3、功能2(买房)
对于功能2,当点击主功能界面上的“买房”功能按钮,就会弹出如下图所示的功能界面,接下来输入相应的参数,点击查询即可。
下图即为功能2查询结果的地图可视化显示:
4、功能3(修路)
对于功能3,当点击主功能界面上的“修路”功能按钮,就会弹出如下图所示的功能界面,接下来输入相应的参数,点击查询即可。
下图即为功能3查询结果的地图可视化显示:
5、功能4(最近医院)
对于功能4,当点击主功能界面上的“最近医院”功能按钮,就会弹出如下图所示的功能界面,接下来输入相应的参数,点击查询即可。
下图即为功能4查询结果的地图可视化显示:
6、功能5(出租车)
对于功能5,当点击主功能界面上的“出租车”功能按钮,就会弹出如下图所示的功能界面,接下来输入相应的参数,点击查询即可。
下图即为功能5查询结果的地图可视化显示:
以上功能实现的主要思想是使用Java的Swing可视化工具,调用Oracle数据库中编写的存储过程,实现可以与用户交互输入、输出的空间数据库管理系统。并且将最终的查询结果以及涉及到的空间地点信息在地图上显示出来,使查询结果更加直观!
二、代码实现部分
接下来是代码实现部分,包括Java代码和修改后的PL/SQL代码。
1、Java代码
总共包括8个java文件,分别负责8个页面,1个登录页面,1个主功能页面,5个子功能页面和1个输出页面。
其中前7个界面是直接用代码写的布局,参考的就是我原来写的一个学生管理系统,最后一个输出界面我是用控件拖拽的,这个相对来说比较容易,而且比较美观,具体怎么使用可以百度。
(1)登录界面(Login.java)
package suzhou;
import javax.swing.*; // 引入swing工具包进行GUI的设计
import java.awt.*; // 引入awt工具包
//import java.awt.event.ActionEvent; // 动作事件
//import java.awt.event.ActionListener; // 动作监听器
import java.awt.event.*;
import java.sql.*;
public class Login extends JFrame implements ActionListener{
// 定义组件
JPanel jp_1, jp_2, jp_3, jp_4 = null; // 设置4个面板
JLabel jlb_1, jlb_2, jlb_3 = null; // 设置3个标签(标题、用户、密码)
JTextField jtf = null; // 设置1个普通文本框,用来输入用户名
JPasswordField jpf = null; // 设置一个密码文本框,用来输入密码
JButton jb_1, jb_2, jb_3 = null; // 设置三个单击按钮(登录、重置、退出)
// 存储数据库的用户名和密码
static String user_name;
static String password;
static Connection connection;
// 构造函数
public Login(){
// 创建组件
// 面板
jp_1 = new JPanel(); jp_2 = new JPanel();
jp_3 = new JPanel(); jp_4 = new JPanel();
// 标签(JLabel)
jlb_1 = new JLabel("安徽省宿州市空间数据库管理系统");
jlb_2 = new JLabel("用户名:");
jlb_3 = new JLabel("密 码:");
// 设置字体
jlb_1.setFont(new java.awt.Font("Dialog", 1, 25));
jlb_2.setFont(new java.awt.Font("Dialog", 1, 15));
jlb_3.setFont(new java.awt.Font("Dialog", 1, 15));
// 普通文本框,输入用户名
jtf = new JTextField(10);
// 密码文本框,输入密码
jpf = new JPasswordField(10);
//单击按钮(JButton)
jb_1 = new JButton("登录");
jb_2 = new JButton("重置");
jb_3 = new JButton("退出");
// 设置监听
jb_1.addActionListener(this);
jb_2.addActionListener(this);
jb_3.addActionListener(this);
// 将组件添加到面板
// “安徽省宿州市空间数据库系统”标题面板
jp_1.add(jlb_1);
// 用户名面板
jp_2.add(jlb_2);
jp_2.add(jtf);
// 密码面板
jp_3.add(jlb_3);
jp_3.add(jpf);
// 按钮面板
jp_4.add(jb_1);
jp_4.add(jb_2);
jp_4.add(jb_3);
// 将面板添加到框架
this.add(jp_1);
this.add(jp_2);
this.add(jp_3);
this.add(jp_4);
// 设置布局管理器(格网布局)
this.setLayout(new GridLayout(4,1));
// 给窗口添加标题
this.setTitle("空间数据库管理系统");
// 设置窗口大小
this.setSize(500, 300);
// 设置窗口的起始位置
this.setLocationRelativeTo(null); //在屏幕中间显示(居中显示)
// 设置当关闭窗口时,程序也结束
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// 显示窗口
this.setVisible(true);
this.setResizable(true);
}
static String url = "jdbc:oracle:thin:@localhost:1521:orcl";
// 将两个文本框的内容清空,点击重置按钮时调用
public void clear(){
jtf.setText("");
jpf.setText("");
}
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
if(e.getActionCommand() == "登录"){
//1.加载驱动
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
} catch (ClassNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
//2.获取连接对象
try {
user_name = jtf.getText();
password = String.valueOf(jpf.getPassword());
connection = DriverManager.getConnection(url,user_name,password);
if(connection==null) {
JOptionPane.showMessageDialog(null, "用户名或者密码错误!\n请重新输入", "提示信息", JOptionPane.ERROR_MESSAGE);
System.out.println("oracle连接失败");
}else {
JOptionPane.showMessageDialog(null, "登陆成功!", "提示消息", JOptionPane.WARNING_MESSAGE);
System.out.println("oracle连接成功");
dispose(); // 退出当前界面
oracle o1 = new oracle(connection); // 创建主功能界面,跳转
}
} catch (SQLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
} else if(e.getActionCommand() == "重置"){
clear();
} else if(e.getActionCommand() == "退出"){
System.exit(0); // 退出当前程序,关闭所有窗口
}
}
// 主函数
public static void main(String[] args) throws ClassNotFoundException, SQLException{
Login login = new Login();
}
}
(2)主功能界面(oracle.java)
package suzhou;
/*
* 主功能界面
*
* 功能:建立与每个子界面的连接
*
* 作者:小木同学
*/
import javax.swing.*; // 引入swing工具包进行GUI的设计
import java.awt.*; // 引入awt工具包
import java.awt.event.*;
import java.sql.*;
public class oracle extends JFrame implements ActionListener{
static Connection connection;
JPanel jp_1, jp_2, jp_3, jp_4, jp_5, jp_6, jp_7 = null; // 设置7个面板
JLabel jlb_1, jlb_2, jlb_3, jlb_4, jlb_5, jlb_6 = null; // 设置6个标签(1个标题、5个功能)
JButton jb_1, jb_2, jb_3, jb_4, jb_5, jb_6 = null; // 设置6个按钮(5个功能、1个退出)
// 构造函数
public oracle(Connection conn){
connection = conn;
jp_1 = new JPanel(); jp_2 = new JPanel(); jp_3 = new JPanel();
jp_4 = new JPanel(); jp_5 = new JPanel(); jp_6 = new JPanel();
jp_7 = new JPanel();
jlb_1 = new JLabel("安徽省宿州市空间数据库功能列表");
jlb_2 = new JLabel("功能1:");
jlb_3 = new JLabel("功能2:");
jlb_4 = new JLabel("功能3:");
jlb_5 = new JLabel("功能4:");
jlb_6 = new JLabel("功能5:");
jb_1 = new JButton("房地产");
jb_2 = new JButton("买房");
jb_3 = new JButton("修路");
jb_4 = new JButton("最近医院");
jb_5 = new JButton("出租车");
jb_6 = new JButton("退出系统");
jlb_1.setFont(new java.awt.Font("Dialog", 1, 25));
jlb_2.setFont(new java.awt.Font("Dialog", 1, 20));
jlb_3.setFont(new java.awt.Font("Dialog", 1, 20));
jlb_4.setFont(new java.awt.Font("Dialog", 1, 20));
jlb_5.setFont(new java.awt.Font("Dialog", 1, 20));
jlb_6.setFont(new java.awt.Font("Dialog", 1, 20));
jb_1.addActionListener(this);
jb_2.addActionListener(this);
jb_3.addActionListener(this);
jb_4.addActionListener(this);
jb_5.addActionListener(this);
jb_6.addActionListener(this);
jp_1.add(jlb_1);
jp_2.add(jlb_2);
jp_2.add(jb_1);
jp_3.add(jlb_3);
jp_3.add(jb_2);
jp_4.add(jlb_4);
jp_4.add(jb_3);
jp_5.add(jlb_5);
jp_5.add(jb_4);
jp_6.add(jlb_6);
jp_6.add(jb_5);
jp_7.add(jb_6);
this.add(jp_1);
this.add(jp_2);
this.add(jp_3);
this.add(jp_4);
this.add(jp_5);
this.add(jp_6);
this.add(jp_7);
// 设置布局管理器(格网布局)
this.setLayout(new GridLayout(7,1));
// 给窗口添加标题
this.setTitle("空间数据库管理系统功能界面");
// 设置窗口大小
this.setSize(500, 600);
// 设置窗口的起始位置
this.setLocationRelativeTo(null); //在屏幕中间显示(居中显示)
// 设置当关闭窗口时,程序也结束
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// 显示窗口
this.setVisible(true);
this.setResizable(true);
}
// 响应函数
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
if(e.getActionCommand() == "房地产"){
real_estate real_estate_1 = new real_estate(connection);
} else if(e.getActionCommand() == "买房"){
maifang maifang_1 = new maifang(connection);
} else if(e.getActionCommand() == "修路"){
xiulu xiulu_1 = new xiulu(connection);
} else if(e.getActionCommand() == "最近医院"){
recent_hospital recent_hospital_1 = new recent_hospital(connection);
} else if(e.getActionCommand() == "出租车"){
taxi_pro taxi_pro_1 = new taxi_pro(connection);
}
else if(e.getActionCommand() == "退出系统"){
System.exit(0);
}
}
}
(3)功能1界面(real_estate.java)
package suzhou;
/*
* 功能1:“房地产”功能
*
* 功能:输入小区名称,每平米利润和楼层数,预估总收益
*
* 作者:小木同学
*/
import javax.swing.*; // 引入swing工具包进行GUI的设计
import oracle.jdbc.OracleTypes;
import java.awt.*; // 引入awt工具包
import java.awt.event.*;
import java.sql.*;
public class real_estate extends JFrame implements ActionListener{
static Connection connection;
String xiaoqu_name;
String price;
String storey;
// 定义组件
JPanel jp_1, jp_2, jp_3, jp_4, jp_5 = null; // 设置5个面板
JLabel jlb_1, jlb_2, jlb_3, jlb_4 = null; // 设置标签
JTextField jtf_1 = null; // 用来输入小区名称
JTextField jtf_2 = null; // 用来输入距学校距离
JTextField jtf_3 = null; // 用来输入距医院距离
JButton jb_1, jb_2= null; // 单击按钮(查询、退出)
// 构造函数
public real_estate(Connection conn){
connection = conn;
jp_1 = new JPanel();
jp_2 = new JPanel();
jp_3 = new JPanel();
jp_4 = new JPanel();
jp_5 = new JPanel();
jlb_1 = new JLabel("“房地产” 功能");
jlb_2 = new JLabel("输入小区名称:");
jlb_3 = new JLabel("利润(平方米/元):");
jlb_4 = new JLabel("楼层数 :");
jlb_1.setFont(new java.awt.Font("Dialog", 1, 25));
jlb_2.setFont(new java.awt.Font("Dialog", 1, 15));
jlb_3.setFont(new java.awt.Font("Dialog", 1, 15));
jlb_4.setFont(new java.awt.Font("Dialog", 1, 15));
jtf_1 = new JTextField(10);
jtf_2 = new JTextField(10);
jtf_3 = new JTextField(10);
jb_1 = new JButton("查询");
jb_2 = new JButton("退出");
jb_1.addActionListener(this);
jb_2.addActionListener(this);
jp_1.add(jlb_1);
jp_2.add(jlb_2);
jp_2.add(jtf_1);
jp_3.add(jlb_3);
jp_3.add(jtf_2);
jp_4.add(jlb_4);
jp_4.add(jtf_3);
jp_5.add(jb_1);
jp_5.add(jb_2);
this.add(jp_1);
this.add(jp_2);
this.add(jp_3);
this.add(jp_4);
this.add(jp_5);
// 设置布局管理器(格网布局)
this.setLayout(new GridLayout(5,1));
// 给窗口添加标题
this.setTitle("房地产功能界面");
// 设置窗口大小
this.setSize(400, 500);
// 设置窗口的起始位置
this.setLocationRelativeTo(null); //在屏幕中间显示(居中显示)
// 设置当关闭窗口时,程序也结束
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// 显示窗口
this.setVisible(true);
this.setResizable(true);
}
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
if(e.getActionCommand() == "查询"){
xiaoqu_name = jtf_1.getText();
price = jtf_2.getText();
storey = jtf_3.getText();
try{
// 调用存储过程
CallableStatement cs = connection.prepareCall("call java_real_estate(?, ?, ?, ?, ?)");
// 给存储过程的参数赋值
cs.setString(1, xiaoqu_name);
cs.setDouble(2, Double.parseDouble(price));
cs.setInt(3, Integer.parseInt(storey));
cs.registerOutParameter(4, OracleTypes.VARCHAR);
cs.registerOutParameter(5, OracleTypes.VARCHAR);
// 执行语句
cs.execute();
String str1 = cs.getString(4);
String str2 = cs.getString(5);
String str = str1+str2;
shuchu frame = new shuchu(str);
frame.setVisible(true);
// 关闭
cs.close();
}
catch(SQLException e1){
e1.printStackTrace();
}
} else if(e.getActionCommand() == "退出"){
dispose();
}
}
}
(4)功能2界面(maifang.java)
package suzhou;
/*
* 功能2:“买房”功能
*
* 功能:输入小区名称,3个限定距离,查询小区周边环境,是否适合买房?
*
* 作者:小木同学
*/
import javax.swing.*; // 引入swing工具包进行GUI的设计
import oracle.jdbc.OracleTypes;
import java.awt.*; // 引入awt工具包
import java.awt.event.*;
import java.sql.*;
public class maifang extends JFrame implements ActionListener{
static Connection connection;
String xiaoqu_name;
String school_distance;
String hospital_distance;
String park_distance;
// 定义组件
JPanel jp_1, jp_2, jp_3, jp_4, jp_5, jp_6 = null; // 设置6个面板
JLabel jlb_1, jlb_2, jlb_3, jlb_4, jlb_5 = null; // 设置标签
JTextField jtf_1 = null; // 用来输入小区名称
JTextField jtf_2 = null; // 用来输入距学校距离
JTextField jtf_3 = null; // 用来输入距医院距离
JTextField jtf_4 = null; // 用来输入距公园距离
JButton jb_1, jb_2= null; // 单击按钮(查询、退出)
public maifang(Connection conn){
connection = conn;
jp_1 = new JPanel();
jp_2 = new JPanel();
jp_3 = new JPanel();
jp_4 = new JPanel();
jp_5 = new JPanel();
jp_6 = new JPanel();
jlb_1 = new JLabel("“买房” 功能");
jlb_2 = new JLabel("输入小区名称:");
jlb_3 = new JLabel("学校距离(英里):");
jlb_4 = new JLabel("医院距离(英里):");
jlb_5 = new JLabel("公园距离(英里):");
jlb_1.setFont(new java.awt.Font("Dialog", 1, 25));
jlb_2.setFont(new java.awt.Font("Dialog", 1, 15));
jlb_3.setFont(new java.awt.Font("Dialog", 1, 15));
jlb_4.setFont(new java.awt.Font("Dialog", 1, 15));
jlb_5.setFont(new java.awt.Font("Dialog", 1, 15));
jtf_1 = new JTextField(10);
jtf_2 = new JTextField(10);
jtf_3 = new JTextField(10);
jtf_4 = new JTextField(10);
jb_1 = new JButton("查询");
jb_2 = new JButton("退出");
jb_1.addActionListener(this);
jb_2.addActionListener(this);
jp_1.add(jlb_1);
jp_2.add(jlb_2);
jp_2.add(jtf_1);
jp_3.add(jlb_3);
jp_3.add(jtf_2);
jp_4.add(jlb_4);
jp_4.add(jtf_3);
jp_5.add(jlb_5);
jp_5.add(jtf_4);
jp_6.add(jb_1);
jp_6.add(jb_2);
this.add(jp_1);
this.add(jp_2);
this.add(jp_3);
this.add(jp_4);
this.add(jp_5);
this.add(jp_6);
// 设置布局管理器(格网布局)
this.setLayout(new GridLayout(6,1));
// 给窗口添加标题
this.setTitle("买房功能界面");
// 设置窗口大小
this.setSize(400, 500);
// 设置窗口的起始位置
this.setLocationRelativeTo(null); //在屏幕中间显示(居中显示)
// 设置当关闭窗口时,程序也结束
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// 显示窗口
this.setVisible(true);
this.setResizable(true);
}
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
if(e.getActionCommand() == "查询"){
xiaoqu_name = jtf_1.getText();
school_distance = jtf_2.getText();
hospital_distance = jtf_3.getText();
park_distance = jtf_4.getText();
try{
// 调用存储过程
CallableStatement cs = connection.prepareCall("call java_maifang(?, ?, ?, ?, ?)");
// 给存储过程的参数赋值
cs.setString(1, xiaoqu_name);
cs.setInt(2, Integer.parseInt(school_distance));
cs.setInt(3, Integer.parseInt(hospital_distance));
cs.setInt(4, Integer.parseInt(park_distance));
cs.registerOutParameter(5, OracleTypes.VARCHAR);
// 执行语句
cs.execute();
String str1 = cs.getString(5);
shuchu frame = new shuchu(str1);
frame.setVisible(true);
//System.out.println(str1);
// 关闭
cs.close();
//connection.close();
}
catch(SQLException e1){
e1.printStackTrace();
}
} else if(e.getActionCommand() == "退出"){
dispose();
}
}
}
(5)功能3界面(xiulu.java)
package suzhou;
/*
* 功能3:“修路”功能
*
* 功能:输入所要维修道路名称和原料钱,输出修路情况和总原料钱
*
* 作者:小木同学
*/
import javax.swing.*; // 引入swing工具包进行GUI的设计
import oracle.jdbc.OracleTypes;
import java.awt.*; // 引入awt工具包
import java.awt.event.*;
import java.sql.*;
public class xiulu extends JFrame implements ActionListener{
static Connection connection;
String road_name;
String price;
// 定义组件
JPanel jp_1, jp_2, jp_3, jp_4 = null; // 设置4个面板
JLabel jlb_1, jlb_2, jlb_3 = null; // 设置标签
JTextField jtf_1 = null; // 用来输入道路名称
JTextField jtf_2 = null; // 用来输入修路原料价钱
JButton jb_1, jb_2= null; // 单击按钮(查询、退出)
// 构造函数
public xiulu(Connection conn){
connection = conn;
jp_1 = new JPanel();
jp_2 = new JPanel();
jp_3 = new JPanel();
jp_4 = new JPanel();
jlb_1 = new JLabel("“修路” 功能");
jlb_2 = new JLabel("输入道路名称:");
jlb_3 = new JLabel("原料钱(万元):");
jlb_1.setFont(new java.awt.Font("Dialog", 1, 25));
jlb_2.setFont(new java.awt.Font("Dialog", 1, 15));
jlb_3.setFont(new java.awt.Font("Dialog", 1, 15));
jtf_1 = new JTextField(10);
jtf_2 = new JTextField(10);
jb_1 = new JButton("查询");
jb_2 = new JButton("退出");
jb_1.addActionListener(this);
jb_2.addActionListener(this);
jp_1.add(jlb_1);
jp_2.add(jlb_2);
jp_2.add(jtf_1);
jp_3.add(jlb_3);
jp_3.add(jtf_2);
jp_4.add(jb_1);
jp_4.add(jb_2);
this.add(jp_1);
this.add(jp_2);
this.add(jp_3);
this.add(jp_4);
// 设置布局管理器(格网布局)
this.setLayout(new GridLayout(4,1));
// 给窗口添加标题
this.setTitle("修路功能界面");
// 设置窗口大小
this.setSize(400, 500);
// 设置窗口的起始位置
this.setLocationRelativeTo(null); //在屏幕中间显示(居中显示)
// 设置当关闭窗口时,程序也结束
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// 显示窗口
this.setVisible(true);
this.setResizable(true);
}
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
if(e.getActionCommand() == "查询"){
road_name = jtf_1.getText();
price = jtf_2.getText();
try{
CallableStatement cs = connection.prepareCall("call java_xiulu(?, ?, ?)");
// 给存储过程的参数赋值
cs.setString(1, road_name);
cs.setDouble(2, Double.parseDouble(price));
cs.registerOutParameter(3, OracleTypes.VARCHAR);
// 执行语句
cs.execute();
String str = cs.getString(3);
shuchu frame = new shuchu(str);
frame.setVisible(true);
//System.out.println(str);
// 关闭
cs.close();
}
catch(SQLException e1){
e1.printStackTrace();
}
} else if(e.getActionCommand() == "退出"){
dispose();
}
}
}
(6)功能4界面(recent_hospital.java)
package suzhou;
/*
* 功能4:“最近医院”功能
*
* 功能:输入当前所在地点,以及想要找的医院数量,输出医院信息
*
* 作者:小木同学
*/
import javax.swing.*; // 引入swing工具包进行GUI的设计
import oracle.jdbc.OracleTypes;
import java.awt.*; // 引入awt工具包
import java.awt.event.*;
import java.sql.*;
public class recent_hospital extends JFrame implements ActionListener{
static Connection connection;
String place_name;
String hospital_num;
// 定义组件
JPanel jp_1, jp_2, jp_3, jp_4 = null; // 设置4个面板
JLabel jlb_1, jlb_2, jlb_3 = null; // 设置标签
JTextField jtf_1 = null; // 用来输入地点名称
JTextField jtf_2 = null; // 用来输入医院数量
JButton jb_1, jb_2= null; // 单击按钮(查询、退出)
// 构造函数
public recent_hospital(Connection conn){
connection = conn;
jp_1 = new JPanel();
jp_2 = new JPanel();
jp_3 = new JPanel();
jp_4 = new JPanel();
jlb_1 = new JLabel("“最近医院” 功能");
jlb_2 = new JLabel("输入地点名称:");
jlb_3 = new JLabel("医院数量:");
jlb_1.setFont(new java.awt.Font("Dialog", 1, 25));
jlb_2.setFont(new java.awt.Font("Dialog", 1, 15));
jlb_3.setFont(new java.awt.Font("Dialog", 1, 15));
jtf_1 = new JTextField(10);
jtf_2 = new JTextField(10);
jb_1 = new JButton("查询");
jb_2 = new JButton("退出");
jb_1.addActionListener(this);
jb_2.addActionListener(this);
jp_1.add(jlb_1);
jp_2.add(jlb_2);
jp_2.add(jtf_1);
jp_3.add(jlb_3);
jp_3.add(jtf_2);
jp_4.add(jb_1);
jp_4.add(jb_2);
this.add(jp_1);
this.add(jp_2);
this.add(jp_3);
this.add(jp_4);
// 设置布局管理器(格网布局)
this.setLayout(new GridLayout(4,1));
// 给窗口添加标题
this.setTitle("修路功能界面");
// 设置窗口大小
this.setSize(400, 500);
// 设置窗口的起始位置
this.setLocationRelativeTo(null); //在屏幕中间显示(居中显示)
// 设置当关闭窗口时,程序也结束
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// 显示窗口
this.setVisible(true);
this.setResizable(true);
}
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
if(e.getActionCommand() == "查询"){
place_name = jtf_1.getText();
hospital_num = jtf_2.getText();
try{
CallableStatement cs = connection.prepareCall("call java_recent_hospital(?, ?, ?)");
// 给存储过程的参数赋值
cs.setString(1, place_name);
cs.setDouble(2, Double.parseDouble(hospital_num));
cs.registerOutParameter(3, OracleTypes.VARCHAR);
// 执行语句
cs.execute();
String str = cs.getString(3);
shuchu frame = new shuchu(str);
frame.setVisible(true);
//System.out.println(str);
// 关闭
cs.close();
}
catch(SQLException e1){
e1.printStackTrace();
}
} else if(e.getActionCommand() == "退出"){
dispose();
}
}
}
(7)功能5界面(taxi_pro.java)
package suzhou;
/*
* 功能5:“出租车”功能
*
* 功能:输入当前所在建筑物名称和目标建筑物名称,规划最近上车地点和下车地 点以及需要步行的信息
*
* 作者:小木同学
*/
import javax.swing.*; // 引入swing工具包进行GUI的设计
import oracle.jdbc.OracleTypes;
import java.awt.*; // 引入awt工具包
import java.awt.event.*;
import java.sql.*;
public class taxi_pro extends JFrame implements ActionListener{
static Connection connection;
String in_building_name;
String out_building_name;
// 定义组件
JPanel jp_1, jp_2, jp_3, jp_4 = null; // 设置4个面板
JLabel jlb_1, jlb_2, jlb_3 = null; // 设置标签
JTextField jtf_1 = null; // 用来输入出发建筑物名称
JTextField jtf_2 = null; // 用来输入目标建筑物名称
JButton jb_1, jb_2= null; // 单击按钮(查询、退出)
// 构造函数
public taxi_pro(Connection conn){
connection = conn;
jp_1 = new JPanel();
jp_2 = new JPanel();
jp_3 = new JPanel();
jp_4 = new JPanel();
jlb_1 = new JLabel("“出租车” 功能");
jlb_2 = new JLabel("上车地点名称:");
jlb_3 = new JLabel("下车地点名称:");
jlb_1.setFont(new java.awt.Font("Dialog", 1, 25));
jlb_2.setFont(new java.awt.Font("Dialog", 1, 15));
jlb_3.setFont(new java.awt.Font("Dialog", 1, 15));
jtf_1 = new JTextField(10);
jtf_2 = new JTextField(10);
jb_1 = new JButton("查询");
jb_2 = new JButton("退出");
jb_1.addActionListener(this);
jb_2.addActionListener(this);
jp_1.add(jlb_1);
jp_2.add(jlb_2);
jp_2.add(jtf_1);
jp_3.add(jlb_3);
jp_3.add(jtf_2);
jp_4.add(jb_1);
jp_4.add(jb_2);
this.add(jp_1);
this.add(jp_2);
this.add(jp_3);
this.add(jp_4);
// 设置布局管理器(格网布局)
this.setLayout(new GridLayout(4,1));
// 给窗口添加标题
this.setTitle("出租车功能界面");
// 设置窗口大小
this.setSize(400, 500);
// 设置窗口的起始位置
this.setLocationRelativeTo(null); //在屏幕中间显示(居中显示)
// 设置当关闭窗口时,程序也结束
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// 显示窗口
this.setVisible(true);
this.setResizable(true);
}
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
if(e.getActionCommand() == "查询"){
in_building_name = jtf_1.getText();
out_building_name = jtf_2.getText();
try{
CallableStatement cs = connection.prepareCall("call java_taxi_pro(?, ?, ?)");
// 给存储过程的参数赋值
cs.setString(1, in_building_name);
cs.setString(2, out_building_name);
cs.registerOutParameter(3, OracleTypes.VARCHAR);
// 执行语句
cs.execute();
String str = cs.getString(3);
shuchu frame = new shuchu(str);
frame.setVisible(true);
//System.out.println(str);
// 关闭
cs.close();
}
catch(SQLException e1){
e1.printStackTrace();
}
} else if(e.getActionCommand() == "退出"){
dispose();
}
}
}
(8)输出界面(shuchu.java)
package suzhou;
import java.awt.BorderLayout;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.border.EmptyBorder;
import javax.swing.JTextArea;
import javax.swing.JLabel;
import java.awt.Color;
import java.awt.Font;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
public class shuchu extends JFrame {
private JPanel contentPane;
/**
* Create the frame.
*/
public shuchu(String str) {
setTitle("查询结果窗口");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// setBounds(100, 100, 600, 434); 可以同时设置位置和大小
setSize(600, 434);
setLocationRelativeTo(null);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(null);
// 多行文本输入框
JTextArea textArea = new JTextArea(str);
textArea.setEditable(false); // 设置为不可编辑
textArea.setBounds(60, 53, 460, 275);
JScrollPane js=new JScrollPane(textArea); // 添加滚动条
js.setBounds(60, 53, 460, 275);
contentPane.add(js);
// 普通文本
JLabel label = new JLabel("查询结果");
label.setFont(new Font("宋体", Font.PLAIN, 22));
label.setBackground(new Color(240, 240, 240));
label.setBounds(60, 13, 129, 32);
contentPane.add(label);
// 单击按钮(退出当前界面)
JButton button = new JButton("退出");
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
dispose();
}
});
button.setFont(new Font("宋体", Font.PLAIN, 22));
button.setBackground(Color.WHITE);
button.setBounds(243, 341, 113, 27);
contentPane.add(button);
}
}
2、PL/SQL代码
由于我们想要将存储过程在Oracle里面输出的东西在Java里面输出,所以我想了一个办法,就是将每一个存储过程都做一个简单的修改,就是添加一个输出参数out,将想要输出的东西全部添加到这个字符串里面来,然后将这个字符串传给Java中的参数,最终输出出来。
(1)房地产功能
-------------------------------------------------- java_real_estate(功能1:房地产) ------------------------------------------------------------
create or replace procedure java_real_estate(estate_name in varchar2, price in number, storey in number, str1 out varchar2, str2 out varchar2)
is
square_mile constant number := 2589988.11034; -- 常量:1平方英里等于2589988.11034平方米
-- 存储小区的信息变量
estate_ID number;
estate_Type varchar2(100);
estate_geom sdo_geometry;
-- 存储小区面积和收益
estate_area number;
estate_price number;
-- 利用游标获取小区信息
cursor c1 is
select la.osm_id, la.type, la.geometry
from landuse la
where la.name=estate_name;
begin
str1 := chr(10);
open c1;
loop
fetch c1 into estate_ID, estate_Type, estate_geom;
exit when c1%notfound;
-- 调用函数calculate_area计算小区面积
estate_area := calculate_area(estate_geom);
-- 计算小区总共收益(万元为单位)
estate_price := estate_area * square_mile * price * storey/10000;
str1 := str1 || '小区ID:'|| estate_ID||chr(10)||'小区名称:'||estate_name||chr(10)||'小区类型:'||estate_Type ;
str2 := '小区占地面积:'||estate_area||'平方英里'||chr(10)||'小区每平方米收益:'||price||'元'||chr(10)||'预估收益:'||estate_price || '万元';
end loop;
close c1;
end;
/
declare
str1 varchar2(500);
str2 varchar2(500);
begin
java_real_estate('中通名仕家园小区', 8000, 20, str1, str2);
dbms_output.put_line(str1);
dbms_output.put_line(str2);
end;
(2)买房功能
----------------------------------------------------------- java_maifang(功能2:买房)----------------------------------------------------------------------------------
create or replace procedure java_maifang(xiaoqu_name in varchar2, school_distance in number, hospital_distance in number, park_distance in number, out_str out clob)
-- 声明区
is
str clob;
-- 声明变量用来存储学校、医院、公园的ID号和名称
school_ID number;
hospital_ID number;
park_ID number;
school_Name varchar2(100);
hospital_Name varchar2(100);
park_Name varchar2(100);
-- 声明游标,分别保存学校、医院、公园的查询记录
cursor c1 is
select po.osm_id, po.name
from points po, landuse la
where la.name=xiaoqu_name and sdo_geom.sdo_distance(po.geometry, la.geometry, 0.5, 'unit=mile')<school_distance and po.type='school' and po.name is not null;
cursor c2 is
select po.osm_id, po.name
from points po, landuse la
where la.name=xiaoqu_name and sdo_geom.sdo_distance(po.geometry, la.geometry, 0.5, 'unit=mile')<hospital_distance and po.type='hospital' and po.name is not null;
cursor c3 is
select na.osm_id, na.name
from natural na, landuse la
where la.name=xiaoqu_name and sdo_geom.sdo_distance(na.geometry, la.geometry, 0.5, 'unit=mile')<park_distance and na.type='park' and na.name is not null;
-- 子程序区
-- 取游标中的数据并输出查询到的学校、医院、公园的信息
begin
str := chr(10);
str := str || '------' || xiaoqu_name || '------' ||'欢迎您!' || chr(10);
-- 输出学校信息
str := str || xiaoqu_name || ' 附近 ' || school_distance || '英里 范围内的学校有如下几所:' || chr(10);
open c1;
loop
fetch c1 into school_ID, school_Name;
exit when c1%notfound;
str := str || '学校id:' || school_ID ||' ' || '学校名称:' || school_Name || chr(10);
end loop;
close c1;
-- 输出医院信息
str := str ||chr(10)|| xiaoqu_name || ' 附近 ' || hospital_distance || '英里 范围内的医院有如下几所:' || chr(10);
open c2;
loop
fetch c2 into hospital_ID, hospital_Name;
exit when c2%notfound;
str := str || '医院id:' || hospital_ID || ' ' || '医院名称:' || hospital_Name || chr(10);
end loop;
close c2;
-- 输出公园信息
str := str || chr(10) || xiaoqu_name || ' 附近 ' || park_distance || '英里 范围内的公园有如下几个:'||chr(10);
open c3;
loop
fetch c3 into park_ID, park_Name;
exit when c3%notfound;
str := str || '公园id:' || park_ID || ' ' || '公园名称:' || park_Name || chr(10);
end loop;
close c3;
str := str || chr(10) || '以上就是本小区附近的环境信息,请根据您的需求进行选购!';
out_str := str;
end;
/
declare
str clob;
begin
java_maifang('中通名仕家园小区', 1, 4, 3, str);
dbms_output.put_line(str);
end;
(3)修路功能
----------------------------------------------------------- java_xiulu(功能3:修路)---------------------------------------------------------------------------------
create or replace procedure java_xiulu(xiu_name in varchar2, material_money in number, out_str out clob)
is
str clob;
road_ID number; -- 公路编号
road_Ref varchar2(100); -- 公路编号
road_Type varchar2(100); -- 公路类型
road_geom sdo_geometry; -- 公路sdo_geometry
-- 计算得到的值存放的变量如下:
road_buffer_geom sdo_geometry; -- 该路段缓冲区sdo_geometry
road_length number; -- 该路段长度
road_buffer_area number; -- 该路段缓冲区面积
road_material_money number; -- 该路段需要原料钱
-- 将所有路段进行汇总的值存放在如下变量:
all_road_length number; -- 总的路段长度
all_buffer_area number; -- 总的缓冲区面积
all_material_money number; -- 总的原料钱
count_road number; -- 统计名为xiu_name的路一共有几段
-- 定义游标并调用sdo_buffer函数
cursor c1 is
select ro.osm_id, ro.ref, ro.type, ro.geometry, sdo_geom.sdo_buffer(ro.geometry, 0.25, 0.5, 'arc_tolerance=0.005 unit=mile') buffer_geom
from roads ro
where ro.name=xiu_name and ro.ref is not null;
begin
str := chr(10);
count_road := 0;
all_material_money := 0;
all_road_length := 0;
all_buffer_area := 0;
str := str || '所要修的路的名称为:' || xiu_name || '! 具体路段信息以及修路信息如下所示:' || chr(10);
str := str || chr(10) ||'路段序号 ' || 'ID ' || '路段长度(英里) ' || '拓宽面积(平方英里) ' || '该路段原料钱(万元)'||chr(10);
open c1;
loop
fetch c1 into road_ID, road_Ref, road_Type, road_geom, road_buffer_geom;
exit when c1%notfound;
count_road := count_road + 1; -- 统计路段号
road_length := sdo_geom.sdo_length(road_geom, 0.05, 'unit=mile'); -- 计算路段长度函数sdo_geom.sdo_length
all_road_length := all_road_length + road_length; -- 计算总长度
road_buffer_area := calculate_area(road_buffer_geom); -- 计算需要拓宽的路段的面积
all_buffer_area := all_buffer_area + road_buffer_area; -- 计算总面积
road_material_money := road_buffer_area*material_money; -- 计算该路段修路原料钱
all_material_money := all_material_money + road_material_money; -- 计算总的原料钱
str := str || ' ' || count_road || ' ' || road_ID || ' ' || road_length || ' ' || road_buffer_area || ' ' || road_material_money ||chr(10);
end loop;
close c1;
str := str || chr(10) || xiu_name || ' 共有 ' || count_road || ' 段' ||chr(10);
str := str || xiu_name || ' 总长度为: ' || all_road_length || '英里' ||chr(10);
str := str || xiu_name || ' 总拓宽面积为: ' || all_buffer_area || '平方英里' ||chr(10);
str := str || xiu_name || ' 修路用的总原料钱为: ' || all_material_money || '万元';
out_str := str;
end;
/
-- 调用存储过程,对“坝子街”进行拓宽修路,输出相应的信息
declare
str clob;
begin
java_xiulu('坝子街', 100, str);
dbms_output.put_line(str);
end;
(4)最近医院功能
----------------------------------------------------------- java_recent_hospital(功能4:最近医院)---------------------------------------------------------------------------------
-- 定义存储过程recent_hospital
-- 其功能为:输入你当前所在地点(places)的名称以及想要查询医院的数量,来查询医院信息并按照距离排序
create or replace procedure java_recent_hospital(place_name in varchar2, hospital_num in number, out_str out clob)
is
str clob;
-- 存储输入地点的行信息
row_places places %ROWTYPE;
-- 存储医院(points里的数据)的ID,名称和距离
hospital_ID number;
hospital_Name varchar2(100);
hospital_distance number;
-- 定义游标用来获取距离某地点最近的几家医院信息
cursor c1 is
select po.osm_id, po.name, sdo_geom.sdo_distance(po.geometry, pl.geometry, 0.5, 'unit=mile') distance
from points po, places pl
where pl.name=place_name and sdo_nn(po.geometry, pl.geometry)='TRUE' and po.type='hospital' and rownum <= hospital_num;
begin
str := chr(10);
-- 获取当前所在地点信息
select * into row_places from places where name=place_name;
-- 输出当前地点的信息
str := str || '您当前所在的地点信息为:'||chr(10);
str := str || '地点ID:' || row_places.osm_id || ' 地点名称:' || row_places.name || ' 地点类型:' || row_places.type ||chr(10);
-- 输出距离最近的几家医院的信息和距离
str := str ||chr(10)||'距离您最近的 ' || hospital_num || ' 家医院的信息和距离如下:'||chr(10);
str := str ||' 医院ID ' || '医院名称 ' || '距离(英里)'||chr(10);
open c1;
loop
fetch c1 into hospital_ID, hospital_Name, hospital_distance;
exit when c1%notfound;
str := str || hospital_ID || ' ' || hospital_Name || ' ' || hospital_distance|| chr(10);
end loop;
close c1;
out_str := str;
end;
/
-- 调用recent_hospital存储过程,并查询距离“赵楼”最近的5家医院信息
declare
str clob;
begin
java_recent_hospital('赵楼', 5, str);
dbms_output.put_line(str);
end;
(5)出租车功能
----------------------------------------------------------- java_taxi_pro(功能5:出租车)---------------------------------------------------------------------------------
-- 定义一个存储过程taxi_pro(规划出租车最近上车地点与下车地点)
-- 功能为:输入两个建筑物的名字,为乘客规划最佳上车地点和下车地点,并输出上车点与下车点信息以及需要步行的距离信息
create or replace procedure java_taxi_pro(in_building_name in varchar2, out_building_name in varchar2, out_str out clob)
is
str clob;
-- 存储上车和下车地点信息的行变量
in_row_buildings buildings %ROWTYPE;
out_row_buildings buildings %ROWTYPE;
-- 上车的道路
recent_in_road_Name varchar2(100); -- 距上车建筑物最近的道路名字
recent_in_road_geom sdo_geometry; -- 距上车建筑物最近的道路sdo_geometry
-- 下车的道路
recent_out_road_Name varchar2(100); -- 距下车建筑物最近的道路名字
recent_out_road_geom sdo_geometry; -- 距下车建筑物最近的道路sdo_geometry
-- 上车信息
dist_in number; -- 上车建筑物到公路的最短距离(乘客需要步行的距离)
geom1 sdo_geometry; -- 公路最近点sdo_geometry(上车)
geom2 sdo_geometry; -- 建筑物最近点sdo_geometry(上车)
-- 下车信息
dist_out number; -- 下车建筑物到公路的最短距离(乘客需要步行的距离)
geom3 sdo_geometry; -- 公路最近点sdo_geometry(下车)
geom4 sdo_geometry; -- 建筑物最近点sdo_geometry(下车)
all_dist number; -- 总共需要步行的距离
two_point_dist number; -- 两上车点之间的直线距离
begin
str := chr(10);
-- 获取上车地点的信息
select * into in_row_buildings from buildings where name=in_building_name;
-- 获取距上车地点最近的道路名字和sdo_geometry
select ro.name, ro.geometry into recent_in_road_Name, recent_in_road_geom
from buildings bu, roads ro
where bu.name=in_building_name and ro.name is not null and sdo_nn(ro.geometry, bu.geometry)='TRUE' and rownum <= 1;
-- 获取下车地点的信息
select * into out_row_buildings from buildings where name=out_building_name;
-- 获取距下车地点最近的道路的名字和sdo_geometry
select ro.name, ro.geometry into recent_out_road_Name, recent_out_road_geom
from buildings bu, roads ro
where bu.name=out_building_name and ro.name is not null and sdo_nn(ro.geometry, bu.geometry)='TRUE' and rownum <= 1;
-- 调用sdo_geom.sdo_closest_points函数计算 上车建筑物(面) 到 上车道路(线) 最短距离并返回最近两点的信息
sdo_geom.sdo_closest_points(recent_in_road_geom, in_row_buildings.geometry, 0.05, 'unit=foot', dist_in, geom1, geom2);
-- 调用sdo_geom.sdo_closest_points函数计算 下车建筑物(面) 到 下车道路(线) 最短距离并返回最近两点的信息
sdo_geom.sdo_closest_points(recent_out_road_geom, out_row_buildings.geometry, 0.05, 'unit=foot', dist_out, geom3, geom4);
-- 计算步行总路程
all_dist := dist_in + dist_out;
-- 计算上车和下车点之间的直线距离
two_point_dist := sdo_geom.sdo_distance(geom1, geom3, 0.5, 'unit=foot');
-- 输出上车和下车的主要信息
str := str || '*********************************************************************' || chr(10);
str := str || '**********************安徽省 宿州市 出租车欢迎您!**********************'|| chr(10);
str := str || '*********************************************************************'|| chr(10);
str := str || chr(10) ||'您出发建筑物名称为:' || in_building_name || '! 想要到达的目标建筑物名称为:' || out_building_name || '!'||chr(10);
str := str || '上车点与下车点之间的直线距离为:' || two_point_dist || '英尺!'|| chr(10);
str := str || chr(10)||'以下为您的上车与下车地点信息以及步行信息:'||chr(10);
str := str || '------------上车地点-------------'||chr(10);
str := str || '上车建筑物最近点坐标:' || to_char(geom2.sdo_point.x) || ', ' || to_char(geom2.sdo_point.y)||chr(10);
str := str || '上车道路最近点坐标:' || to_char(geom1.sdo_point.x) || ', ' || to_char(geom1.sdo_point.y)||chr(10);
str := str || '从出发建筑物到上车地点需要步行的路程:' || dist_in || '英尺'||chr(10);
str := str || '------------下车地点-------------'||chr(10);
str := str || '下车建筑物最近点坐标:' || to_char(geom4.sdo_point.x) || ', ' || to_char(geom4.sdo_point.y)||chr(10);
str := str || '下车道路最近点坐标:' || to_char(geom3.sdo_point.x) || ', ' || to_char(geom3.sdo_point.y)||chr(10);
str := str || '从下车点到目标建筑物需要步行的路程:' || dist_out || '英尺'||chr(10);
str := str || chr(10)||'共需要步行的路程:' || all_dist || '英尺'||chr(10);
out_str := str;
end;
/
-- 假如我是一位乘客,现在想要从”广电宿舍1号楼“乘坐出租车到”淮北市体育馆“,调用taxi_pro存储过程为我规划最佳上车和下车地点
declare
str clob;
begin
java_taxi_pro('广电宿舍1号楼', '淮北市体育馆', str);
dbms_output.put_line(str);
end;
总结
主要实现了Java连接Oracle数据库,然后可视化界面,以及利用Java调用存储过程。只是将存储过程做了一下更改。