关于java:JDBCMySQL实战

47次阅读

共计 10901 个字符,预计需要花费 28 分钟才能阅读完成。

前言

hello 我是 bigsai,明天咱们进行 JDBC+MySQL 实战,非常适合初入门的小伙伴关上新的世界。实现一个增删改查 (curd) 的例子。先点赞再观看、帅哥靓女养成好习惯!

在这个案例进行之前,你要确保本人电脑上领有 MySQL 和 IDEA 编译器,另外还要装置 MySQL 数据库连贯管理工具 Navicat。方能进行以下的操作。

如果以前没见过或者应用过也不要紧,本课程提供傻瓜式教学你只需跟着我的要求来包胜利包会。

通过本翩你能够把握以下内容:

  • MySQL 数据库的创立
  • JDBC+MySQL 我的项目的创立
  • JDBC 胜利对 MySQL 增删改查

案例剖析

本次案例到底是个什么后果呢?本案例实现一个学生信息的治理,即学生个人信息的增删改查。

外围思路拆解

咱们该如何设计这个我的项目呢?

别急别急,听我缓缓说道。对于本案例的实战,旨在实现用 Java 语言 (JDBC) 操作 MySQL,外围的主轴是 MySQL 的数据,所以咱们从 MySQL 为起始点动手,整个案例实现的流程大抵能够分为:

  • 剖析设计需要、创立 MySQL 数据库和表
  • 创立 Java 我的项目,增加 JDBC 以及 Junit 单元测试的依赖
  • 编写我的项目代码,实现 JDBC 增删改查案例
  • 单元测试

而对于 JDBC 编程来说,它须要与 MySQL 进行连贯交互,它也有肯定流程程序须要恪守,通常为以下 6 个流程:

  • 1:注册驱动 (仅仅做一次)
  • 2:建设连贯(Connection)
  • 3:创立运行 SQL 的语句(Statement)
  • 4:运行语句
  • 5:解决运行后果(ResultSet)
  • 6:开释资源

案例波及知识点

本案例次要波及的知识点为 MySQL 和 JDBC。而这两个知识点是 Java Web 开发十分罕用的技术,上面我就给你介绍一番。

MySQL
MySQL 是以后十分风行的数据库之一,且收费开源,数据库是用来贮存数据的,就数据格式而言,有关系型数据和非关系型数据,MySQL 是一种关系型数据库。就 web 方面,MySQL 是最好的 RDBMS(关系数据库管理系统:Relational Database Management System)之一:MySQL 的 sql 语句是罕用关系数据库的规范之一,具备速度快、体积小、成本低等劣势,是中小企业以及学习应用的最好形式之一。

在 Java 中利用 JDBC 能够疾速在利用中应用 MySQL。除了 DDL(数据库模式定义语言:Data Definition Language)和 DML(数据操纵语言:Data Manipulation Language)等传统操作外,你能够通过 JDBC 应用 MySQL 的大部分性能。并且 MySQL 提供索引优化查问速度,利用 B + 树或哈希形式的索引满足不同场景查问性能的要求。还提供视图、函数、束缚、触发器等性能可能使得数据库满足更多的场景应用。而 MySQL 提供的事务、回滚等机制可能使得数据在安全性一致性方面有更大的保障。

JDBC

Java 数据库连贯,(Java Database Connectivity,简称 JDBC)是 Java 语言中用来标准客户端程序如何来拜访数据库的利用程序接口 (位于 jdk 的 java.sql 中)。咱们通常说的 JDBC 是面向关系型数据库的,提供了诸如查问、更新、删除、减少数据库中数据的办法。在应用时候须要导入具体的 jar 包,不同数据库须要导入的 jar 包不同。

而 JDBC 次要有以下 API:

  • DriverManager:负责加载不同驱动程序(Driver),并依据不同的申请,向调用者返回相应的数据库连贯(Connection)。
  • Driver:驱动程序,会将本身加载到 DriverManager 中去,并解决相应的申请并返回相应的数据库连贯(Connection)。
  • Connection:数据库连贯,负责与数据库进行通信,SQL 执行以及事务处理都是在某个特定 Connection 环境中进行的。能够产生用以执行 SQL 的 Statement、PreparedStatement 等。
  • Statement:用以执行 SQL 查问和更新(针对动态 SQL 语句和单次执行)。
  • PreparedStatement:用以执行蕴含动静参数的 SQL 查问和更新(在服务器端编译,容许反复执行以提高效率)继承 Statement,本案例应用 PreparedStatement。
  • CallableStatement:用以调用数据库中的存储过程。
  • SQLException:代表在数据库连贯的建设和敞开和 SQL 语句的执行过程中产生了例外情况(即谬误)。

我想当初你对 MySQL 和 JDBC 有了更分明的意识吧,MySQL 就是一个数据库供咱们应用,而 JDBC 就是 Java 应用 MySQL 的一个工具和桥梁,联合下面常识,上面咱们就开始实战吧!

第一关 创立数据库和我的项目

在实战之前,须要把数据库和我的项目创立好能力进行 JDBC 的增删改查。

创立数据库

咱们应用 Navicat 创立数据库,你可能好奇 Navicat 到底是个什么样的工具,有何作用?

其实 Navicat 是一个数据库管理工具,它并不能间接批改 MySQL 的数据和构造,而是通过你的可视化界面操作它帮你执行 sql 代码,因为思考到如果间接让你用 sql 操作数据库,可能不太直观并且上手难度挺大的,通过 Navicat 治理数据库能够清晰看到数据库构造、数据、设置状况也可能很容易的进行更改,大大晋升开发效率肯定水平缩小谬误。能够参考下图:

关上 Navicat 连贯数据库,连贯胜利的数据库右击创立数据库,数据库名称为:boxuegu,字符集和排序规定应用其默认即可。


而后关上 boxuegu 数据库,在表的栏目右击新建表,设置 id,name,age,high 四个字段,其中 id 设为主键且自增。

保留时候把这张表命名为 student,代指学生表。这样,学生表就增加实现了。其中 id 为自增主键,插入的时候不插入 id 会主动递增插入,name 就是学生的姓名,age 示意学生年龄。high 示意学生身高,咱们用这几个字段示意一个学生信息状况。

当然,如果你不喜爱应用数据库管理工具进行这样操作,更喜爱控制台或者命令行创立数据库以及表格,当然也是能够的:

SET FOREIGN_KEY_CHECKS=0;

-- ----------------------------
-- Table structure for students
-- ----------------------------
DROP TABLE IF EXISTS `student`;
CREATE TABLE `students` (`id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) NOT NULL,
  `age` int(11) NOT NULL,
  `high` int(11) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

这样咱们数据库以及表就创立实现啦,咱们上面就要用 JDBC 对 MySQL 的这张表进行增删改查实战。让你入手操作数据。

创立我的项目

咱们创立 java 我的项目要引入 JDBC 的依赖,这里我为了更简略不让你去本人找 JDBC 的 jar 包,应用 Maven 的形式引入 jar 包,所以咱们应用 IDEA 创立 Maven 我的项目。

首先关上 IDEA, 创立 Maven 我的项目,点击 next。

接着填写 GroupId 和 ArtifactId 能够自行填写,本案例填写 com 和 JDBCTest,点击 next。

紧接着抉择磁盘中一个文件夹作为我的项目的门路,点击 finish 我的项目即创立胜利。接着咱们须要增加 MySQL 的 JDBC 依赖以及 Junit 单元测试依赖,在我的项目 pom.xml 文件中增加以下内容:

<dependencies>
   <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
   <dependency>
       <groupId>mysql</groupId>
       <artifactId>mysql-connector-java</artifactId>
       <version>5.1.49</version>
   </dependency>
   <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
</dependencies>

而后我的项目就胜利创立啦,紧接着创立以下类:

  • main 的 java 目录下:sqlmanage 类,用于编写 sql 相干语句
  • main 的 java 目录下:student 类,示意 student 实体与 MySQL 的 student
  • test 的 java 目录下:test 类,用于编写单元测试。

有了 JDBC 的环境只需编写正确的代码即可运行! 对于我的项目最终的目录是这样的:

第二关 JDBC 插入和查问

咱们下面有讲过进行 JDBC 操作的 6 个步骤,但有些步骤不须要反复进行,比方加载驱动、建设连贯、敞开等能够复用。此外,咱们在我的项目中将 MySQL 中的数据和 Java 中的对象进行映射(即 MySQL 表中每一条记录能够生成一个 Java 对象),我的项目中函数的设计基于 Java 对象而非 MySQL 中数据字段,升高我的项目中各模块的耦合性。

预备工作

首先在 student 类中编写以下内容,该类与 MySQL 数据库的 student 表对应。<!– 这段代码能够加些正文吗?–>

public class student {
    private int id;// 与 student 表得 id 对应
    private  String name;// 与 student 表得 name 对应
    private int age;// 年龄与 student 表得 age 对应
    private  int high;// 身高与 student 表 high 对应
    // 带 id 构造方法(查问时应用)
    public student(int id, String name, int age, int high) {
        this.id = id;
        this.name = name;
        this.age = age;
        this.high = high;
    }
    // 不带 id 得构造方法(插入时候应用)
    public student(String name, int age, int high) {
        this.name = name;
        this.age = age;
        this.high = high;
    }
    //toString()办法,控制台打印测试应用 
      @Override
    public String toString() {
        return "student{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                ", high=" + high +
                "}\n";
    }
    //get set 办法,设置值,取值应用
    public int getId() {return id;}
    public void setId(int id) {this.id = id;}
    public String getName() {return name;}
    public void setName(String name) {this.name = name;}
    public int getAge() {return age;}
    public void setAge(int age) {this.age = age;}
    public int getHigh() {return high;}
    public void setHigh(int high) {this.high = high;}
}

紧接着解决 sqlmanage 类,咱们将 JDBC 的一些操作封装到这外面。在初始化函数中进行注册驱动、建设连贯的操作。在 sqlmanage 中编写以下内容:<!– 既然讲到 Connection,第一行能够加个正文 –>

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

public class sqlmanage {
    private Connection con=null;// 数据库连贯,从 DriverManager 的办法取得,用以产生执行 sql 的 PreparedStatement
    public sqlmanage() throws SQLException, ClassNotFoundException {
        //step1 加载数据库驱动
        Class.forName("com.mysql.jdbc.Driver");
        System.out.println("数据库驱动加载胜利");
        //step2 连贯数据库
        this.con =  DriverManager.getConnection("jdbc:mysql://localhost:3306/boxuegu?useSSL=false","root","bigsai66");
        System.out.println("数据库连贯胜利");
    }
    public void close() throws SQLException {this.con.close();;
    }
}

其中通过 Connection 建设连贯,Connection 是一个接口类。其性能是与数据库进行连贯(会话)。建设 Connection 接口类对象:
Connection conn =DriverManager.getConnection(url, user, password);
其中 url 的格局要求为:

  • jdbc:mysql://<host>:<port>/<database_name>?property1=value1&property2=value2…
  • host 为主机地址或者域名,本地能够用 localhost 或 127.0.0.1.
  • database_name 为 MySQL 中创立数据库名,本案例中数据库名为 boxuegu。
  • property 用来配置一些例如编码、时区等属性。

其中 user 为 MySQL 登录用户名,password 为 MySQL 登录明码。

单个插入

MySQL 插入的 sql 语句很简略:

insert into  表名
(字段 1, 字段 2,... 字段 n)
value
(值 1, 值 2,... 值 n);

咱们 JDBC 中进行插入操作应用的 sql 满足上述标准,在 sqlmanage 中编写 insertStudent(student student) 函数用来插入单个学生记录,具体函数如下:

 public  void insertStudent(student student) throws SQLException {
        // 创立 sql 语句
        String sql="insert into student(name,age,high)value(?,?,?)";
        //PreparedStatement 可能对 SQL 语句进行预编译,这样避免了   SQL 注入 进步了安全性。PreparedStatement ps = con.prepareStatement(sql);
        ps.setString(1,student.getName());
        ps.setInt(2,student.getAge());
        ps.setInt(3,student.getHigh());
        // 执行 sql 因为这里插入操作就不对结解决
        ps.executeUpdate();
        ps.close();}

在 test 类中的编写 insertTest() 函数,用来测试插入三条学生的记录:

@Test
public void insertTest() throws SQLException, ClassNotFoundException {sqlmanage sqlmanage=new sqlmanage();
      sqlmanage.insertStudent(new student("bigsai",22,180));
      sqlmanage.insertStudent(new student("bigpian",21,165));
      sqlmanage.insertStudent(new student("doudou",20,160));
  }

执行结束刷新 navicat 中 student 表你会发现数据被胜利插入了:

批量插入

如果同时有 100 组数据或者更多若干组数据让你插入你会怎么操作?

  • 循环一个一个的插入
  • 批处理一次插入多个

    批量解决相比循环的单个单个解决起来省了很多工夫,进步了零碎效率。所以当遇到较多数据时能够抉择多个插入。

批量插入实现也很容易,在 sqlmanage 中编写 insertStudents(student students[]) 函数用来批量插入学生记录:

 public void insertStudents(student students[]) throws SQLException {this.con.setAutoCommit(false);// 不主动提交
        String sql="insert into student(name,age,high)value(?,?,?)";
        PreparedStatement ps =con.prepareStatement(sql);
        for(int i=0;i<students.length;i++)
        {ps.setString(1,students[i].getName());
            ps.setInt(2,students[i].getAge());
            ps.setInt(3,students[i].getHigh());
            ps.addBatch();
            if(i%1000==0)
            {ps.executeBatch();
            }
        }
        ps.executeBatch();
        con.commit();
        ps.close();}

其中:

  • con.setAutoCommit(false)意为不主动提交,因为咱们在批量解决的时候个别手动提交提高效率。
  • 次要通过 PreparedStatement 对象的 addBatch()进行多组插入而未提交。
  • 如果为设置不主动提交当执行 executeBatch()时就会提交,但为了减小提交次数曾经设置不主动提交。当且仅当 con.commit()执行才会真的提交到 MySQL 中。

接着在 test 单元测试中编写 insertStudentsTest()函数进行测试批量插入:

@Test
public void insertStudentsTest() throws SQLException, ClassNotFoundException {sqlmanage sqlmanage=new sqlmanage();
    student students[]=new student[5];
    for(int i=0;i<students.length;i++)
    {students[i]=new student("路人"+i,12,156);
    }
    sqlmanage.insertStudents(students);
}

执行结束后你能够看到数据被胜利插入 MySQL 中:

查问数据

查问的应用频率要远比其余的操作多,尽管有些简单表的查问可能会让人比拟头疼,但根底的 sql 查问还是比较简单,其语法格局为:

select 字段 1, 字段 2,…… from 表名 [where 条件] // 形式 1
select * from 表名 [where 条件] // 形式 2 

其中如果没有 where 条件那么就默认查问整张表的内容,咱们在这里依据此条件查问所有记录:查问返回年龄小于 21 岁的所有学生

首先在 sqlmanage 中编写 getallstudent() 函数,用来查问 student 表中所有 age 小于 21 的记录,并把查问的数据最终以 List<studnet> 类型返回:<!– 能够解释一下这段代码的作用 –>

 public List<student> getallstudent() throws SQLException {List<student>list=new ArrayList<student>();// 返回的后果
        String sql = "select * from student  where age < 21";
        PreparedStatement ps = con.prepareStatement(sql);
        ResultSet resultSet=ps.executeQuery();// 后果集
        while(resultSet.next())// 遍历
        {int id=resultSet.getInt(1);
            String name=resultSet.getString(2);
            int age=resultSet.getInt(3);
            int high=resultSet.getInt(4);
           list.add(new student(id,name,age,high));
        }
        ps.close();
        return list;
    }

在后面讲的插入的过程返回值其实不须要特地解决,因为返回是插入胜利与否的音讯,而在查问的步骤就要严格的跟着 JDBC 的 6 个步骤来—因为须要对返回的数据进行解决。咱们次要通过 ResultSet 解决返回的数据。

在对 ResultSet 进行迭代遍历取值的过程中,通过 getXXX(int index)的办法取值并主动转换为 java 对应的数据类型。而 index 为 MySQL 数据库表格列的编号,也是数据在 ResultSet 中的对应序列号。

通过下面的函数在 test 单元测试中编写selectTest() 测试函数在控制台打印从数据库中查问所有 age 小于 21 的记录:<!– 能够解释一下这段代码的作用 –>

@Test
public  void selectTest() throws SQLException, ClassNotFoundException {sqlmanage sqlmanage=new sqlmanage();
    List<student>list=sqlmanage.getallstudent();
    System.out.println(list.toString());
}

能够看到数据被胜利查问:

JDBC 批改和删除

批改数据

对某个确定的记录批改,咱们个别依据这条信息的主键作为条件进行批改。而批改个别都须要条件语句 where,否则批改整个表的内容。批改的 MySQL 语句为:

update 表名 set 字段 = 值 [where 条件]; -- 倡议都有 where: 不然的话会批改每一条数据

这里咱们假如 将上述 student 表中所有 age 为 12 的记录的 name 设置为 xiaoming。在 sqlmanage 中编写 update() 函数用来进行批改:

public void update() throws SQLException {
       String sql = "update student set name='xiaoming'where age=12";
       PreparedStatement ps = con.prepareStatement(sql);
       ps.executeUpdate();
       ps.close();}

在 tes 单元测试中编写 updateTest() 函数调用 sqlmanage 类的 update()办法,将 student 表中所有 age 为 12 的记录的 name 设为 xiaoming。<!– 能够解释一下这段代码的作用 –>

 @Test
    public void updateTest() throws SQLException, ClassNotFoundException {sqlmanage sqlmanage=new sqlmanage();
        sqlmanage.update();}

刷新 Navicat 你会发现数据被胜利更新了:

删除数据

JDBC 删除也是罕用的一种操作,但删除的操作肯定要审慎,谨防误删、多删等操作。删除的语句个别都有 where 条件,否则会删除所有记录。删除的 sql 语句为:

delete from 表名 [where 条件];

咱们编写一个依照 id 删除记录的函数,在 sqlmanage 中编写deletebyid(int id),该函数意为依据 id 删除 student 表中对应 id 的一条记录:<!– 能够解释一下这段代码的作用 –>

public  void deletebyid(int id) throws SQLException {
        String sql = "delete from student where id = ?";
        PreparedStatement ps = con.prepareStatement(sql);
        ps.setInt(1,id);
        ps.executeUpdate();
        ps.close();}

这么一个依据 id 删除的函数就写好了,咱们在 test 单元测试中编写 deleteTest() 测试函数删除 student 表中 id 为 1 的那条记录。:<!– 能够解释一下这段代码的作用 –>

@Test
public  void deleteTest() throws SQLException, ClassNotFoundException {sqlmanage sqlmanage=new sqlmanage();
    sqlmanage.deletebyid(1);
}

执行实现查看数据库发现 id 为 1 的记录(name 为 bigsai 的记录) 被胜利删除:

总结与拓展

总结

好了,本次 JDBC+MySQL 的增删改查的案例就到这里了。回顾本课程你是不是感觉所有如同没那么难,只须要循序渐进就能够实现整个案例。咱们回顾一下整个流程:

  • 创立数据库和表
  • 创立我的项目增加 JDBC 和 Junit 单元测试依赖
  • 编写我的项目代码(JDBC 6 个步骤)
  • 单元测试

每个流程代表一个知识点,其中最重要的就是要熟练掌握 JDBC 编程的流程了,把握其办法,如果有所忘记还得多多回顾。

拓展

MySQL 本案例只应用了四种基本操作对应的 sql 语句:insert(插入),select(查问),update(批改),delete(删除)。如果须要深刻学习 MySQL 的话很多方面须要深刻开掘,从 sql 语句上你还须要去学习 MySQL 简单查问例如关联查问、分组、排序等。从性能上要关注 MySQL 索引类型以及理解其底层数据结构与劣势。从安全性和数据一致性你要去理解学习 MySQL 脏读、幻读等以及各种锁的应用……

而 JDBC 算是在 Java 中一种很原生解决 MySQL 的形式了,而到前面随着学习的深刻你会接触两个 ORM 框架—MybatisHibernate,当然在国内 Mybatis 要更风行一些。这两个框架是对 JDBC 的封装,让开发者可能更容易的在利用中应用 MySQL 等关系数据库,在 Web 我的项目有着宽泛的利用,无论是以前的 SSH(Spring,Strus2,Hibernate) 和当初风行的 SSM(Spring,SpringMVC,Mybatis),其作为长久层的框架都是基于对 JDBC 的封装解决。所以日后在学习新框架同时要记得回顾 JDBC 的内容,多把握 JDBC 底层原理!

好啦,下课!咱们后会有期!

最初,本文收录在公众号:bigsai 中,更多精彩与材料与您分享,欢送 mark与您一起成长! 同时也收录在博学谷以关卡的新模式展示,欢送尝试!

正文完
 0