在对mySql、oracle数据库进行操作的时候,我们往往会有这样的困惑:
1、新增oracle数据时,按照mySql的写法为什么新增不了?
2、多个数据表,通过外键关联,如何通过一条sql语句把所有需要的表关联起来并且获取到我所需要的数据内容?
那么在下面,将详细讲解单表的增删改成及多表的关联查询该如何书写sql语句:
首先,我们要建立数据库的连接,在src目录下面创建一个db.properties的类,里面封装的内容为:
user=数据库用户名
password=数据库密码
url=jdbc\:oracle\:thin\数据库连接地址
driver=oracle.jdbc.driver.OracleDriver
我们接下来要创建一个JDBC工具类,用于封装连接数据库的连接:
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
public class JDBCUtils {
private static String driver;
private static String url;
private static String user;
private static String password;
static{
try {
//0读取配置文件
Properties prop = new Properties();
InputStream is = JDBCUtils.class.getResourceAsStream("/db.properties");
prop.load(is);
is.close();
driver = prop.getProperty("driver");
url = prop.getProperty("url");
user = prop.getProperty("user");
password = prop.getProperty("password");
//1 注册驱动
Class.forName(driver);
} catch (Exception e) {
e.printStackTrace();
}
}
//1 获得连接
public static Connection getConnection(){
Connection conn = null;
try {
//2 获得连接
conn = DriverManager.getConnection(url, user, password);
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("创建连接失败!");
}
return conn;
}
//2 释放资源
//1> 参数可能为空
//2> 调用close方法要抛出异常,确保即使出现异常也能继续关闭
//3>关闭顺序,需要从小到大
public static void close(Connection conn , Statement st , ResultSet rs){
try {
if(rs!=null){
rs.close();
}
} catch (SQLException e) {
e.printStackTrace();
}finally{
try {
if(st!=null){
st.close();
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
try {
if(conn!=null){
conn.close();
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
System.out.println(getConnection());
}
}
在这两步准备工具完成之后,接下来就是我们的重头戏了
一、单表的增删改查
单表的结构为:表名:tb_info 字段名:①主键:ID 自增 ②用户名:NAME ③年龄:AGE
1、新增:新增不同于mySql的新增语句,因为mySql中主键一旦设置好,那么在我们执行新增语句时,主键会自动+1,不需要我们做其他操作,如:
mySql的新增语句为:
//当调用这个方法时会会获取一个返回值,当返回值为1时,证明新增了一条数据
public int inserInto(){
//定义一个默认数值为0
int count = 0;
//1. 获得连接
Connection conn = JDBCUtils.getConnection();
String name = "老王";
String age = "18";
//2. 准备sql
String sql = " INSERT INTO tb_info (NAME,AGE) VALUES (?,?)";
//3. 获得PrepareStatement对象
PreparedStatement ps = null;
try {
ps = conn.prepareStatement(sql);
//4. 设置参数
ps.setString(1,name);
ps.setString(2,age);
//5. 执行sql
count = ps.executeUpdate();
//如果result !=1,没有获取到数据,证明保存失败
return count;
} catch (SQLException e) {
e.printStackTrace();
}finally{
//6. 关闭资源
JDBCUtils.close(conn, ps, null);
}
return count;
}
但是这条语句在oracle中就不适用了,因为mySql的主键在你新增数据时,会自动新增,但是oracle中就不会,他需要你去执行新增时,获取一下当前表中的序列号的下 一个数值,然后传入主键中,若不知道序列号是哪个,我们可以通过查询所有序列号语句来执行查询:
查询所有序列号语句:select * from user_sequences; 语句来查找所有的序列号;
如果还是不知道序列号是哪个或者不能用,我们可以新建一个序列号:
新建序列号:CREATE SEQUENCE 序列名 -----序列名
INCREMENT BY 1 -----每次加几个
START WITH 1 -----从1开始计数
NOMAXVALUE -----不设置最大值
NOCYCLE -----一直累加不循环
创建好序列号之后我们执行新增语句:
public int insert() {
//定义一个默认数值为0
int count = 0;
//1. 获得连接
Connection conn = JDBCUtils.getConnection();
//2. 准备sql语句,其中ID为主键
String sql = " INSERT INTO tb_info(ID,NAME,AGE) values(序列号.nextval,?,?)";
//3. 获得PrepareStatement对象
PreparedStatement ps = null;
try {
ps = conn.prepareStatement(sql);
//4. 设置参数
ps.setString(1, driverInfo.getDRIVER_NAME());
ps.setString(2, driverInfo.getDRIVER_ID());
//5. 执行sql
count = ps.executeUpdate();
//如果result !=1,没有获取到数据,证明保存失败
} catch (SQLException e) {
e.printStackTrace();
}finally{
//6. 关闭资源
JDBCUtils.close(conn, ps, null);
}
return count;
}
2、删除:删除中oracle和mySql语句一致:通过传入的名字条件来进行删除其所在条目的数据信息
String sql = “delete from tb_info where NAME=?”;
3、修改:
①普通的修改语句:
修改中oracle和mySql语句一致:根据所在的主键数据,来修改用户名和年龄信息,也可where后跟着其他的修改条件进行修改,update后面的每一个值都用逗号隔开
String sql = "update tb_info set NAME=?,AGE=? where ID=?";
②带日期的修改语句:
public int updateVehiSafe(VehiSafe vehiSafe) {
//定义一个默认数值为0
int count = 0;
//1.获得连接
Connection conn = JDBCUtils.getConnection();
String sql = "update tb_vehicle_extrude set VEHI_CUSTOMERS_NUM=?," +
"vehi_card_date=to_date('"+vehiSafe.getVEHI_CARD_DATE().toString()+"','yyyy-MM-dd') where vehi_no=?";
PreparedStatement ps = null;
try {
ps = conn.prepareStatement(sql);
//4. 设置参数
ps.setString(1, vehiSafe.getVEHI_CUSTOMERS_NUM());
ps.setString(2, vehiSafe.getVEHI_NO());
//5. 执行sql,修改成功返回1
count = ps.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}finally{
//6. 关闭资源
JDBCUtils.close(conn, ps, null);
}
return count;
}
4、查询:查询oracle和mySql语句一致:
①根据某个条件查询,如姓名
String sql = “select * from tb_info where NAME=?”;
②查询所有的数据:
String sql =“select * from tb_info”;
二、多表关联
1、查询:如下面有三个表
①总公司表,包含总公司的ID和总公司名称
②分公司表,包含分公司的ID、分公司的名称、总公司的ID
③部门表,包含部门ID、部门名称和分公司ID
从上面三个表中不难看出,表①和表②是通过总公司ID关联,表②和表③是通过分公司ID关联,如下图所示:
总公司表:TB_OWNER
分公司表:TB_BUSI_AREA
部门表:TB_DEPARTMENT
那么这三个表,当展示总公司名字,分公司名字和部门名字信息应该怎么做呢,只需要一条关联语句就可以了
①不带条件查询,即查询部门表中关联的分公司表和总公司表,如下:
在mySql中:
String sql =“select owner.OWNER_NAME,ba.BA_NAME,td.DEPARTMENT_NAME "+
"from tb_owner owner,tb_busi_area ba,tb_department td "+
"where owner.OWNER_ID=ba.OWNER_ID and ba.BA_ID=td.BA_ID";
语句解析:
select 后面跟着的是我们要通过这几个关联表获取的展示数据,即总公司名称、分公司名称、部门名称,用逗号隔开;
from 后面跟着的是我们要展示的数据信息来源,其中表名后面跟着的是表的缩写,可以自己定义,每个表用逗号隔开;
where 后面跟着的是关联条件,用and拼接;
注意:在每个加号的前面引号里最后一个位置都要留一个空格,不然sql会识别错误;
在此我们就已经将三张表关联起来,而且可以直接获取我们需要的数据:
定义实体类封装需要的数据信息:
public class Department {
private String OWNER_NAME;
private String BA_NAME;
private String DEPARTMENT_NAME;
public String getOWNER_NAME() {
return OWNER_NAME;
}
public void setOWNER_NAME(String oWNER_NAME) {
OWNER_NAME = oWNER_NAME;
}
public String getBA_NAME() {
return BA_NAME;
}
public void setBA_NAME(String bA_NAME) {
BA_NAME = bA_NAME;
}
public String getDEPARTMENT_NAME() {
return DEPARTMENT_NAME;
}
public void setDEPARTMENT_NAME(String dEPARTMENT_NAME) {
DEPARTMENT_NAME = dEPARTMENT_NAME;
}
}
那么我们只需要创建实体类对象,然后把数据通过set方法传进去就可以了;
在oracle中关联表并操作和mySql一样,在这里就不做过多阐述了。
②带条件查询,查询条件为部门名称,即查询部门表中关联的分公司表和总公司表,如下:
在mySql中: 



获取数据时:起始站点名称为select后面的第一个数据,即下标值为1;
String sql =“select owner.OWNER_NAME,ba.BA_NAME,td.DEPARTMENT_NAME "+
"from tb_owner owner,tb_busi_area ba,tb_department td "+
"where owner.OWNER_ID=ba.OWNER_ID and ba.BA_ID=td.BA_ID and td.department_name=?";
我们将相关的查询信息select,从哪几个表中查询 from,关联条件 where ,书写完毕之后,通过"and"带上我们的查询条件,当传入指定参数时,会获取我们需要的结 果, 如当我们查询的td.department_name='人事部' 时,结果如下:
那么我们获取到了我们需要的结果,同样通过创建实体类,然后将数据通过set方法传进去就可以了;
在oracle中,查询语句和结果显示同mySql;
③一个表中两个字段都需要与另外同一个表关联:
表1:TB_LINE
那么在这里,我们可以看出START_STATION_ID和END_STATION_ID要获取的站点名称,肯定是来自于同一个数据表TB_STATION,如下:
表2:TB_STATION
这时候,我们要创建两个TB_STATION表,然后分别获取数据,根据select后面字段的位置来设置获取数据的下标值,从1开始计数,这时候我们的sql语句应该这么写:
String sql =“select ts1.STATION_NAME,ts2.STATION_NAME "+
"from TB_LINE tl, TB_STATION ts1,TB_STATION ts2 "+
"where ts1.STATION_ID=tl.START_STATION_ID and ts2.STATION_ID=tl.END_STATION_ID";
在mySql中可能会获取的名称有所不同,如下:
在oracle中获取的数据名称是一致的,即字段名都为STATION_NAME;
建议,通过获取数据的所在位置获取数据值,以保证数据的准确性;
终点站点名称为select后面的第二个数据,即下标值为2;
2、修改:在一个表a中,通过多个外键ID关联多个表,但展示给用户的显示及用户的筛选都是根据NAME字段来操作的,那么在执行update修改时,我们需要把相对 应的ID 传进去,这时候的sql语句如下:
String sql ="update tb_vehicle tv "+
"set tv.comp_id=(select comp.comp_id from tb_company comp where comp.comp_name=?),"+
"tv.metertype=?,"+
"tv.vt_id=(select vt.vt_id from tb_vehi_type vt where vt.vt_name=?),"+
"tv.vc_id=(select vc.vc_id from tb_vehi_color vc where vc.vc_name=?),"+
"tv.vnt_id=(select vnt.vnt_id from tb_vehi_no_type vnt where vnt.vnt_name=?),"+
"tv.vs_id=(select vs.vs_id from tb_vehi_state vs where vs.vs_name=? ),"+
"tv.vehi_num=? "+
"where tv.vehi_no=?";
"set tv.comp_id=(select comp.comp_id from tb_company comp where comp.comp_name=?),"+
"tv.metertype=?,"+
"tv.vt_id=(select vt.vt_id from tb_vehi_type vt where vt.vt_name=?),"+
"tv.vc_id=(select vc.vc_id from tb_vehi_color vc where vc.vc_name=?),"+
"tv.vnt_id=(select vnt.vnt_id from tb_vehi_no_type vnt where vnt.vnt_name=?),"+
"tv.vs_id=(select vs.vs_id from tb_vehi_state vs where vs.vs_name=? ),"+
"tv.vehi_num=? "+
"where tv.vehi_no=?";
在这里oracle和mySql的语句基本描述完成了!
附:
1、删除oracle某个序列号语句:DROP SEQUENCE 序列名;
2、删除数据表中某个不要的字段:ALTER TABLE 表名 DROP COLUMN 字段名;
3、通过时间作为查询数据的条件:
String sql = "select * from tb_time tt where to_char(tt.start_time,'yyyy-MM-dd')=? and to_char(tt.end_time,'yyyy-MM-dd')=?";
to_char是固定写法,to_char(tt.start_time,'yyyy-MM-dd') 表示将tt表中的start_time时间数据先转成‘yyyy-MM-dd’格式,然后去根据传入的时间值进行比对获取数据;
4.时间范围筛选:
①String sql = “select * from tb_time tt where to_char(tt.start_time,'yyyy-MM-dd') <=? and to_char(tt.end_time,'yyyy-MM-dd') >=? ”;
②String sql = "select * from tb_time tt where tt.tc_date between to_date('2017-02-15','yyyy-MM-dd') and to_date('2017-02-16','yyyy-MM-dd');
版权声明:本文为chengxc2016原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。