JAVA八股文基础知识(四)(详细版JDBC连接数据库以及线程)

JAVA基础知识

1.I/O

一.File类

(1) java.io.File类:文件和文件目录路径的抽象表示形式,与平台无关

(2)File类中涉及到关于文件或文件目录的创建、删除、重命名、修改时间、文件大小等方法,并未涉及到写入或读取文件内容的操作。如果需要读取或写入文件内容,必须使用IO流来完成。

(1)File类的常用构造方法:
  1. public File(String pathname)    以pathname为路径创建File对象,可以是绝对路径或者相对路径,如果pathname是相对路径,则默认的当前路径在系统属性user.dir中存储。
  2. public File(String parent,String child)    以parent为父路径,child为子路径创建File对象。
  3. public File(File parent,String child)    根据一个父File对象和子文件路径创建File对象
public class FileDemo {

    public static void main(String[] args) {
        // 方式一:根据文件路径名创建 File 实例
        File file1 = new File("test.txt");

        // 方式二
        File file2 = new File("parent", "child");
        
        // 方式三
        File parent = new File("parent");
        File file3 = new File(parent, "child");
    }
}
(2)File类的常用方法:
  • public String getAbsolutePath()    获取绝对路径
  • public String getPath()    获取路径
  • public String getName()    获取名称
  • public String getParent()    获取上层文件目录路径。若无,返回null
  • public long length()    获取文件长度(即:字节数)。不能获取目录的长度。
  • public long lastModified()    获取最后一次的修改时间,毫秒值
  • public String[] list()    获取指定目录下的所有文件或者文件目录的字符串数组
  • public File[] listFiles()    获取指定目录下的所有文件或者文件目录的File对象数组
  • public boolean renameTo(File dest)  把文件重命名为指定的文件路径
  • public boolean isDirectory()    判断是否是文件目录
  • public boolean isFile()    判断是否是文件
  • public boolean exists()    判断是否存在
  • public boolean canRead()    判断是否可读
  • public boolean canWrite()    判断是否可写
  • public boolean isHidden()    判断是否隐藏
  • public boolean createNewFile()    创建文件。若文件存在,则不创建,返回false
  • public boolean mkdir()    创建文件目录。如果此文件目录存在,就不创建了。如果此文件目录的上层目录不存在,也不创建。
  • public boolean mkdirs()    创建文件目录。如果上层文件目录不存在,一并创建
  • public boolean delete()     删除文件或者文件夹
 (3)详细的创建File
  1. boolean createNewFile() :当且仅当不存在此文件时,就会创建一个新的空文件。
  2. boolean mkdir() :当且仅当不存在此文件夹时,就会创建此文件夹(仅限以及目录)
  3. boolean mkdirs() :创建文件夹(可多级目录)
  4. import java.io.File;
    public class Main{
        public static void main(String[] args) throws Exception{
            // 方式一
            File file1 = new File("test.txt");
            boolean b1 = file1.exists();
            System.out.println(b1);
    
            // 方式二
            File file2 = new File("parent", "child");
            boolean b2 = file2.exists();
            System.out.println(b2);
    
            // 方式三
            File parent = new File("parent");
            File file3 = new File(parent, "child");
            boolean b3 = file3.exists();
            System.out.println(b3);
    //因为有了createNewFile()
           boolean b = file1.createNewFile();
           System.out.println(b);
        }
    }
    

      原本test.txt不存在,我们把它创建出来了

第一次调用结果,返回“true”。而且,在项目路径下也创建了一个文件“test.txt”。结果:创建文件成功。

那么,当这个文件已存在时,再次调用那方法会有什么结果呢?

 

 很显然,返回“false”,创建失败。因为此文件已经存在。

(4)详细的删除文件
  • boolean delete() :删除存在的文件或文件夹。

 

 如果文件/文件夹存在,则删除成功;否则,删除失败,并不会抛出异常哈~

(5)遍历目录下的文件

File类中提供了list()方法,可以获取目录下所有文件和目录的名称。

对目录下的文件遍历可分为以下3种方式:

  • 遍历指定目录下的所有文件
  • 遍历指定目录下指定扩展名的文件
  • 遍历包括子目录中的文件在内的所有文件

 1.遍历指定目录下的所有文件
    首先要去D盘里面创建相关文件

import java.io.File;
public class Main{
    public static void main(String[] args) throws Exception{
        // 方式一
        File file = new File("D:\\javase03");
        fileDir(file);
    }

    private static void fileDir(File dir) {
        File[] files=dir.listFiles();
        for (File file:files){
            if (file.isDirectory()){
                fileDir(file);
            }
            System.out.println(file.getAbsolutePath());
        }
    }
}

 2.遍历指定目录下指定扩展名的文件

File类提供了一个重载的list()方法,该方法接收了一个FilenameFilter类型的参数。FilenameFilter是一个接口,被称作文件过滤器,其中定义了抽象方法accept()用于依次对指定File的所有子目录或文件进行迭代。

import java.io.File;
import java.io.FilenameFilter;
public class Main{
    public static void main(String[] args) throws Exception{
        //创建File对象
        File file = new File("D:\\javase03");
        //创建文件过滤器对象
        FilenameFilter filter=new FilenameFilter() {
            @Override
            //实现accept()方法
            public boolean accept(File dir, String name) {
                File currFile=new File(dir,name);
                //如果文件名以.java结尾,则返回true,否则返回false
                if(currFile.isFile()&&name.endsWith(".java")) {
                    return true;
                }else{
                    return false;
                }
            }
        };
        if(file.exists()){//判断File对象对应的目录是否存在
            String[] lists=file.list(filter);//获得过滤后的所有文件名数组
            for(String name:lists){
                System.out.println(name);
            }
        }
    }
}

3.遍历包括子目录中的文件在内的所有文件

使用File类提供的另一个方法————listFiles()

import java.io.File;
//import java.io.FilenameFilter;
public class Main {
    public static void main(String[] args) throws Exception {
        //创建File对象
        File file = new File("D:\\javase03");
        fileDir(file);//调用fileDir()方法
    }
    private static void fileDir(File dir) {
        File[] files=dir.listFiles();//获得表示目录下所有文件的数组
        for(File file:files){//遍历所有子目录和文件
            if(file.isDirectory()){
                fileDir(file);//如果是目录,则递归调用fileDir()
            }
            System.out.println(file.getAbsolutePath());//输出文件的绝对路径
        }
    }

}
(6)删除文件及目录

调用File类的delete()方法。File类的delete()方法只能删除一个指定的文件;加入File对象代表一个目录,并且这个目录下包含子目录或文件,则File类的delete()方法不允许直接删除这个目录。在这种情况下,需要通过递归的方式将整个目录以及目录下的文件全部删除。

import java.io.File;
//import java.io.FilenameFilter;
public class Main {
    public static void main(String[] args) throws Exception {
        //创建File对象
        File file = new File("D:\\javase03");
        deleteDir(file);//调用deleteDir()方法
        System.out.println("删除成功!");
    }
    private static void deleteDir(File dir) {
        if(dir.exists()){//判断传入的File对象是否存在
            File[] files=dir.listFiles();//得到File数组
            for(File file:files){//遍历所有子目录和文件
                if(file.isDirectory()){
                    deleteDir(file);//如果是目录,则递归调用deleteDir()方法
                }else{
                    //如果是文件,则直接删除
                    file.delete();
                }
            }
            //删除一个目录里的所有文件后,就删除这个目录
            dir.delete();
        }
    }

}
//运行后:就会发现D盘里没有javase03这个文件了

二.字节流

JDK提供了两个抽象类————InputStream和OutputStream,它们是字节流的顶级父类,所有的字节输入流都继承InputStream,所有的字节输出流都继承OutputStream。

(1)字节流读文件

1)导入相关的类

import java.io.IOException;

import java.io.InputStream;

import java.io.FileInputStream;

2)构造一个文件输入流对象

InputStream fileObject = new FileInputStream("text.txt");//此时的文件输入流对象fileObject就和源数据源(text.txt)关联起来。

3)利用文件输入流类的方法读取文本文件中的数据

fileObject.available();//可读取的字节

fileObject.read();//读取文件的数据

4)关闭文件输入流对象

fileObject.close();

 代码典例如下:

import java.io.*;
public  class  Main{
    public  static  void  main(String[] args) throws  Exception{
        //创建一个文件字节输入流,并指定源文件名称
        FileInputStream in=new FileInputStream("test.txt");
        int b=0;//定义int类型的变量b,用于记住每次读取的一字节
        while(true){
            b=in.read();//变量b记住读取的一字节
            if(b==-1){//如果读取的字节为-1,则跳出while循环
                break;
            }
            System.out.println(b);//否则将b输出
        }
        in.close();
    }

}

 如出现无法查找到文件,那就在项目下加入该文件

(2)字节流写文件

1)导入相关的类

import java.io.IOException;

import java.io.InputStream;

import java.io.FileInputStream;

2)构造一个文件输入流对象

InputStream fileObject = new FileInputStream("text.txt");//此时的文件输入流对象fileObject就和源数据源(text.txt)关联起来。

3)利用文件输入流类的方法读取文本文件中的数据

fileObject.available();//可读取的字节

fileObject.read();//读取文件的数据

4)关闭文件输入流对象

fileObject.close();

import java.io.*;
public  class  Main{
    public  static  void  main(String[] args) throws  Exception{
      OutputStream  out=new FileOutputStream("example.txt");
      String str="教育";
      byte[] b=str.getBytes();
      for(int i=0;i<b.length;i++){
          out.write(b[i]);
      }
      out.close();
    }
}

 使用FileOutputStream写数据时,程序自动创建了文件example.txt,并将数据写入example.txt文件。需要注意的是,如果通过FileOutputStream向一个已经存在的文件中写入数据,那么该文件中的数据会被覆盖。

若希望在已存在的文件内容之后追加新内容,则可使用FileOutputStream的构造函数FileOutputStream(String fileName,boolean append)创建文件输出流对象,并将append参数的值设置为true.

import java.io.*;
public  class  Main{
    public  static  void  main(String[] args) throws  Exception{
      OutputStream  out=new FileOutputStream("example.txt",true);
      String str="nihao";
      byte[] b=str.getBytes();
      for(int i=0;i<b.length;i++){
          out.write(b[i]);
      }
      out.close();
    }
}

 (3)文件的复制

文件的复制需要通过输入流读取一个文件中的数据,再通过输出流将数据写入另一个文件。

import java.io.*;
public  class  Main{
    public  static  void  main(String[] args) throws  Exception{
        InputStream in=new FileInputStream("source/.a.png");
      OutputStream  out=new FileOutputStream("target/b.png");
      byte[] buff=new byte[1024];
      int len;
      long begintime=System.currentTimeMillis();
      while((len=in.read(buff))!=-1){
          out.write(buff,0,len);
      }
      long endtime=System.currentTimeMillis();
      System.out.println("复制所用时间"+(endtime-begintime));
      in.close();
      out.close();
    }
}

三.字符流

字符流也有两个抽象的顶级父类,分别是Reader类和Writer类

Reader类的常用方法:

public int read()   从输入流中读一个字符
public int read(char[ ]cbuf)   从输入流中读最多cbuf. length个字符,存入字符数组cbuf中
public int read(char[ ]buffer,int off,int len)   从输入流中读最多len个字符,存入字符数组cbuffer中从off开始的位置 
public long skip(long n)   从输入流中最多向后跳n个字符
public boolean ready()   判断流是否做好读的准备
public void mark(int read  AheadLimit )   标记输入流的当前位置
public boolean  markSupported ()   测试输入流是否支持mark
public void reset()   重定位输入流
public void close()   关闭输入流

Writer类的常用方法:

public void write(int c)   将单一字符c输出到流中
public void write(String str)   将字符串str输出到流中
public void write(char[]cbuf)   将字符数组cbuf输出到流
public void write(char[]cbuf,int off,int len)   将字符数组按指定的格式输出(off表示索引,len表示写入的字符数)到流中
public void flush()   将缓冲区中的数据写到文件中
public void close()   关闭输出流

(1)字符流读文件

port java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
 
public class demo {
    public static void main(String[] args) throws IOException {
//定义文件路径
        String str1="C:\\Users\\Administrator\\Desktop\\id.txt";
//常见字符输入流资源
        FileReader fr1 = new FileReader(str1);
        int ten=0;
        while ((ten=fr1.read())!=-1){
//读取文件并打印
            System.out.print((char)ten);
        }
//释放系统资源
        fr1.close();
    }
}

(2)字符流写文件

        Writer writer=new FileWriter("lib/1.txt");
        //一次写一个字符
        writer.write('好');
        //字符数组
        char chs[]={'黑','马','程','序','员'};
        writer.write(chs,2,3);
        //字符串
        writer.write("好好学习");
        writer.close();

(3)转换流

  • Java API提供了两个转换流:
    InputStreamReader:将InputStream转换为Reader
    OutputStreamWiter:将Writer转换为OutputStream
import java.io.*;
public  class  Main{
    public  static  void  main(String[] args) throws  Exception{
        //创建字节输入流in,并指定源文件为src.txt
        FileInputStream in=new FileInputStream("source。txt");
        //将字节输入流in转换成字符输入流isr
        InputStreamReader isr= new InputStreamReader(in);
        //创建字节输出流out,并指定目标文件的是des.txt
        FileOutputStream out =new FileOutputStream("des.txt");
        //将字节输出流out转换成字符输出流osw
      OutputStreamWriter  osw=new OutputStreamWriter(out);
      int ch;
      while((ch=isr.read())!=-1){
          osw.write(ch);//将字符数据写入des.txt文件中
      }
      isr.close();//关闭字符输入流,释放资源
      osw.close();//关闭字符输出流,释放资源
    }
}

2.JDBC

1.jdbc的概念
  • JDBC(Java DataBase Connectivity:java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系型数据库提供统一访问,它是由一组用Java语言编写的类和接口组成的。
  • JDBC的作用:可以通过java代码操作数据库

2.JDBC的常用API

  • Driver接口:Driver接口是所有JDBC驱动程序必须实现的接口,该接口专门提供给数据库厂商使用。需要注意的是,在编写Java应用程序时,必须把使用的数据库驱动程序(这里指MySQL驱动程序的JAR包)或类库加载到项目的classpath中。
  • DriverManager类:用于加载JDBC驱动程序并且创建Java应用程序与数据库的连接。
  • Connection接口
  • Statement接口
  • PreparedStatement接口
  • ResultSet接口

3.我们直接用代码实现吧,这里我MySQL用的是HeisiSQL

首先关于HeisiSQL的详细使用我们截图体现一下:

首先新建一个连接,我这里已经写好了,我使用的是localhost,用户名:root

进去之后就是新建数据库了

数据库建完就是建表

建完表以后就是建立表的属性信息,也可以查询里面用代码写 

建立表里面的相关属性信息代码是这样子的


CREATE DATABASE test;

USE test;
CREATE TABLE teacher
(
    number INT,
    NAME CHAR(50),
    age int
);

 然后建立完相关信息后,我再用的查询插入信息,查询结果具体如下:

 接下来就是撰写JDBC的代码与MySQL里面的数据连通:

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class ConnMySQL {
    public static void main(String args[]) throws Exception
    {
        Statement stmt=null;
        ResultSet rs=null;
        Connection conn=null;
        try{
            //1.注册数据库的驱动程序
            Class.forName("com.mysql.cj.jdbc.Driver");//这是一个MySQL与JDBC的驱动程序类名,是固定的,初学者会认为cj是命名,从而修改,但这是固定的
            //通过DriverManager获取数据库连接
            String url="jdbc:mysql://localhost:3306/test"+"?serverTimezone=GMT%2B8&useSSL=false";
            String username="root";//数据库用户名
            String password="123456";//数据库密码
            conn=DriverManager.getConnection(url,username,password);
            //通过Connection对象获取Statement对象
            stmt=conn.createStatement();
            //使用Statement执行SQL语句
            String sql="select * from teacher";
            rs=stmt.executeQuery(sql);
            //操作结果集
            System.out.println("number name  age");
            while(rs.next()){
                String number=rs.getString("number");//通过列名获取指定列的值
                String name=rs.getString("name");
                int age=rs.getInt("age");
                System.out.println(number+"  "+name+"  "+age);
            }

        }catch (Exception e){
            e.printStackTrace();
        }finally {
            //回收数据库资源
            if (rs!=null){
                try{
                    rs.close();
                }catch (SQLException e){
                    e.printStackTrace();
                }
                rs=null;
            }
            if(stmt!=null){
                try {
                    stmt.close();
                }catch (SQLException e){
                    e.printStackTrace();
                }
                stmt=null;
            }
            if (conn!=null){
                try {
                    conn.close();
                }catch (SQLException e){
                    e.printStackTrace();
                }
                conn=null;
            }
        }
    }
}

之后运行结果如下:

3.多线程 

多线程就是指一个应用程序中有多种并发执行的线索,每条线索都被称作一个线程,它们会交替执行,彼此可以通信。

一.进程与线程

进程是系统进行资源分配和调度的基本单位,是操作系统结构的基础。程序一旦运行就是进程,进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响

线程是进程的一个执行流,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位


总结:每个运行的程序都是一个进程,在一个进程中还可以由多个执行单元同时执行,这些执行单元可以看作程序执行的线程。每一个进程中都至少存在一个线程。

二.多线程的创建方式

(1)继承java.lang包中的Thread类,重写Thread类的run()方法,在run()方法中实现多线程代码

/*
1.创建一个继承于Thread类的子类
2.重写Thread类的run()
3.创建Thread类的子类的对象
4.通过此对象调用start()
注意:①调动当前线程,②调用当前线程run()
 */
//具体操作如下:
    //1.创建一个继承于Thread类的子类
class MyThread extends Thread{
    //2.重写Thread类的run()
    @Override
    public void run() {
        for (int i=0;i<100;i++){
            if(i%2==0){
                System.out.println(i);
            }
        }
    }
}
public class Exaample {
    public static void main(String[] args){
        //3.创建Thread类的子类的对象
        MyThread t1=new MyThread();
        //通过此对象调用start()
        t1.start();
    }


}

(2)实现java.lang.Runnable接口,在run()方法中实现多线程代码

/*
1.创建一个实现Runnable接口的类
2.实现Runnable接口中的run()---》将此线程要执行的操作,声明在此方法体中
3.创建当前实现类的对象
4.将此对象作为参数传递到Thread类的构造器中,创建Thread类的实例
5.Thread类的实例调用start():
注意:①启动线程,②调用当前线程run()
 */
//具体操作如下:
    //1.创建一个实现Runnable接口的类
class MyThread implements Runnable{
    //2.实现Runnable接口中的run()---》将此线程要执行的操作,声明在此方法体中
    public void run() {
        for (int i=0;i<100;i++){
            if(i%2==0){
                System.out.println(i);
            }
        }
    }
}
public class Exaample {
    public static void main(String[] args){
        //3.创建当前实现类的对象
        MyThread t1=new MyThread();
        //4.将此对象作为参数传递到Thread类的构造器中,创建Thread类的实例
        Thread thread=new Thread(t1);
        //Thread类的实例调用start()
        thread.start();
    }


}

(3)实现java.util.concurrent.Callable接口,重写call()方法,并使用Future接口获取call()方法返回的结果。

import  java.util.concurrent.*;
//定义一个实现Callable接口的实现类
class MyThread implements Callable<Object>{
    //重写Callable接口的call()方法
    public Object call() throws Exception {
        int i=0;
        while(i++<5){
            System.out.println(Thread.currentThread().getName()+"的call()方法在运行");
        }
        return i;
    }
}
public class Exaample {
    public static void main(String[] args) throws InterruptedException, ExecutionException {
    //创建Callable接口的实例对象
    MyThread myThread = new MyThread();
    //使用FutureTask封装Mythread类
    FutureTask<Object> ft1 = new FutureTask<Object>(myThread);
    //使用Thread(Runnable target,String name)构造方法创建线程对象
    Thread thread1 = new Thread(ft1, "thread");
    //调用线程对象的start()方法启动线程
    thread1.start();
    //通过FutureTask对象的方法管理返回值
        System.out.println(Thread.currentThread().getName()+"的返回结果:"+ft1.get());
        int a=0;
        while(a++<5){
            System.out.println("main()的方法 在执行");
        }
    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值