多表查询

一次查询两张以上的表,叫多表查询

1.交叉连接查询:很少使用,有错误数据
		格式:
			select * from 表A,表B; 
	2.内连接查询:在交叉连接查询的基础上,使用外键约束作为查询条件
			a.隐式内连接:不使用关键字 [inner] join on
				格式:
					select * from 表A,表B where 表A.主键 = 表B.外键;
			b.显示内连接:使用关键字 [inner] join on
				格式:
					select * from 表A [inner] join 表B on 表A.主键 = 表B.外键;
	3.外连接查询:在交叉连接查询的基础上,使用外键约束作为查询条件
		  a.左外连接查询:使用关键字left [outer] join on
				格式:
					select * from 表A left [outer] join 表B on 表A.主键 = 表B.外键;
				注意:
						左外连接查询以左边的表为主
							左边有的数据,右边没有使用null代替
							左边没有的数据,右边也不能出现
		  b.右外连接查询:使用关键字right [outer] join on
				格式:
					select * from 表A right[outer] join 表B on 表A.主键 = 表B.外键;
				注意:
						右外连接查询以右边的表为主
							右边有的数据,左边没有使用null代替
							右边没有的数据,左边也不能出现	
	4.子查询(sql语句的嵌套)
			a.一条sql语句的查询结果,作为另外一条sql语句的查询条件
				格式:
					select * from 表B where 字段 = (select 字段 from 表A [where 条件]);
			b.一条sql语句的查询结果,作为另外一条sql语句的另一张表(隐式内连接查询,先过滤数据)
				格式:
					select * from (select * from 表A [where 条件]),表B where 表A.主键 = 表B.外键

原生jdbc

(mysql5.0版本,8.0以上需做局部修改,如:驱动,url连接等…)
原生JDBC:使用java程序执行sql语句,对数据库表进增删改查(CURD)
使用步骤:固定
1.注册驱动
告之JVM我们使用的是那种数据库驱动程序(mysql,oracle…)
2.获取数据库连接对象Connection
java程序:TCP客户端 数据库:TCP服务器
使用客户端访问服务器,和服务器经过3次握手连接一个连接通路
这个连接通路中有一个IO流对象,用于客户端和服务器交互数据
3.获取执行者对象Statement
用于执行sql语句:把sql语句发送到数据库执行
4.执行sql语句,获取结果集
增删改: int affected(受影响的) 影响数据库的有效行数
查询: ResultSet结果集 把查询的多行结果存储到一个结果集中
int executeUpdate(String sql) 执行给定 SQL 语句,该语句可能为 INSERT、UPDATE 或 DELETE 语句
ResultSet executeQuery(String sql) 执行给定的 SQL 语句,该语句可能为SELECT

5.处理结果集
增删改:不用处理,打印
查询:遍历结果集
6.释放资源
注意:
1,2,3,6固定不变,4,5根据增删改查不同而不同

public class Demo01JDBC {
    public static void main(String[] args) throws SQLException, ClassNotFoundException {
        /*
            1.注册驱动
            使用java.sql.DriverManager类中的方法实现
            管理一组 JDBC 驱动程序的基本服务。
            static void registerDriver(Driver driver) 向 DriverManager 注册给定驱动程序。
            参数:
                java.sql.Driver driver:是一个接口,每个驱动程序类必须实现的接口。
                传递Driver接口的实现类对象,由mysql驱动提供
                com.mysql.jdbc.Driver
         */
        //DriverManager.registerDriver(new Driver());

        /*
            查询com.mysql.jdbc.Driver类的源码发现,有一个静态代码块,已经注册了驱动
            static {
                DriverManager.registerDriver(new Driver());
            }
            我们在注册一次驱动,就注册了两次,浪费
            解决方案:使用反射技术,获取class文件对象,会执行类中的静态代码块
            Class.forName("foo.bah.Driver")
         */
        Class.forName("com.mysql.jdbc.Driver");

        /*
            2.获取数据库连接对象Connection
            使用java.sql.DriverManager类中的方法实现
            static Connection getConnection(String url, String user, String password) 试图建立到给定数据库 URL 的连接。
            参数:
                String url:数据库服务器的地址,固定格式
                    jdbc:mysql://ip:端口号/数据库名称
                    jdbc:mysql://localhost:3306/day03 jdbc:mysql://127.0.0.1:3306/day03
                String user:数据库的用户名 root
                String password:数据库的密码 root
            返回值:
                java.sql.Connection是一个接口
                    返回的是Connection接口的实现类对象,由mysql驱动提供
                    我们可以使用Connection接口来接收这个实现类对象(多态)
         */
        Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/day03", "root", "root");
        //System.out.println(conn);//com.mysql.jdbc.JDBC4Connection@3891771e


        /*
            3.获取执行者对象Statement
            使用Connection接口中提供的方法实现
            Statement createStatement() 创建一个 Statement 对象来将 SQL 语句发送到数据库。
            返回值:
                 java.sql.Statement是一个接口
                    返回的是Statement接口的实现类对象,由mysql驱动提供
                    我们可以使用Statement接口来接收这个实现类对象(多态)
         */
        Statement stat = conn.createStatement();
        //System.out.println(stat);//com.mysql.jdbc.StatementImpl@78ac1102

        /*
            4.执行sql语句,获取结果集
            **使用Statement接口中的方法实现
                int executeUpdate(String sql) 执行给定 SQL 语句,该语句可能为 INSERT、UPDATE 或 DELETE 语句
                ResultSet executeQuery(String sql) 执行给定的 SQL 语句,该语句可能为SELECT**
         */
        int row = stat.executeUpdate("INSERT INTO products (pid, pname,price,flag,category_cid) " +
                "VALUES('p011','鼠标',80,'1','c001');");

        //5.处理结果集
        System.out.println(row);

        //6.释放资源
        stat.close();
        conn.close();
    }
}
JDBC查询处理之结果集
4.执行sql语句,获取结果集
            使用Statement接口中的方法实现
            ResultSet executeQuery(String sql) 执行给定的 SQL 语句,该语句可能为SELECT
            返回值:
                   java.sql.ResultSet是一个接口
                    返回的是ResultSet接口的实现类对象,由mysql驱动提供
                    我们可以使用ResultSet接口来接收这个实现类对象(多态)
         */
        ResultSet rs = stat.executeQuery("SELECT * FROM products;");
        //System.out.println(rs);//com.mysql.jdbc.JDBC42ResultSet@124c278f

5.处理结果集,遍历结果集
            和迭代器使用方式一模一样
            ResultSet接口中有一个方法叫next判断有没有下一行数据;有返回true,没有返回false
                boolean next() 将光标从当前位置向前移一行。
                如果新的当前行有效,则返回 true;如果不存在下一行,则返回 false
            ResultSet接口中有一个方法叫getXXX(列的索引/列名)取出结果
                int getInt(int columnIndex) :列的索引,从1开始
                int getInt(String columnLabel) :列名
                注意:数据库列是什么类型,就用get类型的方法获取这个字段
                也可以使用getObject来获取所有类型的字段,返回值是Object类型
         */
        while(rs.next()){
            /*String pid = rs.getString(1);
            String pname = rs.getString(2);
            int price = rs.getInt(3);
            String flag = rs.getString(4);
            String category_cid = rs.getString(5);*/
            String pid = rs.getString("pid");
            String pname = rs.getString("pname");
            int price = rs.getInt("price");
            String flag = rs.getString("flag");
            String category_cid = rs.getString("category_cid");
            System.out.println(pid+"\t"+pname+"\t\t"+price+"\t"+flag+"\t"+category_cid);
        }