MySQL--04

一、三大范式

1、第一范式:原子性 保证每一列不可再分

2、第二范式:在满足第一范式的前提下,每张表只能描述一件事情

3、第三范式:在满足第一第二范式的前提下,第三范式需要确保数据表中的每一列数据都和主键直接相关,不能间接相关。

 

规范数据库的设计:规范性和性能的问题

阿里规范:关联查询的表不得超过三张表

·考虑商业化得需求和目标(成本和用户体验)数据库得性能更加重要

·在规范性能得问题得时候,需要适当的考虑一下规范性

·故意给某些表增加一些冗余得字段(从多表查询变为单表查询)

·故意增加一些计算列(从大数据量降低为小数据量得查询)//或者用索引,但索引树比较占内存

二、JDBC

用Java操作数据库,程序通过数据库驱动和数据库打交道。

每个公司有每个公司得数据库驱动,mysql oracle...

sun公司为了简化开发人员得操作,提供了一个Java操作数据库得规范,俗称JDBC

这些规范的实现由具体得厂商去做

三、Java做JDBC的原理

其实就是在可视化工具中做的操作用Java代码实现。

正常第一步,打开可视化工具(加载驱动),输入用户名密码和url对数据库进行连接 连接成功相当于返回了一个数据库对象

第二部,编写完sql之后执行sql  就这么简单。

package space.urbeautiful.jdbc;

import java.sql.*;

public class jdbcTest {

    public static void main(String[] args) throws ClassNotFoundException, SQLException {
        //1、加载驱动
        Class.forName("com.mysql.jdbc.Driver");//固定写法,加载驱动
        //2、用户信息和url
        //useUnicode=true&characterEncoding=utf&useSSL=true";
        //useUnicode=true--支持中文编码   characterEncoding=utf8--字符集为utf8  utf&useSSL=false--使用安全连接
        String url = "jdbc:mysql://localhost:3306/jzspace?useUnicode=true&characterEncoding=utf8&useSSL=true";
        String userName = "root";
        String password = "space999";
        //3、连接成功 返回一个数据库对象  这个Connection就代表数据库
        Connection conn = DriverManager.getConnection(url, userName, password);//驱动管理来获得连接
        //4、执行SQL的对象    Statement执行sql的对象
        Statement stat = conn.createStatement();
        //5、SQL的对象去执行sql   执行完毕可能存在结果,查看返回结果
        String sql = "select * from users";
        ResultSet resultSet = stat.executeQuery(sql);//返回的结果集,结果集中封装了所有我们查出来的结果,是一个链表形式

        while(resultSet.next()){
            System.out.println("id" + resultSet.getObject("id"));
            System.out.println("name" + resultSet.getObject("name"));
            System.out.println("psw" + resultSet.getObject("psw"));
            System.out.println("email" + resultSet.getObject("email"));
            System.out.println("birthday" + resultSet.getObject("birthday"));
        }
        //6、释放连接
        resultSet.close();
        stat.close();
        conn.close();
    }
}

1、加载驱动  Class.forName("");

2、用户信息和url

3、连接数据库   DriverManager.getConnection();

4、创建一个执行sql的对象   Statement

5、sql语句用statement执行   stat.executeQuery()执行查询语句    stat.executeUpdate()执行update insert delete等操作

6、加载结果集数据

7、关闭连接  从下到上

JAVA万物皆对象,所以将这些操作都整合成为对象来进行操作。

四、详解JDBC-->JAVA中的对象

1、DriverManager

//DriverManager.registerDriver(new com.mysql.jdbc.Driver());
Class.forName("com.mysql.jdbc.Driver");
Connection conn = DriverManager.getConnection(url,username,password);
//Connection代表数据库 用数据库写的代码它都能写 他就是数据库的对象
//数据库设置自动提交
//事务提交 事务回滚
conn.commit();
conn.rollback();
conn.setAutoCommit();//设置自动连接 //推荐使用Class.forName 加载驱动 //上面那个是注册驱动,在Driver()方法中的静态代码块中已经给注册了一个驱动,可能出现重读注册驱动 /* static { try { DriverManager.registerDriver(new Driver()); } catch (SQLException var1) { throw new RuntimeException("Can't register driver!"); } } */

2、URL

String url = "jdbc:mysql://localhost:3306/jzspace?useUnicode=true&characterEncoding=utf8&useSSL=true";

/*
jdbc:mysql://localhost:3306   直接看作是一个网址
jdbc:mysql看作是https这种协议
localhost 看作主机名
3306 看作端口号
公式:协议://主机地址:端口号/数据库名?参数1&参数2&参数3

oracle的写法:
jdbc:oracle:thin:@localhost:1521:sid
*/

3、Statement执行SQL的对象   PrepareStatement执行SQL的对象

String sql = "select * from users";//编写sql

statement.executeQuery();//查询操作返回结果集ResultSeet
statement.execute();//执行任何sql
statement.executeUpdate();//更新,插入,删除都使用这个,返回一个受影响的行数

4、ResultSet  结果集  只有查询操作才有结果集   封装了所有的查询结果

//在不知道列类型的情况下使用getObject()
resultSet.getObject();
//如果知道列类型就使用指定的类型
resultSet.getString();
resultSet.getInt();
resultSet.getFloat();
resultSet.getDate();
//...

5、遍历结果集

resultSet.next();//移动到下一个数据

6、释放资源

resultSet.close();
stat.close();
conn.close();//十分耗资源,用完关掉!

五、详解Statement对象

Jdbc中的statement对象适用于向数据库发送sql语句,像完成对数据库的增删改查,只需要通过这个对象向数据库发送增删改查的语句即可。

Statement对象的executeUpdate方法,用于向数据库发送增、删、改的sql语句,execcuteUpdate执行完后,将会返回一个整数(即增删改语句导致数据库几行数据发生了变化)

Statement.executeQuery方法用于向数据库发送查询语句,executeQuery方法返回代表查询结果的ResultSet对象

1、CRUD操作-insert  使用executeUpdate(String sql)方法完成数据添加操作:

Statement stat = conn.createStatement();
String sql = "insert into table(...) values(...)";
int num = stat.executeUpdate(sql);
if(num>0){
     System.out.println("插入成功");
}

2、CRUD操作-delete  使用executeUpdate(String sql)方法完成数据删除操作:

Statement stat = conn.createStatement();
String sql = "delete from student where StudentNo=1004";
int num = stat.executeUpdate(sql);
if(num>0){ 
    System.out.println("删除成功");
}

3、CRUD操作-update  使用executeUpdate(String sql)方法完成数据更新操作:

Statement stat = conn.createStatement();
String sql = "update table set column='' where id=''";
int num = stat.executeUpdate(sql);
if(num>0){
    System.out.println("更新成功");
}

4、CRUD操作-select  使用executeQuery(String sql)方法完成数据查询操作:

Statement stat = conn.createStatement();
String sql = "select * from users";
ResultSet resultSet = stat.executeQuery(sql);
while(resultSet.next()){
  //根据获取列的数据类型,分别调用resultSet的相应方法映射到Java对象中
}

六、代码实现   有很多方法我们需要经常写,那我们就需要封装一些工具类

因为Statement是执行sql语句的,所以需要进行操作,这种我们就不需要封装

要封装的有Connection连接和释放连接。

首先将用户信息写到配置文件中:

driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/jzspace?useUnicode=true&characterEncoding=utf8&useSSL=true&serverTimezone=UTC
username=root
password=space999

下面是封装的代码:

package space.urbeautiful.utils;

import java.io.IOException;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;

public class JdbcUtils {
    private static String driver = null;
    private static String username= null;
    private static String url = null;
    private static String password = null;
    static{
        try{
            //将配置文件放入流中
            InputStream in = JdbcUtils.class.getClassLoader().getResourceAsStream("db.properties");
            //读取配置文件的类
            Properties properties = new Properties();
            //加载流中的配置文件
            properties.load(in);

            //从文件中读取出来内容
            driver = properties.getProperty("driver");
            url = properties.getProperty("url");
            username = properties.getProperty("username");
            password = properties.getProperty("password");

            //加载驱动
            Class.forName(driver);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    //获取连接
    public static Connection getConn() throws SQLException {
        return DriverManager.getConnection(url,username,password);
    }

    //释放资源
    public static void release(Connection conn,Statement stat,ResultSet rs){
        if(rs!=null) {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if(stat!=null) {
            try {
                stat.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if(conn!=null) {
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

下面测试一个insert的JDBC:

package space.urbeautiful.utils;

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

public class TestInsert {

    public static void main(String[] args) {
        Connection conn = null;
        Statement stat = null;
        ResultSet rs = null;
        try {
            conn = JdbcUtils.getConn();
            stat = conn.createStatement();
            String sql = "insert into student(StudentNO,StudentName,sex,birthday,Address,email) " +
                    "values('1004','迈巴赫','男','1996-09-09','浙江省','2770974690@qq.com')";
            int i = stat.executeUpdate(sql);
            if(i>0){
                System.out.println("插入成功 --> insert " + i + "条数据");
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally{
            JdbcUtils.release(conn,stat,rs);
        }
    }
}
/*
下面说一个我在学习JDBC的时候碰到的错误和解决方法
因为我的MySQL版本是8.0,所以我和秦老师下的版本是不一样的
在加载驱动时写的是:class.forName("com.mysql.jdbc.Driver")
报的错误是:Loading class `com.mysql.jdbc.Driver'. This is deprecated. The new driver class is `com.mysql.cj.jdbc.Driver'. The driver is automatically registered via the SPI and manual loading of the driver class is generally unnecessary.
我也没仔细读,大致意思就是"com.mysql.jdbc.Driver"这句话写错了  应该写成`com.mysql.cj.jdbc.Driver'.
改了之后还是出现了一个错误:java.sql.SQLException: The server time zone value '�й���׼ʱ��' is unrecognized or represents more than one time zone. You must configure either the server or JDBC driver (via the 'serverTimezone' configuration property) to use a more specifc time zone value if you want to utilize time zone support.
那么百度:大概就是一个时区的问题,在url后面添加一个serverTimezone=UTC就解决了
*/

/*
如果你用编译器连接数据库,定义了serverTimezone=UTC,那么在你编译器上执行的SQL语句,会先以UTC时区进行存储,发送到MySQL,然后MySQL以本地时区进行转换,就会导致,执行时间比从编译器上的执行时间早8个小时,导致,同一段SQL语句,在mysql直接执行,与编译器执行,结果不同,因为时间相差8个小时
原文链接:https://blog.csdn.net/baidu_38837718/article/details/104981617
*/
上一篇:JDBC


下一篇:JDBC语法总结