MySQL 和 JDBC编程


MySQL 相关



1. 什么是JDBC? 优势? 功能?

  • JDBC (Java Database Connectivity) 是Java数据库连接的意思, 是用来执行SQL语句的 JAVA API

  • 优势是跨平台, 跨应用; 实现同一种API访问不同平台不同数据库系统

  • 功能就是连接数据库, 执行SQL语句

2. JDBC 驱动程序是什么? 几种? 使用哪一种?

  • 数据库驱动程序就是JDBC和数据库之间的转换层, 将JDBC调用映射成数据库调用

  • 有 JDBC-ODBC, 直接将JDBC API 映射成数据库特定的客户端 API, 支持三层结构的 JDBC 访问方式, 纯JAVA直接与客户端交互4种

  • 正常使用 第四种

3. Win 10 安装MySQL步骤?

  • 下载MySQL安装压缩包

  • 下载 vcredist_x86.exe 并安装

  • 在MySQL安装包目录新建 my.ini 并正确编写

  • 将 MySQL 添加到环境变量并在 path 种添加MySQL环境变量

  • CMD 执行 mysqld -install 获取密码并更改密码

  • 重启MySQL服务 service MySQL restart

4. DBMS? MySQL数据库类型? MySQL引擎?

  • DBMS 是 Database management System 数据库管理系统的简称

  • MySQL 数据关系型数据库, 所使用的引擎是 InnoDB

5. 标准SQL语句的类型?

  • 查询语句: 由 select 关键字完成

  • DML(Data Manipulation Language) 数据操作语言: 主要由 insert, update, delete 关键字完成

  • DDL(Data Definition Language) 数据定义语言: 主要由 create, alter, drop, truncate 关键字完成

  • DCL(Data Control Language) 数据控制语言: 主要由 grant(授予), revoke(撤销) 关键字完成

  • 事务控制语句: 主要由 commit, rollback, savepoint 关键字组成

6. 创建数据库?

    CREATE DATABASE test CHARSET=UTF8;

7. 创建表语法?

    CREATE TABLE test_img (
        id int(10) not null PRIMARY KEY AUTO_INCREMENT,
        title varchar(20) not null,
        post_date datetime,
        photo mediumblob
    );

8. 子查询建表?

    CREATE TABLE new_test_img 
    as 
    SELECT * FROM test_img;

9. 增加/修改表结构?

    ALTER TABLE test 
    ADD (
        test_date date default '2019-12-31'
    );
    ALTER TABLE test 
    MODIFY name varchar(30) not null;

10. 删除数据表某一列语法?

    ALTER TABLE test
    drop word;

11. 重命名数据表?

    ALTER TABLE test 
    RENAME TO user;

12. 重命名数据表中的某列?

    ALTER TABLE user
    CHANGE  test_date age DATE NOT NULL DEFAULT '1990-01-01';

13. 删除数据库语法?

    DROP TABLE new_user;

14. 删除数据表数据, 保留语法结构?

    TRUNCATE user;

15. NOT NULL 只能作为列级约束例子?

    CREATE TABLE category (
    id INT NOT NULL AUTO_INSCREMENT PRIMARY KEY,
    category varchar(50) NOT NULL);

16. UNIQUE 唯一约束, 表级, 列级语法?

    -- 列级唯一约束
    CREATE TABLE user1 (
        id INT(10) NOT NULL UNIQUE,
        username varchar(50) NOT NULL DEFAULT 'admin'
    );

    -- 表级唯一约束
    CREATE TABLE user2 (
        id INT(10) NOT NULL,
        username varchar(50) NOT NULL DEFAULT 'admin',
        -- 表级约束
        UNIQUE (id));

    -- 表级唯一约束, 且指定约束名
    CREATE TABLE user3 (
        id INT(10) NOT NULL,
        username varchar(50) NOT NULL DEFAULT 'admin',
        CONSTRAINT user3_unique UNIQUE (id, username)
    );

17. 删除, 修改唯一约束?

    -- 修改唯一约束
    ALTER TABLE user3 
    MODIFY id INT(10) NOT NULL UNIQUE;

    -- 删除约束
    -- 可以通过 SHOW CREAE TABLE user3; 语句来查看唯一约束的约束名
    ALTER TABLE user3 
    DROP INDEX user3_unique;

18. PRIMARY KEY 主键约束是什么?

  • 主键约束相当于非空约束和唯一约束的组合, 每张表只能有一个主键约束

  • 主键约束有表级以及列级约束之分, 也可以指定组合作为主键约束

19. 列级主键约束, 表级主键约束?

    -- 列级约束
    CREATE TABLE test1 (
        id INT(10) PRIMARY KEY AUTO_INCREMENT,
        test_name VARCHAR(50) NOT NULL 
    );

    -- 表级约束
    CREATE TABLE test2 (
        id INT(10) AUTO_INCREMENT,
        test_name VARCHAR(50),
        CONSTRAINT test_pk PRIMARY KEY(id)
    );

20. 删除主键约束?

    ALTER TABLE test2 
        DROP PRIMARY KEY;

21. 什么是外键约束 FOREIGN KEY?

  • 外键约束是一种参照关系, 即一张表的两个字段或两张表的两个字段之间的参照关系

  • 参照关系: 子表外键列的值必须在主表被参照列的值范围之内, 或者为空

  • 从表外键参照的只能是主表主键列或者唯一列, 同一表可以有多个外键

22. 创建外键约束的例子?

    -- 例子1: 实例 建立blog数据库
    create database blog charset=utf8;
    -- 建立 User 表
    -- 如果想删除主表(user)记录时, 从表(blog)记录也会随之删除, 则需要在建立外键约束后添加 on delete cascade
    -- 或者添加 on delete set null (第一种:主表删除后,从表记录也全部级联删除; 第二种: 主表删除后, 参照该主表
    -- 记录的外键设为null)
    create table user (
        user_id int not null primary key auto_increment,
        user_name varchar(255) not null unique,
        create_date datetime not null,
        is_admin boolean defaule false
    );
    --
    -- 建立 category 表
    create table category (
        category_id int not null auto_increment primary key,
        category_name varchar(255) not null unique
    );
    --
    -- 建立 blog 主表 使用表级约束语法
    create table blog (
        title varchar(255) not null,
        blog_user varchar(255),
        blog_category varchar(255),
        blog_body text,
        -- 表级约束
        foreign key (blog_user) references user(user_name) on delete cascade,
        foreign key (blog_category) references category(category_name) on delete set null
    );

23. 索引是什么? 自动创建索引? 手动创建索引?

  • 索引是存放在模式(schema)中的一个数据库对象, 作用是加速对表的查询

  • 自动创建索引: 当定义了唯一约束, 主键约束, 外键约束时, 系统自动为该数据列创建对应的索引

  • 手动创建索引: 通过 create index 语法来手动创建索引

24. 创建索引, 删除索引?

    -- 创建单独列的索引
    create index emp_last_name_idx 
    on employees(last_name);
    --
    -- 同时对多列创建索引
    create index emp_last_name_idx2 
    on employees(first_name, last_name);
    --
    -- 删除索引
    drop index emp_last_name_idx2
    on employees;

25. 什么是视图?

  • 视图是一个或多个数据表中数据的逻辑显示, 视图不存储数据, 也不是数据表

26. 创建删除视图?

-- 创建一个视图
    create view blog_all
    as 
    select * from blog;
   --
   -- 删除上面创建的视图名
    drop view blog_all;

27. insert into 数据表插入语句?

    -- 同时插入多条语句
    insert into user values
    (0, 'python', '2018-08-08'),
    (0, 'java', '2019-09-01'),
    (0, 'CSS', '2019-05-01');

28. update 语句修改表?

  • update 语句用于修改表数据, 可一次修改一条或多条或多列记录, 可以通过 WHERE 来限定修改那些记录
    -- 语法
    update table_name 
    set column1 = value1[, column2 = value2]...
    [WHERE condition];

    -- 例子
    update user 
    set name = 'Java' where id = 2;

29. delete from 语句删除指定表的记录?

  • delete from 语句用于删除指定数据表的记录, delete from 总是整行删除记录, 也可以通过 WHERE 来限定删除条件
    -- 语法:
    delete from table_name
    [WHERE condition];
    --
    -- 例子:
    -- 删除student_table2表中的全部记录
    delete from student_table2;

    -- 通过 where 来限定删除条件
    delete from student_table2 
    where teacher_id > 2;


JDBC 相关



1. 简述 JDBC4.2 常用接口和类---DriverManger类?

  • DriverManager 类主要是用于管理JDBC驱动的服务类, 主要功能就是获取 Connection 对象

  • 用法: Connection conn = DriverManager.getConnection(String url, String user, String password)

2. 简述 JDBC4.2 常用接口和类---Connection接口及接口的主要方法?

  • Connection 代表了数据库的连接对象, 每个Connection代表一个物理连接会话, 想访问数据库, 必须先获得数据库连接

  • Connection 常用的方法:

    • Statement createStatement() throws SQLException(); 获得一个Statement对象

    • PreparedStasement preparedStatement(String sql) throws SQLException 获得一个预编译的 PreparedStasement 对象, 可以传入带有参数的SQL语句

    • CallableStatement prepareCall(String sql) throws SQLException 返回 CallableStatement 对象

3. 简述 Statement 接口?

  • 用于执行SQL语句的工具接口, 该对象可执行DDL, DCL, DML 以及 SQL查询语句, 执行SQL查询语句时返回查询到的结果集

  • Statement 常用方法:

    • ResultSet executeQuery(String sql) throws SQLException; 用于执行查询语句, 并返回查询结果对应的 ResultSet 对象, 该方法只能用于执行查询语句

    • int executeUpdate(String sql) throws SQLException; 该方法用于执行DML语句, 并返回执行后受影响的行数; 也可用于执行DDL语句, 执行DDL语句返回0

    • boolean execute(String sql) throws SQLException; 该方法可执行任何SQL语句, 如果执行后的第一个结果为 ResultSet 对象, 则返回 true; 如果执行后第一个结果为受影响的行数或没有任何结果, 则返回false

    • executeLargeUpdate()

4. 简述 PreparedStatement 接口?

  • 预编译的 Statement 对象, 它允许数据库预编译SQL语句(这些SQL语句通常都带有参数), 以后每次只改变SQL命令参数, 避免数据库每次都要编译SQL语句

  • PreparedStatement 同样有 executeUpdate(), executeQuery() 以及

5. 简述 ResultSet 结果集?

  • ResultSet 结果集是 Statement 接口的查询方法 executeQuery(String sql) 以及 execute(String sql) 查询语句执行后的返回对象; 该对象包含执行查询语句的结果, ResultSet 可以通过列索引或列名获得列数据

  • 当通过移动指针到指定行之后, ResultSet 可通过 getXxx(int columnIndex) 或 getXxx(String columnLabel) 方法来获取当前行, 指定列的值, 前者根据索引来获取值, 后者通过列名来获取值

  • 移动指针的方法:

    • boolean absolute(int row) 将结果集的记录指针移动到第row行, 如果 row 为负数, 则移动到倒数第 row 行

    • void beforeFirst() 定位到第一行之前

    • void afterLast() 定位到最后一行之后

    • boolean previous() 定位到前一行

    • boolean next() 定位到后一行

    • boolean first() 定位到行首

    • boolean last() 定位到行尾

6. 简述 JDBC 编程步骤(以MySQL为例)?

  • 第一步: 通过 Class.forName(dirverclass) 静态方法来加载数据库驱动

    Class.forName("com.mysql.cj.jdbc.Driver");

  • 第二步: 通过 DriverManager.getConnection(url, user, password) 方法获取数据库连接

    String url = "jdbc:mysql://localhost:3306/blog?useSSL=false&serverTimezone=UTC";
    String user = "root";
    String password = "password";
    Connection conn = DriverManager.getConnection(url, user, password);

  • 第三步: 通过Connection对象创建 Statement 对象

    Statement stmt = conn.createStatement(); 创建基本的Statement对象
    PreparedStatement pstmt = conn.PreparedStatement(Sql); 创建预编译的 PreparedStatement 对象

  • 第四步: 通过 Statement 或 PreparedStatement 对象调用 execute() 或 executeUpdate() 或 executeQuery() 方法执行SQL语句

    stmt.execute() 可执行任何SQL语句, 但是比较麻烦
    stmt.executeUpdate() 执行DML(返回int类型的受影响的行数),DDL语句(返回int类型的0)
    stmt.exeuteQuery() 只能执行查询语句, 返回的是 ResultSet 类型的结果集

  • 第五步: 操作 ResultSet 结果集

    next(), previous(), first(), last(), beforeFirst(), afterLast() 这些事移动指针的方法
    getString(), getInt() 这些是获取移动到指定行列的数据的方法

  • 第六步: 反向关闭资源

    反向关闭 ResultSet, Statement, Connection 等资源

7. 使用 JDBC 进行MySQL数据库增删改查的例子?

    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.SQLException;
    /**
     * JDBCUtil.java
     * 用来获取 Connection 类型的数据库连接
     */
    public class JDBCUtil {
        final static String driver = "com.mysql.cj.jdbc.Driver";
        final static String url = "jdbc:mysql://localhost:3306/blog?useSSL=false&serverTimezone=UTC";
        final static String user = "root";
        final static String password = "password";

        static {
            try {
                Class.forName(driver);
            } catch (ClassNotFoundException e) {
                System.out.println("数据库驱动加载失败");
                e.printStackTrace();
            }
        }

        public static Connection getConn() throws SQLException{
            return DriverManager.getConnection(url, user, password);
        }
        
        public static void closeConn(Connection conn) {
            if (null != conn) {
                try {
                    conn.close();
                } catch (SQLException e) {
                    System.out.println("Connection close failed!");
                    e.printStackTrace();
                }
            }
        }
    }
    import java.sql.Connection;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.sql.Statement;

    import java.sql.ResultSetMetaData;

    public class CRUDUtil {
        /**
         * MySQL数据库CRUD
         * 执行 DML 或 DDL 语句 
         */
        public static void exeuteDDLOrDDM(String sql) throws Exception {
            try (
                Connection conn = JDBCUtil.getConn();
                Statement stmt = conn.createStatement()) {
                int result = stmt.executeUpdate(sql);
                if (result != 0) {
                    System.out.println("执行DML语句后, 有[" + result + "]条记录受影响" + "\n");
                } else {
                    System.out.println("已执行DDL语句, 并成功返回[" + result + "]" + "\n");
                }
            }
        }

        /**
         * MySQL数据库CRUD
         * 执行 查询 语句 
         */
        public static void executeSelect(String sql) throws Exception {
            try (
                Connection conn = JDBCUtil.getConn();
                Statement stmt = conn.createStatement()) {
                ResultSet rs = stmt.executeQuery(sql);
                while (rs.next()) {
                    System.out.println(rs.getString(1) + "\t"
                        + rs.getString(2) + "\t"
                        + rs.getString(3) + "\t");
                }
            }
        }

        /**
         * MySQL数据库CRUD
         * 可执行 任何 SQL语句 
         */
        public static void executeSQL(String sql) throws SQLException {
            try (
                Connection conn = JDBCUtil.getConn();
                Statement stmt = conn.createStatement()) {
                boolean hasResultSet = stmt.execute(sql);
                if (hasResultSet) {
                    try (
                        ResultSet rs = stmt.getResultSet()) {
                        ResultSetMetaData rsmd = rs.getMetaData();
                        int columnCount = rsmd.getColumnCount();
                        while (rs.next()) {
                            for (int i = 0; i < columnCount; i++) {
                            System.out.print(rs.getString(i + 1) + "\t"); 
                            }
                            System.out.print("\n");
                        }
                    }
                } else {
                    System.out.println("该SQL语句影响的记录有[" 
                    + stmt.getUpdateCount() + "]条");
                    
                }
            }
        }
    }

    public class JDBCDemo {
        /**
         * MySQL SQL语句类型:
         *      DML : insert, update, delete
         *      DDL : create, alter, drop, truncate
         *      DCL : grant, revoke
         *      查询语句 : select
         * 
         * Statement用于执行SQL语句的方法:
         *      ResultSet executeQuary(String sql)方法只能执行查询语句
         *      int executeUpdate(String sql) 方法可执行DML或DDL语句
         *      boolean execute(String sql) 可执行任何SQL语句
         */

        // DDL
        static String sql1 = "create table demo "
            + "(d_id int primary key auto_increment,"
            + "d_name varchar(255),"
            + "d_body text);";
        static String sql8 = "truncate demo";
        static String sql9 = "alter table demo add photo mediumblob";

        // DML 
        static String sql2 = "insert into demo values(0,'jeff','desc jeff .....',null)";
        static String sql3 = "insert into demo values(0,'cony','desc cony .....',null)";
        static String sql4 = "insert into demo values(0,'hurry','desc hurry .....',null)";

        // select
        static String sql5 = "select * from demo";
        static String sql10 = "desc demo";

        // DML 
        static String sql6 = "update demo set d_name='JULIA', d_body='desc julia.....' where d_id=4";
        static String sql7 = "delete from demo where d_id=4";

        public static void main(String[] args) throws Exception {
            // CRUDUtil.exeuteDDLOrDDM(sql9);
            // CRUDUtil.executeSelect(sql5);
            CRUDUtil.executeSQL(sql5);
        }
    }

8. 离线 RowSet 接口简述?

  • RowSet 接口继承了 ResultSet 接口, RowSet 接口包含了 JdbcRowSet, CachedRowSet, FilteredRowSet, JoinRowSet 和 WebRowSet 常用子接口; 其中 JdbcRowSet需要保持与数据库的连接之外, 其余4个子接口都是离线的RowSet, 无须保持与数据库的连接

  • 离线 RowSet 会直接将底层数据读入内存中, 封装成 RowSet 对象, 而 RowSet 对象则完全可以当成 java Bean 来使用

  • 对离线的 RowSet, 程序在创建 RowSet 时已把数据从底层数据库加载到内存,从而降低数据库服务器的负载, 提高性能

  • CachedRowSet 是所有离线 RowSet 的父接口

9. RowSet 接口常用方法?

  • setUrl(String url) 设置该RowSet要访问的数据库的RUL

  • setUserName(String Name) 设置该RowSet要访问的数据库的用户名

  • setPassword(String password) 设置该RowSet要访问的数据库的密码

  • setCommand(String sql) 设置使用该sql语句的查询结果来装填该RowSet

  • execute() 执行查询语句

  • populate(ResultSet rs) 让该RowSet直接包装给定的ResultSet对象

10. RowSetProvider 类 和 RowSetFactory 接口?

  • Java 7 新增了 RowSetProvider类 和 RowSetFactory 接口, 其中 RowSetProvider 负责创建 RowSetFactory,而 RowSetFactory 通过方法创建 RowSet 实例, 这样就把应用程序与RowSet实现类分离开

  • 方法:

    • RowSetFactory factory = RowSetProvider.newFactory();

11. RowSetFactory 提供的创建 RowSet 实例的方法?

  • CachedRowSet createCachedRowSet() 创建一个默认的 CachedRowSet

  • FilteredRowSet createFilteredRowSet() 创建一个默认的 FilteredRowSe

  • dbcRowSet createJdbcRowSet() 创建一个默认的 JdbcRowSet 不支持离线

  • JoinRowSet createJoinRowSet() 创建一个默认的 JoinRowSet

  • WebRowSet createWebRowSet() 创建一个默认的 WebRowSet

12. 装填 RowSet 两种方法?

  • 第一种: 通过Statement对象执行 executeQuery() 方法返回 ResultSet 对象; 调用RowSet实例的 populate(ResultSet rs) 方法, 并将上述的ResultSet 对象传入其中进行装填

  • 第二种: 通过 RowSet实例的 setCommand(sql) 和 execute() 方法执行SQL查询, 用返回的数据来装填RowSet

13. 装填 RowSet 两种方法的两种例子?

    `import java.sql.Connection;
    import java.sql.ResultSet;
    import java.sql.Statement;

    import javax.sql.rowset.CachedRowSet;
    import javax.sql.rowset.RowSetFactory;
    import javax.sql.rowset.RowSetProvider;

    import app.MyINI;

    public class RowSetFactoryTest1 {
        static MyINI myini = new MyINI();

        public static void query1(String sql) throws Exception {
            Connection conn = JDBCUtil.getConn();
            Statement stmt = conn.createStatement();
            ResultSet rs = stmt.executeQuery(sql);
            RowSetFactory factory = RowSetProvider.newFactory();
            CachedRowSet cachedRs = factory.createCachedRowSet();
            cachedRs.populate(rs);
            cachedRs.beforeFirst();
            while (cachedRs.next()) {
                System.out.println(cachedRs.getString(1) + "\t"
                        + cachedRs.getString(2) + "\t"
                        + cachedRs.getString(3) + "\t"
                        + cachedRs.getString(4) + "\t");
            }
            rs.close();
            stmt.close();
        }

        public static void query2(String sql) throws Exception {
            Class.forName(myini.driver);
                //
                // 使用 RowSetProvider 创建 RowSetFactory
                RowSetFactory factory = RowSetProvider.newFactory();
            try (
                // 使用 RowSetFactory 创建默认的 JdbcRowSet 实例
                CachedRowSet cachedRs = factory.createCachedRowSet()) {
                cachedRs.setUrl(myini.url);
                cachedRs.setUsername(myini.user);
                cachedRs.setPassword(myini.pass);
                // 设置SQL查询语句
                cachedRs.setCommand(sql);
                // 执行查询语句
                cachedRs.execute();
                cachedRs.beforeFirst();
                // 向前滚动结果集
                while (cachedRs.next()) {
                    System.out.println(cachedRs.getString(1) + "\t"
                        + cachedRs.getString(2) + "\t"
                        + cachedRs.getString(3) + "\t"
                        + cachedRs.getString(4) + "\t");
                }
            }
        }
        public static void main(String[] args) throws Exception {
            query1("select * from demo");
            System.out.println("=========================");
            query2("select * from demo");
            
        }
    }

你可能感兴趣的:(MySQL 和 JDBC编程)