mySql、oracle数据表的单表增删改查及多表关联查询

        在对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会识别错误;
                   
mySql、oracle数据表的单表增删改查及多表关联查询_第1张图片

           在此我们就已经将三张表关联起来,而且可以直接获取我们需要的数据:

          定义实体类封装需要的数据信息:

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中: 
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
mySql、oracle数据表的单表增删改查及多表关联查询_第2张图片

这时候,我们要创建两个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后面的第一个数据,即下标值为1;
终点站点名称为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=?";
     

        在这里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');


你可能感兴趣的:(数据库知识)