MySQL 多表& JDBC

外键:
现在我们有两张表”分类表“和”商品表“,为了表明商品属于哪个分类,通常情况下,我们将在商品表上加一列,用于存放 cid 的信息,此列称为:外键

category(分类)
cid
cname

products(商品)
pid
name
price
category_id(外键字段)
此时”分类表 category“称为主表,”cid“我们称之为主键,”商品表  products“称为从表,”category_id“称为外键,我们通过主表的主键和从表的外键来描述主外键关系,呈现出的是一对多的关系。

外键特点:
从表外键值是 对主表主键的引用
从表外键类型必须和主表主键类型一致

声明外键约束:
语法:alter table 从表 add [constraint] [外键名称] foreign key(从表外键字段名) refereces  主表 (主表的主键)

创建分类表:
CREATE TABLE category(
cid VARCHAR(32) PRIMARY KEY,
cname VARCHAR(100)
);
INSERT INTO category(cid,cname) VALUES('c001','家电');
INSERT INTO category(cid,cname) VALUES('c002','服饰');
INSERT INTO category(cid,cname) VALUES('c003','化妆品');



创建商品表:
CREATE TABLE category(
cid VARCHAR(32) PRIMARY KEY,
cname VARCHAR(100)
);
INSERT INTO product(pid,pname,price,category_id) VALUES('p001','联想','5000','c001');
INSERT INTO product(pid,pname,price,category_id) VALUES('p002','海尔','5000','c001');
INSERT INTO product(pid,pname,price,category_id) VALUES('p003','雷神','5000','c001');

INSERT INTO product(pid,pname,price,category_id) VALUES('p004','JACK JONES','800','c002');
INSERT INTO product(pid,pname,price,category_id) VALUES('p005','真维斯','200','c002');
INSERT INTO product(pid,pname,price,category_id) VALUES('p006','花花公子','440','c002');
INSERT INTO product(pid,pname,price,category_id) VALUES('p007','劲霸','2000','c002');

INSERT INTO product(pid,pname,price,category_id) VALUES('p008','香奈儿','800','c003');
INSERT INTO product(pid,pname,price,category_id) VALUES('p009','相宜本草','200','c003');

建立关联:
alter table product add foreign key (category_id) references category(cid)




使用外键的目的:
保证数据的完整性

一对多建表原则:
在多的一方创建一个字段,字段作为外键指向一的一方的主键

多对多关系建表原则:
需要创建第三张表,中间表至少l两个字段,这两个字段分别作为外键指向另一方主键。

创建订单表:
CREATE TABLE orders(
    oid VARCHAR(32) PRIMARY KEY,
    totalprice DOUBLE
);

创建订单项表:
CREATE TABLE orderitem(
    oid VARCHAR(50),
    pid VARCHAR(50)
);


订单表和订单项表的主外键关系:
alter table orderitem add constraint orderitem_orders_fk foreign key(oid) references orders(oid);

商品表和订单项表的主外键关系:
alter table orderitem add constraint orderitem_product_fk foreign key(pid) references product(pid);


多表查询(三种方式及其区别)
1、交叉连接查询:
SELECT * FROM category,product;
1 queries executed, 1 success, 0 errors, 0 warnings

查询:select * from category,product LIMIT 0, 1000

返回了 27 行

执行耗时   : 0.042 sec
传送时间   : 0.001 sec
总耗时      : 0.044 sec


2、内连接查询(使用关键字 inner join --inner可以省略):
    隐式内连接:select * from A,B where 条件;
    显示内连接:select * from A inner join B on 条件;
3、外连接查询:(使用关键字 outer join --outer可以省略)
    左外连接:left outer join
        select * from A left outer join B on 条件
    右外连接:right outer join
        select * from A right outer join B on 条件


现在看看左外连和右外连接的区别:
INSERT  INTO category VALUES('c004',NULL);
INSERT INTO product VALUES ('p010','海飞丝',0.5,NULL);





子查询:
一条 select 语句结果作为另一条 select 语法的一部分(查询条件, 查询结果, 表等)。
 查询“化妆品”分类上架商品信息



JDBC工具类:


package com.itcast.ma;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

/**
* 工具类
* 提供获取连接及释放资源的方法
* @author lenovo
*
*/

public class JDBCUtils {
    /**
     * 获取连接方法
     * @return
     */
    public static Connection getConnection(){
        Connection conn = null;
        try {
            Class.forName("com.mysql.jdbc.Driver");
            
            conn = DriverManager.getConnection("jdbc: mysql://localhost:3306/user ","root","123456");
            
        } catch (Exception e) {
            
            e.printStackTrace();
        }
        
        
        return conn;
    }
    /**
     * 释放资源方法
     * @param conn
     * @param pstmt
     * @param rs
     */
    public static void release(Connection conn, PreparedStatement pstmt, ResultSet rs){
        if(rs != null){
            try {
                rs.close();
            } catch (SQLException e) {
                
                e.printStackTrace();
            }
        }
        if(pstmt != null){
            try {
                pstmt.close();
            } catch (SQLException e) {
                
                e.printStackTrace();
            }
        }
        if(conn != null){
            try {
                conn.close();
            } catch (SQLException e) {
                
                e.printStackTrace();
            }
        }
    }

}

查询数据:

package com.ma.test;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.junit.Test;
import com.itcast.ma.JDBCUtils;
/**
 *测试工具类
 * @author lenovo
 *
 */
public class TestUtils {
       /**
       * 根据id查询
       */
       @Test
       public void testFindUserById (){
            Connection conn = null ;
            PreparedStatement pstmt  = null ;
            ResultSet rs = null ;
      
             try {
                   //1、获取连接
                  conn = JDBCUtils. getConnection ();
                   //2、编写 sql
                  String sql = "select * from t_user where uid = ?" ;
                   //3、获取执行语句对象
                  pstmt = conn.prepareStatement(sql);
                   //4、设置参数
                  pstmt.setInt(1, 2);
                   //5、查询
                  rs = pstmt.executeQuery();
                   //6、处理资源
                   while (rs.next()){
                        System. out .println(rs.getString(2)+ "----" + rs.getString( "password" ));
                  }
                  
            } catch (SQLException e) {
                  
                  e.printStackTrace();
            } finally {
                   //7、释放资源
                  JDBCUtils. release (conn, pstmt, rs);
            }
            
      }  
}

测试结果:


使用 properties 配置文件:

开发过程中获得连接的四个参数(驱动、url 、用户名、密码)通常都存放在配置文件中,方便后期维护,程序如果需要更换数据库,只需要修改配置文件即可。
1、文件位置:建议 src 下面。
2、文件名称:任意,扩展名为 properties。
3、文件内容:一行一组数据,格式是“key = value”;key 名自定义,如果多个单词用 . 分隔;value 不支持中文。

driver = com.mysql.jdbc.Driver
url = jdbc;mysql://localhost:3306/user?useUnicode = true & characterEncoding = utf-8
username = rooot
password = 123456

加载配置文件:ResourceBundle 对象。

package com.itcast.ma;
import java.util.ResourceBundle;
/**
 * 工具类
 * 提供获取连接及释放资源的方法
 * @author lenovo
 *
 */
public class JDBCUtils {
       private static String driver ; //驱动
       private static String url ; //路径
       private static String user ; //用户
       private static String password ; //密码
       /**
       * 配置文件只需要加载一次,提供静代码,当前类被加载到内存执行
       */
       static {
             //1、使用 JDK 提供的工具类加载 properties 文件
             //ResourceBundle 专门处理 properties 文件,提供 getBundle() 方法,只需要写入文件。
            ResourceBundle bundle = ResourceBundle. getBundle ( "db" );
             //2、通过 key 获取需要的值
             driver = bundle.getString( "driver" );
             url = bundle.getString( "url" );
             user = bundle.getString( "username" );
             password = bundle.getString( "password" );
            
      }
}

插入数据:



/**
       * 添加用户信息方法
       */
       @Test
       public void testAdd (){
            Connection conn = null ;
            PreparedStatement pstmt = null ;
            
             try {
                   //1、获取连接
                  conn = JDBCUtils. getConnection ();
                   //2、书写 sql 语句
                  String sql = "insert into t_user values(null,?,?,?)" ;
                   //3、获取 sql 执行对象
                  pstmt = conn.prepareStatement(sql);
                   //4、设置参数
                  pstmt.setString(1, "MaYue" );
                  pstmt.setString(2, "321456" );
                  pstmt.setString(3, "LIN" );
                   //5、执行插入操作
                   int row = pstmt.executeUpdate();
                   if (row > 0){
                        System. out .println( "插入成功 !" );
                  }
            } catch (SQLException e) {
                  
                  e.printStackTrace();
            }
            
      }

删除数据:

/**
       * 根据id 删除用户的方法
       */
       @Test
       public void testDelete (){
            Connection conn = null ;
            PreparedStatement pstmt = null ;
            
             try {
                   //1、获取连接
                  conn = JDBCUtils. getConnection ();
                   //2、书写 sql 语句
                  String sql = "delete from t_user where uid = ?" ;
                   //3、获取 sql 执行对象
                  pstmt = conn.prepareStatement(sql);
                   //4、设置参数
                  pstmt.setInt(1, 9);
                   //5、执行插入操作
                   int row = pstmt.executeUpdate();
                   if (row > 0){
                        System. out .println( "删除成功 !" );
                  } else {
                        System. out .println( "删除失败 !" );
                  }
            } catch (SQLException e) {
                  
                  e.printStackTrace();
            } finally {
                   //6、释放资源
                  JDBCUtils. release (conn, pstmt, null );
            }
            
            
      }



更新数据:

/**
       * 根据id 更新用户的方法
       */
       @Test
       public void testUpdate (){
            Connection conn = null ;
            PreparedStatement pstmt = null ;
            
             try {
                   //1、获取连接
                  conn = JDBCUtils. getConnection ();
                   //2、书写 sql 语句
                  String sql = "update t_user set password = ? where uid = ?" ;
                   //3、获取 sql 执行对象
                  pstmt = conn.prepareStatement(sql);
                   //4、设置参数
                  pstmt.setString(1, "666666" );
                  pstmt.setInt(2, 1 );
                   //5、执行插入操作
                   int row = pstmt.executeUpdate();
                   if (row > 0){
                        System. out .println( "更新成功 !" );
                  } else {
                        System. out .println( "更新失败 !" );
                  }
            } catch (SQLException e) {
                  
                  e.printStackTrace();
            } finally {
                   //6、释放资源
                  JDBCUtils. release (conn, pstmt, null );
            }
            
            
      }



猜你喜欢

转载自blog.csdn.net/young_1004/article/details/80702736
今日推荐