全民学后端快餐教程(2) - 连接数据库

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS PostgreSQL,集群系列 2核4GB
简介: 使用JdbcTemplate访问数据库

全民学后端快餐教程(2) - 连接数据库

上一节我们介绍了如何像写一个普通Java程序一样去写Web应用,现在我们已经可以通过@Controller注解来获取路由,并且返回字符串给浏览器显示。
跟客户端打通了之后,下面最重要的任务就是能够访问数据库。我们就以MySQL数据库被Oracle收购后fork出来的Mariadb为例,说明连接数据库的方法。

安装配置Mariadb

看了下阿里云ECS最新的Ubuntu镜像已经升级到了18.04 LTS,我们就以此版本为基础说明。

安装Mariadb

安装Mariadb很简单,用下面命令就可以了:

apt install mariadb-server

连接到Mariadb

通过mysql连接Mariadb服务:

mysql -u root

然后我们执行下show databases看看都有些什么库:

MariaDB [(none)]> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
+--------------------+
3 rows in set (0.00 sec)

创建使用数据库

连接正常,于是我们开始干活,建立我们要用的数据库。
使用create database命令可以创建数据库,命令如下:

MariaDB [(none)]> create database prefix;
Query OK, 1 row affected (0.00 sec)

然后我们切换到prefix数据库,通过use命令:

MariaDB [(none)]> use prefix;
Database changed

建表

下面我们创建一张表。这张表叫做issue表,用于保存做代码扫描时发现的问题,主要字段是代码所在的文件名,行号,还有发现问题的内容字符串。
SQL语句如下:

CREATE TABLE issue(
    id integer(16) not null auto_increment,
    filename varchar(256) not null,
    linenum integer(16) not null,
    issuestring varchar(256) not null,
    primary key(id)
);

运行结果如下:

MariaDB [prefix]> CREATE TABLE issue(
    ->     id integer(16) not null auto_increment,
    ->     filename varchar(256) not null,
    ->     linenum integer(16) not null,
    ->     issuestring varchar(256) not null,
    ->     primary key(id)
    -> );
Query OK, 0 rows affected (0.02 sec)

我们插入一条记录测试下:

MariaDB [prefix]> insert into issue (filename,linenum, issuestring) values ('test.java',1,'No @author');
Query OK, 1 row affected (0.00 sec)

再select一下看看刚才插入的结果:

MariaDB [prefix]> select * from issue;
+----+-----------+---------+-------------+
| id | filename  | linenum | issuestring |
+----+-----------+---------+-------------+
|  1 | test.java |       1 | No @author  |
+----+-----------+---------+-------------+
1 row in set (0.00 sec)

创建用户

直接使用root用户访问数据库是件风险很高的事情。我们创建有只读权限的用户来访问数据库就好了。

我们通过create user命令来创建用户,例如就叫prefix:

create user 'prefix'@'localhost' identified by 'AliOS123';

下面我们给这个用户授予select, insert, update, delete的权限:

grant select,update,delete on *.* to 'prefix'@'localhost';

创建是否成功,我们测试一下,使用prefix用户来登录mysql:

mysql -u prefix -p

密码使用刚才设置的AliOS123。

我们试验下是否可以使用prefix数据库,并且可以选择issue表的内容:

MariaDB [(none)]> use prefix;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
MariaDB [prefix]> select * from issue;
+----+-----------+---------+-------------+
| id | filename  | linenum | issuestring |
+----+-----------+---------+-------------+
|  1 | test.java |       1 | No @author  |
+----+-----------+---------+-------------+
1 row in set (0.00 sec)

使用JDBC Template访问数据库

数据库配置

访问数据库,首先我们需要进行一些配置。配置文件我们放在src/main/resources目录下,名字叫application.properties,写库名,用户名,密码这三项就好:

spring.datasource.url=jdbc:mysql://localhost:3306/prefix
spring.datasource.username=prefix
spring.datasource.password=AliOS123

引入JDBC和MySQL的库依赖

我们还是修改pom.xml引入对JDBC和MySQL的库的依赖:

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>

现在的完整pom.xml是这样的:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>cn.alios.system.service.prefix</groupId>
    <artifactId>Prefix</artifactId>
    <version>1.0.0-SNAPSHOT</version>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.2.RELEASE</version>
    </parent>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

POJO类

下面我们开始写Java代码。首先为了保存数据库中读来的值,我们需要定义一个Java对象。这个对象不继承任何复杂对象,不实现任何接口,所以一般称为POJO(Plain Ordinary Java Object)对象。

我们的Issue类,只要id, filename, linenum, issuestring四个属性就好:

    private Long id;
    private String filename;
    private Long lineNum;
    private String issueString;

完整的类是再加上自动生成的getter和setter方法:

package cn.alios.system.service.prefix.pojo;

public class Issue {
    private Long id;
    private String filename;
    private Long lineNum;
    private String issueString;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getFilename() {
        return filename;
    }

    public void setFilename(String filename) {
        this.filename = filename;
    }

    public Long getLineNum() {
        return lineNum;
    }

    public void setLineNum(Long lineNum) {
        this.lineNum = lineNum;
    }

    public String getIssueString() {
        return issueString;
    }

    public void setIssueString(String issueString) {
        this.issueString = issueString;
    }

}

服务类

有个POJO类保存结果之后,我们来写一个根据id来查询的简单功能。这个名字可以叫做getIssueById,我们就简称getIssue吧:

package cn.alios.system.service.prefix.service;

import cn.alios.system.service.prefix.pojo.Issue;

public interface JdbcTemplateIssueService {

    public Issue getIssue(Long id);
}

如何实现这个功能呢?这时候JDBCTemplate最省事,直接写SQL语句,调用JDBCTemplate的queryForObject函数,如下:

    @Override
    public Issue getIssue(Long id) {
        String sql = "select id, filename, linenum, issuestring from issue where id = ?;";
        Object[] params = new Object[]{id};
        Issue issue = jdbcTemplate.queryForObject(sql, params, getIssueMapper());
        return issue;
    }

getIssueMapper负责将字段跟Issue对象的各个字段关联起来:

    //映射关系
    private RowMapper<Issue> getIssueMapper() {
        RowMapper<Issue> issueRowMapper = (ResultSet rs, int rownum) -> {
            Issue issue = new Issue();
            issue.setId(rs.getLong("id"));
            issue.setFilename(rs.getString("filename"));
            issue.setLineNum(rs.getLong("linenum"));
            issue.setIssueString(rs.getString("issuestring"));
            return issue;
        };
        return issueRowMapper;
    }

下面是完整的Service类。其中的@Autowired注解是Spring Boot会为我们自动注入JdbcTemplate对象。

package cn.alios.system.service.prefix.service;

import cn.alios.system.service.prefix.pojo.Issue;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Service;

import java.sql.ResultSet;

@Service
public class JdbcTemplateIssueServiceImpl implements JdbcTemplateIssueService {
    @Autowired
    private JdbcTemplate jdbcTemplate = null;

    /*
    表结构:
    +----+-----------+---------+-------------+
    | id | filename  | linenum | issuestring |
    +----+-----------+---------+-------------+
     */

    //映射关系
    private RowMapper<Issue> getIssueMapper() {
        RowMapper<Issue> issueRowMapper = (ResultSet rs, int rownum) -> {
            Issue issue = new Issue();
            issue.setId(rs.getLong("id"));
            issue.setFilename(rs.getString("filename"));
            issue.setLineNum(rs.getLong("linenum"));
            issue.setIssueString(rs.getString("issuestring"));
            return issue;
        };
        return issueRowMapper;
    }

    @Override
    public Issue getIssue(Long id) {
        String sql = "select id, filename, linenum, issuestring from issue where id = ?;";
        Object[] params = new Object[]{id};
        Issue issue = jdbcTemplate.queryForObject(sql, params, getIssueMapper());
        return issue;
    }
}

将Service注入给Controller

JdbcTemplate是Spring容器帮我们注入的,现在我们再用@Autowired把Service注入给Controller,然后Controller就可以调用Service来查询数据库了:

package cn.alios.system.service.prefix.controller;

import cn.alios.system.service.prefix.pojo.Issue;
import cn.alios.system.service.prefix.service.JdbcTemplateIssueServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
@RequestMapping("/test")
public class TestController {
    @Autowired
    JdbcTemplateIssueServiceImpl jdbcTemplateIssueService = null;

    @RequestMapping("/")
    @ResponseBody
    public String test() {
        Issue issue = jdbcTemplateIssueService.getIssue((long) 1);
        if (issue != null) {
            return issue.getFilename() + "," + issue.getIssueString();
        } else {
            return "Test Controller!";
        }
    }
}

到这里,一次对于数据库的完整访问流程就走通了。

我们试验一下效果:

mvn package
java -jar target/Prefix-1.0.0-SNAPSHOT.jar

然后在浏览器中查看:http://127.0.01:8080/test/
输出值为:test.java,No @author

小结

使用JdbcTemplate编程,主要靠直接写SQL语句,然后调用JdbcTemplate的接口去执行SQL语句,并处理返回值。

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
1月前
|
关系型数据库 MySQL 数据库连接
python脚本:连接数据库,检查直播流是否可用
【10月更文挑战第13天】本脚本使用 `mysql-connector-python` 连接MySQL数据库,检查 `live_streams` 表中每个直播流URL的可用性。通过 `requests` 库发送HTTP请求,输出每个URL的检查结果。需安装 `mysql-connector-python` 和 `requests` 库,并配置数据库连接参数。
126 68
|
19天前
|
存储 SQL API
探索后端开发:构建高效API与数据库交互
【10月更文挑战第36天】在数字化时代,后端开发是连接用户界面和数据存储的桥梁。本文深入探讨如何设计高效的API以及如何实现API与数据库之间的无缝交互,确保数据的一致性和高性能。我们将从基础概念出发,逐步深入到实战技巧,为读者提供一个清晰的后端开发路线图。
|
20天前
|
存储 SQL 数据库
深入浅出后端开发之数据库优化实战
【10月更文挑战第35天】在软件开发的世界里,数据库性能直接关系到应用的响应速度和用户体验。本文将带你了解如何通过合理的索引设计、查询优化以及恰当的数据存储策略来提升数据库性能。我们将一起探索这些技巧背后的原理,并通过实际案例感受优化带来的显著效果。
36 4
|
29天前
|
SQL Java 数据库连接
在Java应用中,数据库访问常成为性能瓶颈。连接池技术通过预建立并复用数据库连接,有效减少连接开销,提升访问效率
在Java应用中,数据库访问常成为性能瓶颈。连接池技术通过预建立并复用数据库连接,有效减少连接开销,提升访问效率。本文介绍了连接池的工作原理、优势及实现方法,并提供了HikariCP的示例代码。
44 3
|
2月前
|
关系型数据库 MySQL 数据库连接
DBeaver如何连接一个数据库
【10月更文挑战第27天】DBeaver 是一款功能强大的通用数据库管理工具,支持多种主流数据库。本文介绍了使用 DBeaver 连接数据库的基本步骤,包括下载安装、创建新连接、选择数据库类型、配置连接参数、测试连接以及最终连接到数据库。详细的操作指南帮助用户轻松管理和操作数据库。
218 9
|
29天前
|
Java 数据库连接 数据库
深入探讨Java连接池技术如何通过复用数据库连接、减少连接建立和断开的开销,从而显著提升系统性能
在Java应用开发中,数据库操作常成为性能瓶颈。本文通过问题解答形式,深入探讨Java连接池技术如何通过复用数据库连接、减少连接建立和断开的开销,从而显著提升系统性能。文章介绍了连接池的优势、选择和使用方法,以及优化配置的技巧。
27 1
|
29天前
|
Java 数据库连接 数据库
Java连接池在数据库性能优化中的重要作用。连接池通过预先创建和管理数据库连接,避免了频繁创建和关闭连接的开销
本文深入探讨了Java连接池在数据库性能优化中的重要作用。连接池通过预先创建和管理数据库连接,避免了频繁创建和关闭连接的开销,显著提升了系统的响应速度和吞吐量。文章介绍了连接池的工作原理,并以HikariCP为例,展示了如何在Java应用中使用连接池。通过合理配置和优化,连接池技术能够有效提升应用性能。
43 1
|
1月前
|
SQL 关系型数据库 数据库连接
"Nacos 2.1.0版本数据库配置写入难题破解攻略:一步步教你排查连接、权限和配置问题,重启服务轻松解决!"
【10月更文挑战第23天】在使用Nacos 2.1.0版本时,可能会遇到无法将配置信息写入数据库的问题。本文将引导你逐步解决这一问题,包括检查数据库连接、用户权限、Nacos配置文件,并提供示例代码和详细步骤。通过这些方法,你可以有效解决配置写入失败的问题。
56 0
|
9天前
|
Web App开发 JavaScript 前端开发
Node.js 是一种基于 Chrome V8 引擎的后端开发技术,以其高效、灵活著称。本文将介绍 Node.js 的基础概念
Node.js 是一种基于 Chrome V8 引擎的后端开发技术,以其高效、灵活著称。本文将介绍 Node.js 的基础概念,包括事件驱动、单线程模型和模块系统;探讨其安装配置、核心模块使用、实战应用如搭建 Web 服务器、文件操作及实时通信;分析项目结构与开发流程,讨论其优势与挑战,并通过案例展示 Node.js 在实际项目中的应用,旨在帮助开发者更好地掌握这一强大工具。
30 1
|
4天前
|
存储 缓存 监控
后端开发中的缓存机制:深度解析与最佳实践####
本文深入探讨了后端开发中不可或缺的一环——缓存机制,旨在为读者提供一份详尽的指南,涵盖缓存的基本原理、常见类型(如内存缓存、磁盘缓存、分布式缓存等)、主流技术选型(Redis、Memcached、Ehcache等),以及在实际项目中如何根据业务需求设计并实施高效的缓存策略。不同于常规摘要的概述性质,本摘要直接点明文章将围绕“深度解析”与“最佳实践”两大核心展开,既适合初学者构建基础认知框架,也为有经验的开发者提供优化建议与实战技巧。 ####

热门文章

最新文章