Logo

郎哥编程

Spring使用JDBC访问MySQL数据库

2018-10-24 963

在Java应用程序开发中,使用JDBC访问MySQL数据库是Java开发者常用的技术。在Spring框架中,Spring对JDBC又进行了封装,简化了程序访问数据库的复杂度。本课主要讨论在Spring框架中如何使用封装的JDBC访问MySQL数据库。通过本课的学习,可以解决如下问题。

●  在Spring框架下,如何让程序连接数据库?

●  如何利用DAO技术从数据源读取和写入数据?

企业级应用开发都会涉及到对数据库的访问,在Java编程环境中,访问数据库是非常繁琐的事情,需要编写启动数据库连接、准备和执行SQL语句、处理事务和异常、关闭连接等大量数据库操作代码。

使用Spring框架可以简化Java程序对数据库的访问,Spring提供了一套完整的数据库访问框架,用于简化各种数据库访问技术的使用。Spring框架支持JDBC、Hibernate、Java Perssitence等数据库访问技术,本文主要讨论JDBC数据库访问技术。


1、 配置数据源


要让Spring能够访问数据库,就要把数据库的位置,以及访问数据库的账号和密码告诉Spring。这个过程称为配置数据源。Spring提供了多种方式配置数据源,下面主要讨论基于JDBC驱动方式配置数据源。

Spring提供的JDBC驱动提供了三类数据源的配置方式,开发者可以根据程序需要选择不同的配置方式,配置方式及其配置说明如下表所示。

表1 JDBC驱动配置数据源方式

image.png


本课主要使用DriverManagerDataSource连接数据源,没有使用连接池技术。后面的课程会讨论数据库连接池技术。

数据源可以在Spring配置文件中进行配置,配置代码如下。

  <!-- 配置数据源 -->
   <bean id="dataSource"
      class="org.springframework.jdbc.datasource.DriverManagerDataSource">
      <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
      <property name="url" value="jdbc:mysql://localhost:3306/mooc?characterEncoding=utf8"/>
      <property name="username" value="root"/>
      <property name="password" value="~123456q"/>
   </bean>


2、创建数据访问对象(DAO)


数据访问对象(DAO)相当于程序和数据源之间的经纪人。程序要访问数据源,必须要通过DAO来访问,DAO提供了程序访问数据源必要的接口和方法,接口和方法的具体实现细节,程序并不需要了解。

DAO由数据访问对象接口、数据访问对象实现类、访问对象实体类组成。其中,数据访问对象接口定义了访问数据必要的接口声明;数据访问对象实现类实现了定义的接口,并负责从数据源读取数据,数据源可以是数据库、XML文件或者是其它存储对象;访问对象实体类定义了要访问的对象结构,假设要访问的数据对象是数据库,则该实体类定义了数据库中一个表的结构。下面以访问数据库为例,分别讨论数据访问对象接口、数据访问对象实现类和访问对象实体类。

(1)数据访问对象接口

访问数据库的操作一般是增、删、改、查。增是在指定的数据库表中插入一条记录;删是在指定的数据库表中删除一条记录;改是在指定的数据库表中修改记录;查是按指定条件查询数据库表记录。数据访问对象接口就是定义操作数据库表的增删改查接口。下面给出课程案例mooc数据库course表的DAO接口。

课程案例mooc数据库ER图如下所示。

image.png

                                             

图 1 mooc数据库ER图

mooc数据库course表结构如下。

表 2  课程表

image.png


course表DAO接口代码如下。

package com.milihua.springprogram.dao;
import java.util.List;
import javax.sql.DataSource;
import com.milihua.springprogram.entity.Course;
public interface CourseDao {
       /**
        * 初始化数据源
        */
       public void setDataSource(DataSource ds);
       /**
        * 插入一条课程记录
        */
       public void insertCourse(Course inCourse);
       /**
        * 获取课程记录,获取的课程由编号指定
        */
       public Course getCourse(String number);
       /**
        * 获取全部课程记录
        */
       public List<Course> listCourse();
       /**
        * 删除课程记录,删除的课程由编号指定
        */
       public void delete(String number);
       /**
        * 更新课程记录
        *
        */
       public void update(Course inCourse);
}

(2)数据访问对象实现类

数据访问对象实现类实现DAO接口,并负责从mooc数据库中读取数据。在Spring中,可以采用JDBC、Hibernate、MyBits、JPA等技术在DAO层实现对数据库的访问。本课采用JDBC技术,JdbcTemplate类是Spring对JDBC的封装,让JDBC更加容易使用,JdbcTemplate 类可以执行 标准的SQL 语句和过程调用。数据访问对象实现类代码如下。

package com.milihua.springprogram.jdbc;
import java.util.List;
import javax.sql.DataSource;
import org.springframework.jdbc.core.JdbcTemplate;
import com.milihua.springprogram.dao.CourseDao;
import com.milihua.springprogram.entity.Course;
 
public class CourseJDBCTemplate implements CourseDao{
 
    private DataSource dataSource;
    private JdbcTemplate jdbcTemplateObject;
 
    @Override
    public void setDataSource(DataSource ds) {
        // TODO Auto-generated method stub
        this.dataSource = ds;
        this.jdbcTemplateObject = new JdbcTemplate(dataSource);
    }
 
    @Override
    public void insertCourse(Course inCourse) {
        // TODO Auto-generated method stub
        String SQL = "insert into course (number,price,brief,category,teacher_number,name) values (?,?,?,?,?,?)";    
        jdbcTemplateObject.update(SQL,inCourse.getNumber(),inCourse.getPrice(),inCourse.getBrief(),inCourse.getCategory(),inCourse.getTeacher_number(),inCourse.getName());
        System.out.println("插入课程记录 = " + inCourse.getName());
        return;
    }
 
    @Override
    public Course getCourse(String number) {
        // TODO Auto-generated method stub
        String SQL = "select * from course where number = ?";
        Course course = jdbcTemplateObject.queryForObject(SQL,
                            new Object[]{number}, new CourseMapper());
        return course;
    }
 
    @Override
    public List<Course> listCourse() {
        // TODO Auto-generated method stub
        String SQL = "select * from course";
        List <Course> students = jdbcTemplateObject.query(SQL,new CourseMapper());
        return students;
    }
 
    @Override
    public void delete(String number) {
        // TODO Auto-generated method stub
        String SQL = "delete from course where number = ?";
        jdbcTemplateObject.update(SQL, number);
        System.out.println("删除课程记录  课程编号 = " + number );
        return;
 
    }
 
    @Override
    public void update(Course inCourse) {
        // TODO Auto-generated method stub
        String SQL = "update course set name = ? where number = ?";
        jdbcTemplateObject.update(SQL, inCourse.getName(), inCourse.getNumber());
        System.out.println("更新课程名称 = " + inCourse.getName() );
        return;
       
    }
}

CourseJDBCTemplate类实现了CourseDao接口,并实现了接口的所有方法。CourseJDBCTemplate类内置了DataSource和JdbcTemplate类。DataSource为数据源类,存储了数据源的连接地址、登录数据源的账号密码等数据。JdbcTemplate类是Spring对JDBC的封装,JdbcTemplate 类可以执行 标准的SQL 语句和过程调用,创建JdbcTemplate类时传入的参数为DataSource。

package com.milihua.springprogram.jdbc;
import java.util.List;
import javax.sql.DataSource;
import org.springframework.jdbc.core.JdbcTemplate;
import com.milihua.springprogram.dao.CourseDao;
import com.milihua.springprogram.entity.Course;
 
public class CourseJDBCTemplate implements CourseDao{
 
    private DataSource dataSource;
    private JdbcTemplate jdbcTemplateObject;
 
    @Override
    public void setDataSource(DataSource ds) {
        // TODO Auto-generated method stub
        this.dataSource = ds;
        this.jdbcTemplateObject = new JdbcTemplate(dataSource);
    }
 
    @Override
    public void insertCourse(Course inCourse) {
        // TODO Auto-generated method stub
        String SQL = "insert into "
                + "course (number,price,brief,category,teacher_number,name)"
                + " values (?,?,?,?,?,?)";    
        jdbcTemplateObject.update(SQL,inCourse.getNumber(),
            inCourse.getPrice(),
            inCourse.getBrief(),
            inCourse.getCategory(),
            inCourse.getTeacher_number(),
            inCourse.getName());
        System.out.println("插入课程记录 = " + inCourse.getName());
        return;
    }
 
    @Override
    public Course getCourse(String number) {
        // TODO Auto-generated method stub
        String SQL = "select * from course where number = ?";
        Course course = jdbcTemplateObject.queryForObject(SQL,
                            new Object[]{number}, new CourseMapper());
        return course;
    }
 
    @Override
    public List<Course> listCourse() {
        // TODO Auto-generated method stub
        String SQL = "select * from course";
        List <Course> students = jdbcTemplateObject.query(SQL,new CourseMapper());
        return students;
    }
 
    @Override
    public void delete(String number) {
        // TODO Auto-generated method stub
        String SQL = "delete from course where number = ?";
        jdbcTemplateObject.update(SQL, number);
        System.out.println("删除课程记录  课程编号 = " + number );
        return;
 
    }
 
    @Override
    public void update(Course inCourse) {
        // TODO Auto-generated method stub
        String SQL = "update course set name = ? where number = ?";
        jdbcTemplateObject.update(SQL, inCourse.getName(), inCourse.getNumber());
        System.out.println("更新课程名称 = " + inCourse.getName() );
        return;
 
       
    }
 
}

代码中用到了JdbcTemplate类的queryForObject方法,该方法从数据库中查询符合条件的记录。queryForObject方法的第三个参数是RowMapper泛型类型,通过继承RowMapper泛型,可以将查询返回的ResultSet数据集映射到访问对象实体类。

package com.milihua.springprogram.jdbc;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.springframework.jdbc.core.RowMapper;
import com.milihua.springprogram.entity.Course;
 
public class CourseMapper implements RowMapper<Course>{
 
@Override
public Course mapRow(ResultSet rs, int arg1) throws SQLException {
    // TODO Auto-generated method stub
    Course course = new Course();
    course.setNumber(rs.getString("number"));
    course.setName(rs.getString("name"));
    course.setBrief(rs.getString("brief"));
    course.setPrice(rs.getFloat("price"));
    course.setTeacher_number(rs.getString("teacher_number"));
    course.setCategory(rs.getString("category"));
    return course;
}
 
}

(3)访问对象实体类

访问对象实体类定义了要访问的对象结构,假设要访问的数据对象是数据库,则该实体类定义了数据库中一个表的结构。mooc数据库course表的实体类代码如下。

package com.milihua.springprogram.entity;
public class Course {
/*
 * 课程编号
 */
private String number;
/*
 * 课程价格
 */
private float price;
/*
 * 课程简介
 */
private String brief;
/*
 * 课程类别
 */
private String category;
/*
 * 老师编号
 */
private String teacher_number;
/*
 * 课程名称
 */
private String name;
public String getNumber() {
    return number;
}
public void setNumber(String number) {
    this.number = number;
}
public float getPrice() {
    return price;
}
public void setPrice(float price) {
    this.price = price;
}
public String getBrief() {
    return brief;
}
public void setBrief(String brief) {
    this.brief = brief;
}
public String getCategory() {
    return category;
}
public void setCategory(String category) {
    this.category = category;
}
public String getTeacher_number() {
    return teacher_number;
}
public void setTeacher_number(String teacher_number) {
    this.teacher_number = teacher_number;
}
public String getName() {
    return name;
}
public void setName(String name) {
    this.name = name;
}
}


3、运行JDBC的测试程序


前面主要讨论了配置数据源和创建数据访问对象(DAO)相关内容,解决了程序如何访问数据库以及数据库表的读写问题。下面给出一个程序实例,利用前面配置的数据源和已创建的DAO对象,实现对mooc数据库course表的课程插入和查询操作。

mooc数据库非常简单,可以根据课程给出的ER图和course二维表,手动创建mooc数据库和course表。mooc数据库创建完成后,需要修改Spring配置文件中配置的数据源,主要是修改数据库的连接地址、登录账户和密码。

运行程序前需要确定项目已经引入了Spring框架关于JDBC功能的jar包。下面列出的是spring 5.0版本相关JDBC的jar包。

● mysql-connector-java-5.1.7-bin

● spring-jdbc-5.0.8.RELEASE


测试程序代码如下。

package test;
import java.util.List;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.milihua.springprogram.entity.Course;
import com.milihua.springprogram.jdbc.CourseJDBCTemplate;
 
public class DataBaseTest {
 
public static void main(String[] args) {
    // TODO Auto-generated method stub
     ApplicationContext context = new ClassPathXmlApplicationContext("config/database.xml");
     CourseJDBCTemplate courseJDBCTemplate =
     (CourseJDBCTemplate)context.getBean("courseJDBCTemplate");   
     System.out.println("------插入课程记录--------" );
     Course course = new Course();
     course.setNumber("0001");
     course.setName("Java基础教程");
     course.setBrief("本课程尝试用一个编程案例与同学们探讨程序的开发流程,"
            + "然后讲述Java的基础语法,"
            + "掌握变量的意义及用法,在掌握变量的基础上,"
            + "梳理Java的数据类型及基本的输入与输出。");
     course.setCategory("编程");
     course.setPrice((float)39.5);
     course.setTeacher_number("teacher_001");
     courseJDBCTemplate.insertCourse(course);
    
     course.setNumber("0002");
     course.setName("Python教程");
     course.setBrief("课程阐述Python的核心内容,包括基本的概念和语句"
            + "、Python对象、映射和集合类型、文件的输入和输出、"
            + "函数和函数式编程等内容");
     course.setCategory("编程");
     course.setPrice((float)29);
     course.setTeacher_number("teacher_001");
     courseJDBCTemplate.insertCourse(course);
 
     System.out.println("------查询课程记录--------" );
     List<Course> courses = courseJDBCTemplate.listCourse();
     for (Course record : courses) {
         System.out.print("课程编号 : " + record.getNumber() );
         System.out.print("课程名称 : " + record.getName() );
         System.out.println("课程简介: " + record.getBrief());
      }
  }
}

程序运行结果如下图示所示。

image.png

                                             

课程小结

(1)要让Spring能够访问数据库,就要把数据库的位置,以及访问数据库的账号和密码告诉Spring,这个过程称为配置数据源。数据源可以在Spring配置文件中进行配置,也可以写成Bean的方式,由DAO对象读取。

(2)数据访问对象(DAO)相当于程序和数据源之间的经纪人。程序要访问数据源,必须要通过DAO来访问,DAO提供了程序访问数据源必要的接口和方法,接口和方法的具体实现细节,程序并不需要了解。DAO将底层数据操作细节和上层应用进行了有效隔离,在程序开发过程中,DAO和上层应用都可以独立编写代码,然后再进行集成就可以了,利用DAO层也可以轻松实现不同数据库的访问。


代码在线纠错(通义千问 qwen-max)

支持粘贴多个代码文件,提交后由阿里云通义千问自动分析代码漏洞、语法错误、逻辑问题并给出修改建议。
您已解锁 AI 代码纠错功能,可正常使用!

评论区

登录 后发表评论
暂无评论