如何使用 Groovy 操作数据库?

上一节课程中我们学习了 Groovy 的部分语法、闭包和集合处理的知识,本次课程将带领大家学习如何使用 Groovy 操作数据库、编写 Groovy 脚本。为了完成本次课程目标,我划分了两个 task:

  • Groovy 操作数据库
  • 编写和执行 Groovy 脚本

groovy操作数据库

在开始学习前请安装 MySQL服务器和客户端并创建对应的 Database。

以下是在DataBase中创建一张 user 表和 address 表并初始化一些数据的 SQL:

CREATE TABLE IF NOT EXISTS `user`(
  `id` INT UNSIGNED AUTO_INCREMENT,
  `username` VARCHAR(100) NOT NULL,
  `age` INTEGER NOT NULL,
  `create_date` DATE,
  PRIMARY KEY ( `id` )
)ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE IF NOT EXISTS `address`(
  `id` INT UNSIGNED AUTO_INCREMENT,
  `userId` INT ,
  `address` VARCHAR(100) NOT NULL,
  `create_date` DATE,
  PRIMARY KEY ( `id` )
)ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO USER (username,age,create_date)VALUES ('TOM',10,'2019-10-11 12:10:10');
INSERT INTO USER (username,age,create_date)VALUES ('DONE',15,'2019-10-10 12:10:10');
INSERT INTO USER (username,age,create_date)VALUES ('ECHO',20,'2019-10-15 12:10:10');
INSERT INTO USER (username,age,create_date)VALUES ('MARY',10,'2019-10-10 12:10:10');
INSERT INTO address (userId,address,create_date)VALUE (1,'chengdu','2019-11-12 00:00:00');
INSERT INTO address (userId,address,create_date)VALUE (2,'beijing','2019-11-12 00:00:00');
INSERT INTO address (userId,address,create_date)VALUE (3,'shanghai','2019-11-12 00:00:00');
INSERT INTO address (userId,address,create_date)VALUE (4,'hangzhou','2019-11-12 00:00:00');

通过客户端工具例如 navicat 执行上述 SQL,执行完后确保数据是完整的,因为后面会编写代码来获取数据库数据,如果数据不正确,测试 Case 会运行失败。

如下图所示,笔者使用命令查看数据库中数据确实已初始化成功。

为了在接口测试项目中编写连接数据库的代码,需要添加mysql依赖。接口测试项目pom.xml文件中需添加内容如下。

properties中添加 version 信息

 <mysql.version>5.1.44</mysql.version>

dependencies下添加依赖

 <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>${mysql.version}</version>
      <scope>test</scope>
    </dependency>

配置好pom.xml文件后,在命令框或者 IntellJ 中执行mvn clean install下载依赖。

下载依赖后就可以开始编写操作数据库的代码了,创建DataSource,ConstantSql,DataRepository 三个 Class。

  • DataSources 负责数据库的连接
  • ConstantSql 存放 SQL 常量
  • DataRepository 存放操作数据库的方法

以下是DataSources的代码,实际项目中如果需要连接多个数据库或者多种类型数据库,例如mongoDB,oracle等都可以放到该Class中

class DataSource {
    Sql sql
    Sql getSql() {
        if (!sql) {
            def mysqlDB = [
                    driver  : 'com.mysql.jdbc.Driver',
                    url     : 'jdbc:mysql://127.0.0.1:3306/apitestdb',
                    user    : 'root',          //这里写入安装mysql是设置的用户名
                    password: 'root12345'     //这里写入安装mysql时设置的密码
            ]
            sql = Sql.newInstance(mysqlDB.url, mysqlDB.user, mysqlDB.password, mysqlDB.driver)
            // 连接mysql数据库固定写法
        }
        sql
    }
}

ConstantSql代码,包含增删该查 SQL

class ConstantSql {
    static final getUserInfo="select * from user"
    static final getAddressInfoByUserName ="select a.username,a.age,b.address from user a,address b where a.id=b.userId and a.username=?"
    static final addUser = "insert into user (username,age,create_date) values (?,?,'1019-10-11:11:12:13')"
    static final getUser="select * from user where username=?"
    static final updateAge="update user set age=? where username=?"    //sql查询语句固定写法,需要传递参数的地方用?
}

DataRepository代码,负责执行 SQL

class DataRepository extends DataSource{
    def getUserInfo() {
        def userInfo = sql.rows(ConstantSql.getUserInfo)   //查询多行数据
        userInfo ? userInfo : ''  //这里做了空保护
    }

    def getAddressByUserName(userName) {
        def address = sql.firstRow(ConstantSql.getAddressInfoByUserName, [userName])  //只获取第一行数据
        // 上面调用的getAddressInfoByUserName sql语句需要传递一个参数,所以在后面带了userName参数
        address ? address : ''
    }

    def addUser(userName,age) {
        sql.execute(ConstantSql.addUser,[userName,age])   //传递两个参数
        // 非查询类操作使用execute方法
    }

    def getUser(userName) {
        sql.firstRow(ConstantSql.getUser,[userName])
    }

    def updateAddress(userName,age) {
        sql.execute(ConstantSql.updateAge,[age,userName])
    }
}   

编写case检查是否能获取正确数据

class Case extends Specification {
    DataRepository dataRepository

    void setup() {
        dataRepository = new DataRepository()
    }

    def "should get user info successfully"() {
        given: "no given"
        when: "query user table to get info"
        def userInfo = dataRepository.getUserInfo()
        then: "should get user info"
        userInfo.each { it -> println it.username + ":" + it.age + ":" + it.create_date }   //打印从数据库获取到的所有user信息
    }

    def "should get user address successfully"() {
        given: "no given"
        when: "query user and address table"
        def addressInfo = dataRepository.getAddressByUserName(userName)
        then: "should get correct user address info"
        Assert.assertEquals(addressInfo.address, address)  //校验从数据库获取的数据是否正确
        where:
        userName | address
        "TOM"    | "chengdu"
        "DONE"   | "beijing"
        "ECHO"   | "shanghai"
        "MARY"   | "hangzhou"
    }

    def "should add user successfully"() {
        given: "no given"
        when: "add user"
        dataRepository.addUser(userName, age)    //添加信息到user表
        then: "should get added user successfully"
        Assert.assertEquals(dataRepository.getUser(userName).username, userName)  //只有成功添加了“Dave”这个user,校验才会成功
        where:
        userName | age
        "Dave"   | 88
    }

    def "should update address successfully"() {
        given: "no given"
        when: "update user's address"
        dataRepository.updateAddress(userName, age)  //修改user表信息
        then: "should update address successfully"
        Assert.assertEquals(dataRepository.getUser(userName).age, age)   //校验修改后的user的age是否正确
        where:
        userName | age
        "MARY"   | 55
    }
}

执行上述的case,全部执行成功如下图所示,说明正确从数据库获取到了数据。

以上就是 Groovy 操作数据库的所有知识点,可以看到非常简单,配置好数据库连接信息后编写 SQL 增删该查语句并调用 Groovy 自带的 execute、firstRow、rows 等方法执行即可。接下来将给大家介绍下 Groovy 脚本。

groovy脚本文件

以上讲解的内容中都是通过创建 Class 使用 Groovy ,实际上面所写的所有代码还可以放到xxx.groovy文件中,且可直接运行xxx.groovy,即通过执行脚本文件运行编写的代码。

测试工作中编写合理脚本可协助进行手动测试提升测试效率,例如一些测试数据的准备,测试结果的校验等。

要运行 Groovy 脚本需要单独安装 Groovy,Groovy 安装方法

安装好后创建一个 first.groovy 的文件,文件中写入println "hello world",然后在命令行工具上运行groovy ./test.groovy,就可以打印出"hello world",如下图所示。

大家可以把前面写过的一些内容copy到 Groovy 脚本上尝试运行感受下,这里介绍 Groovy 脚本内容是期望大家能多掌握一些技能,这样在日常手动测试中,可以编写一些脚本辅助手动测试,提升测试效率。

另外如今越来越火的构建工具 Gradle 就是 Groovy 写的,掌握好 Groovy 脚本可以更好的使用Gradle。

至此 Groovy 操作数据库的内容就结束了,下节课会带领大家学习如何通过 Groovy 操作各种文件,然后重写 DataSource,将数据库连接信息放到 yaml 文件中统一管理。

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Groovy中连接多个数据库进行数据操作,可以使用不同的数据库驱动程序和连接池。以下是一个示例代码,演示如何连接两个数据库(MySQL和Oracle)并执行数据操作: ```groovy @Grab(group='org.codehaus.groovy.modules', module='groovy-sql', version='3.0.0') import groovy.sql.Sql import groovy.sql.SqlDataSource // MySQL 数据库连接信息 def mysqlUrl = 'jdbc:mysql://localhost:3306/mydb' def mysqlUsername = 'root' def mysqlPassword = 'root' // Oracle 数据库连接信息 def oracleUrl = 'jdbc:oracle:thin:@localhost:1521:xe' def oracleUsername = 'system' def oraclePassword = 'oracle' // 创建 MySQL 数据库连接池和 Sql 对象 def mysqlDataSource = new SqlDataSource( url: mysqlUrl, username: mysqlUsername, password: mysqlPassword, driver: 'com.mysql.jdbc.Driver' ) def mysql = Sql.newInstance(mysqlDataSource) // 创建 Oracle 数据库连接池和 Sql 对象 def oracleDataSource = new SqlDataSource( url: oracleUrl, username: oracleUsername, password: oraclePassword, driver: 'oracle.jdbc.driver.OracleDriver' ) def oracle = Sql.newInstance(oracleDataSource) // 在 MySQL 中插入数据 mysql.execute("INSERT INTO users (username, password) VALUES ('john', 'doe')") // 在 Oracle 中查询数据 def result = oracle.rows("SELECT * FROM orders WHERE customer_id = 123") // 关闭连接 mysql.close() oracle.close() ``` 在上面的示例中,我们使用了 `groovy-sql` 模块来连接数据库和执行数据操作。我们首先定义了两个数据库的连接信息(URL、用户名、密码和驱动程序),然后创建了两个 `SqlDataSource` 对象,分别用于连接 MySQL 和 Oracle 数据库。接着,我们使用 `Sql.newInstance` 方法来创建两个 `Sql` 对象,用于执行数据操作。最后,我们在 MySQL 数据库中插入了一条数据,然后在 Oracle 数据库中查询了一些数据。最后,我们使用 `close` 方法关闭了连接。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

taoli-qiao

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值