Java基础(6)——架构迭代--从面向过程到面向对象,到IO流再到数据库

目录

  • 引出
  • 面向过程到面向对象到数据库【数据存储】
    • 1.面向过程
      • (1)用变量和类型描述
      • (2)用一行数据描述员工
      • (3)用数组存储多个数据
      • (4)用集合存储多个数据
    • 2.面向对象
      • (1)新建一个Emp类型的对象——存多种类型的数据
      • (2)属性私有化,指定修改或读取方式——安全性
      • (3)用构造器对类的属性赋值——从变量到属性
      • 补充:创建对象的三种方式
        • **1)直接创建new**
        • **2)反射**
        • **3)Class.forName(类名)【调用static代码块中的代码】**
  • 从IO对象流到数据库【数据持久化存储】
    • 3.用IO对象流-serializable
    • 4.数据库-SQL
      • (1)创建实体类&对应的表
      • (2)编写dao负责CRUD
      • (3)连接数据库的工具JDBC
      • (4)Junit进行单元测试——测试dao
  • 总结

引出

1.为什么要从面向过程到面向对象;
2.为什么要从IO流要到数据库;


Java基础(6)——架构迭代--从面向过程到面向对象,到IO流再到数据库_第1张图片

面向过程到面向对象到数据库【数据存储】

要点:解决数据的存储和运算

问题:为什么要使用面向对象的方式?

1.面向过程

从面向过程到面向对象,例如描述一个员工:姓名,性别,年龄,工资,职位

(1)用变量和类型描述

String name = "Peter";
String gender = "男";
int age = 23;
double sal = 3455.5;
String job = "经理";
System.out.println(name+gender+age+sal+job);

存在问题:

存储数据量少,写法要求严格;

(2)用一行数据描述员工

String emp1 = "Peter-男-23-3455.5-经理";
String emp2 = "Shirley-女-28-5231.6-老板";
String[] emp1Mess = emp1.split("-");
System.out.println("name:"+emp1Mess[0]
                   +"gender:"+emp1Mess[1]
                   +"age:"+emp1Mess[2]
                   +"sal:"+emp1Mess[3]
                   +"job:"+emp1Mess[4]
                  );

存在问题:

字符串中有各种数据类型,在实际使用时需要进行类型转换;

数据存储无规律

(3)用数组存储多个数据

        String emp1 = "Peter-男-23-3455.5-经理";
        String emp2 = "Shirley-女-28-5231.6-老板";
        String[] emps = new String[]{emp1,emp2};
        for (int i=0;i<emps.length;i++){
            String emp = emps[i];
            String[] empSplit = emp.split("-");
            System.out.println(empSplit[0]);
        }


存在问题:

数组扩容困难,

(4)用集合存储多个数据

        List<String> empList = new ArrayList<>(5);
        empList.add(emp1);
        empList.add(emp2);

        for (int i = 0; i<empList.size(); i++){
            System.out.println(empList.get(i));
        }

        Iterator<String> it = empList.iterator();
        while (it.hasNext()){
            String emp = it.next();
            System.out.println(emp);
        }

存在问题:

采用字符串的形式进行存储,取出过程很难把控数据的类型

2.面向对象

(1)新建一个Emp类型的对象——存多种类型的数据

public class Emp {
    public String name;
    public String gender;
    public int age;
    public double sal;
    public String job;

}
public class EmpTestDemo1 {
    public static void main(String[] args) {
        Emp emp = new Emp(); // emp 没有和任何对象绑定
        emp.name = "Shirley";
        emp.age = 24;

        // 可以随便更改
        emp.name = "Shirley";
        System.out.println(emp.name);
        System.out.println(emp.age);
    }
}

存在问题:

属性值公开,可以被随便更改,不安全;

可以指定修改或取出的方式

(2)属性私有化,指定修改或读取方式——安全性

public class EmpAttr {
    private String name;
    private String gender;
    private int age;
    private double sal;
    private String job;

    public void setName(String name){
        this.name = name; // this 当前对象
        // this.name: 当前对象的属性name
    }

    public String getName(){
        return name;
    }
}
public class EmpAttrTest {
    public static void main(String[] args) {
        EmpAttr emp = new EmpAttr();
        emp.setName("Peter");
        System.out.println(emp.getName());
    }
}

(3)用构造器对类的属性赋值——从变量到属性

Java基础(6)——架构迭代--从面向过程到面向对象,到IO流再到数据库_第2张图片

Java基础(6)——架构迭代--从面向过程到面向对象,到IO流再到数据库_第3张图片

至此,用面向对象的方法,解决了不同数据类型存储不同的属性值,来表示一个事物——比如员工的问题;

结合java提供的集合,就可以实现有序存储多个员工;

存在问题:

数据不能持久化保存;

补充:创建对象的三种方式

1)直接创建new

Car.java 编译成 Car.clase 类加载到 JVM 中,加载时还没有创建对象;

进入JVM中给类Car创建单独的唯一的对象Class 类,该Class对象中存储了Car类的一些必要信息,没有记录相关的值;

以Class对象生产成多个Car对象,通过Class类映射出多个Car对象

2)反射

一个类会产生一个唯一的Class对象,JVM底层原理

Java基础(6)——架构迭代--从面向过程到面向对象,到IO流再到数据库_第4张图片
Java基础(6)——架构迭代--从面向过程到面向对象,到IO流再到数据库_第5张图片

获取Class对象的方式

// 不知道类型用?简写Class c = Car.class;
Class<?> c = Car.class;
// new对象之后再获取Clss
Class<?> C = new Car().getClass();

System.out.println(c);
System.out.println(C);

作用创建对象:

// 1.创建对象
Car x = (Car) c.newInstance();
System.out.println(x);
3)Class.forName(类名)【调用static代码块中的代码】
// 通过包的包名加类名即可拿到
Class<?> clazz = Class.forName("com.tianju.entity.Car");
Car y = (Car) clazz.newInstance();
System.out.println(y);

【调用static代码块中的代码】

Pig类

public class Pig {
    // 静态代码块
    static { // JVM 的 Pig对象的 Class
        System.out.println("静态代码块");
    }

    {
        System.out.println("代码块");
    }
}

测试:

// 静态代码块执行1次,代码块执行2次
new Pig();
new Pig();

// 虚拟机什么时候把Class
Class.forName("com.tianju.entity.Pig");
Class.forName("com.tianju.entity.Pig");

从IO对象流到数据库【数据持久化存储】

Java基础(6)——架构迭代--从面向过程到面向对象,到IO流再到数据库_第6张图片

3.用IO对象流-serializable

public class EmpIO implements Serializable {
    private String name;
    private String gender;
    private int age;
    private double sal;
    private String job;
}
public class EmpIOTest {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        EmpIO emp1 = new EmpIO("Peter", "男", 28, 5252.5, "经理");
        EmpIO emp2 = new EmpIO("Shirley", "女", 26, 6252.5, "老板");
        // 从内存写入硬盘,写
        String filePath = "D:\\Myprogram\\idea-workspace\\recruit_v1.0" +
                "\\recruit_v1.0\\src\\com\\qianbaidu\\recruit\\resource\\empIO.dat";
        ObjectOutputStream out = new ObjectOutputStream(
                new FileOutputStream(filePath)
        );
        List<EmpIO> list = new ArrayList<>();
        list.add(emp1);
        list.add(emp2);
        // 写入文件
        out.writeObject(list);
        out.flush();
        out.close();

        // 从硬盘读入内存,读
        ObjectInputStream in = new ObjectInputStream(
                new FileInputStream(filePath)
        );
        List<EmpIO> listIn = (List<EmpIO>) in.readObject(); // 向下转型
        System.out.println(listIn);


    }
}

存在问题:

数据存储方式不专业,读写困难;

需要有专业的方式进行数据的持久化——数据库;

4.数据库-SQL

(1)创建实体类&对应的表

package com.qianbaidu.recruit.main;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

@Getter @Setter
@AllArgsConstructor
@NoArgsConstructor
public class EmpJDBC {
    private Integer id;
    private String name;
    private String gender;
    private int age;
    private double sal;
    private String job;

    @Override
    public String toString() {
        return "\nEmpJDBC{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", gender='" + gender + '\'' +
                ", age=" + age +
                ", sal=" + sal +
                ", job='" + job + '\'' +
                '}';
    }
}

Java基础(6)——架构迭代--从面向过程到面向对象,到IO流再到数据库_第7张图片

(2)编写dao负责CRUD

package com.qianbaidu.recruit.main;

import com.qianbaidu.recruit.util.DbUtilJDBC;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

public class EmpJDBCDao {
    private DbUtilJDBC db;

    public EmpJDBCDao() {
        db = DbUtilJDBC.INSTANCE;
    }

    // 私有的拿单个的方法
    private EmpJDBC getEmp(ResultSet rs){
        EmpJDBC emp = null;
        try {
            if (rs.next()){
                emp = new EmpJDBC(rs.getInt("emp_id"),
                        rs.getString("emp_name"),
                        rs.getString("emp_gender"),
                        rs.getInt("emp_age"),
                        rs.getDouble("emp_sal"),
                        rs.getString("emp_job"));
            }
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
        db.close();
        return emp;
    }

    // 私有的拿多个的方法
    private List<EmpJDBC> getEmps(ResultSet rs){
        List<EmpJDBC> list = new ArrayList<>(5);
        try {
            while (rs.next()){
                EmpJDBC emp = new EmpJDBC(rs.getInt("emp_id"),
                        rs.getString("emp_name"),
                        rs.getString("emp_gender"),
                        rs.getInt("emp_age"),
                        rs.getDouble("emp_sal"),
                        rs.getString("emp_job"));
                list.add(emp);
            }
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
        return list;
    }


    /**
     * 保存到数据库
     * @param emp 要保存的实体类
     */
    public void save(EmpJDBC emp){
        db.connect();
        String sql = "INSERT INTO emp_tab(emp_id, emp_name, emp_gender, emp_age, emp_sal, emp_job) " +
                "VALUES(?, ?, ?, ?, ?, ?) \n";
        db.prepareStatement(sql,
                emp.getId(),
                emp.getName(),
                emp.getGender(),
                emp.getAge(),
                emp.getSal(),
                emp.getJob());
        db.executeUpdate();
        db.close();
    }

    /**
     * 根据id找数据库中的实体类的数据
     * @param id 唯一id
     * @return 实体类
     */
    public EmpJDBC findById(Integer id){
        db.connect();
        String sql = "SELECT * FROM emp_tab WHERE emp_id = ?";
        db.prepareStatement(sql,id);
        ResultSet rs = db.executeQuery();
        EmpJDBC emp = getEmp(rs);
        db.close();
        return emp;
    }

    /**
     * 找到数据库中所有的数据
     * @return emp的集合List
     */
    public List<EmpJDBC> findAll(){
        db.connect();
        db.prepareStatement("SELECT * FROM emp_tab" );
        ResultSet rs = db.executeQuery();
        List<EmpJDBC> list = getEmps(rs);
        db.close();
        return list;
    }

}

私有的获取单条数据和多条数据的方法;

(3)连接数据库的工具JDBC

package com.qianbaidu.recruit.util;

import java.sql.*;

public enum DbUtilJDBC {
    INSTANCE;
    // 加载驱动,建立连接,准备sql语句,增删改,查询返回,关闭
    private Connection conn;
    private PreparedStatement pst;
    private ResultSet rs;

    private DbUtilJDBC(){
        register();
    }

    /**
     * 第一步:加载驱动
     */
    private void register(){
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 第二步:建立数据库的连接
     * @param ip 数据库的地址:192.168.0.104:3310/emp_db
     * @param username 用户名
     * @param password 密码
     */
    public void connect(){
        // ip: 192.168.0.104:3310/emp_db
        String ipp = "192.168.111.128:3306/emp_db";
        String url = "jdbc:mysql://"+ipp+"?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true";
        try {
            // "192.168.111.128:3306/rec_db", "root", "123"
            // conn = DriverManager.getConnection(url,username,password);
            conn = DriverManager.getConnection(url, "root", "123");
//            System.out.println("成功连接到数据库:"+ip);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 第三步:准备sql语句
     * @param sql sql语句
     * @param values 填充语句中的?位置
     */
    public void prepareStatement(String sql, Object... values){
        try {
            pst = conn.prepareStatement(sql);
            for (int i=0;i<values.length;i++){
                pst.setObject(i+1, values[i]);
            }
//            System.out.println("准备好sql语句");
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

    // 第四步:进行增删改,或者查询+返回结果

    /**
     * 进行数据库的增删改操作
     */
    public void executeUpdate(){
        try {
            pst.executeUpdate();
//            System.out.println("进行数据库的增删改操作");
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 进行数据库的查询操作
     * @return 返回查询结果
     */
    public ResultSet executeQuery(){
        try {
            rs = pst.executeQuery();
            return rs;
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 关闭数据库连接
     */
    public void close(){
        try {
            if(rs!=null){
                rs.close();
            }
            if (pst!=null){
                pst.close();
            }
            if (conn!=null){
                conn.close();
            }
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }
}

(4)Junit进行单元测试——测试dao

package com.qianbaidu.recruit.main;

import org.junit.Test;

import static org.junit.Assert.*;

public class EmpJDBCDaoTest {
    private EmpJDBCDao dao = new EmpJDBCDao();

    @Test
    public void save() {
        dao.save(new EmpJDBC(null, "Peter", "男", 28, 5252.5, "经理"));
        dao.save(new EmpJDBC(null, "Shirley", "女", 26, 6252.5, "老板"));
        System.out.println(dao.findById(1));
        System.out.println(dao.findAll());

    }
}

总结

1.计算机解决数据的存储和计算的问题;
2.面向对象的相比面向过程的优势;
3.用数据库相比IO流的优势;

你可能感兴趣的:(Java,java,数据库,学习)