scala 操作mysql

依赖库

scala 和 Java 操作mysql一样,依赖mysql-connector-java

添加依赖库

<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.49</version>
</dependency>

连接数据库

//连接mysql
val host="localhost"
val port=3306
val database="test"
val jdbcUrl=s"jdbc:mysql://$host:$port/$database?useUnicode=true&characterEncoding=utf-8"
val mysqlConn: Connection = DriverManager.getConnection(jdbcUrl, "root", "123")

Statement和PreparedStatement

在操作mysql数据库的时候,有两个接口,一个是Statement,另一个是PreparedStatement

StatementPreparedStatement都是用于执行SQL语句的句柄,但是PreparedStatement代表的是一个预编译的SQL。这两种对象的主要区别体现在以下三个方面

  1. 使用方面的区别:Statement执行的sql语句必须是完整的SQL语句,而对于PreparedStatement来说,可以使用?进行占位。然后使用PreparedStatementsetxxx()方法来给占位符赋值,最后再执行。

  2. 在使用Statement时,如果SQL语句中出现'或者-时,需要使用转义字符来进行转义,而在PreparedStatement中,如果使用占位符来进行赋值,当赋值中出现这些符号,PreparedStatement会自动进行转义。

  3. PreparedStatement会将SQL语句进行预编译,每次执行的时候只需要将参数设置给相应的占位符就可以运行。而使用Statement时,SQL语句每次都需要编译一次,所以相对来说PreparedStatment的效率会高一点。

Statement

Statement在执行SQL语句的时候有三个方法:executeQuery,executeUpdate,execute

  • executeQuery:用于产生单个结果集的语句,例如select语句
  • executeUpdate:用于执行insertupdatedeleteSQLDDL(数据定义语言),例如showaltercreatedrop等。executeUpdate 的返回值是一个整数,指示受影响的行数(即更新计数)。对于CREATE TABLE 或 DROP TABLE 等不操作行的语句,executeUpdate 的返回值总为零。
  • execute:用于执行返回多个结果集、多个更新计数或二者组合的语句

查询数据

val statement: Statement = mysqlConn.createStatement()
val result: ResultSet =statement.executeQuery("select * from article")
while (result.next()){
  println(result.getInt("title"),result.getString("content"))
}

result.close()
statement.close()

/**
 * 输出
 * (1,aaa)
 * (2,bbb)
 * (3,ccc)
 * (4,ddd)
 */

在执行完查询语句的时候返回的是一个ResultSetResultSet返回的实际就是一张数据表,有一个指针指向数据表的第一行的前面,可以调用next()方法检测下一行是否有效。

若有效该方法返回true,且指针下移,相当于Iterator对象的hasNext()next()方法的结合体,当指针定位到一行时,可以调用getXXX(index)或者getXXX(columName)获取每一列的值。在使用``getXXX(index)`获取数据时,索引从1开始。

Statement对象将由 Java 垃圾收集程序自动关闭,ResultSet当然也需要关闭,。而作为一种好的编程风格,应在不需要 Statement对象时显式地关闭它们。这将立即释放 DBMS 资源,有助于避免潜在的内存问题。

PreparedStatement

PreparedStatementStatement一样,拥有executeQuery,executeUpdate,execute三个方法。

PreparedStatement在执行executeQuery等方法的时候不需要传入sql语句,如果传入了SQL语句,会隐式调用Statement接口的方法。

查询数据

val sql="select * from article"

val ps: PreparedStatement = mysqlConn.prepareStatement(sql)
val result: ResultSet =ps.executeQuery()
while (result.next()){
  println(result.getString("title"),result.getString("content"))
}

/**
 * 输出:
 * (1,aaa)
 * (2,bbb)
 * (3,ccc)
 * (4,ddd)
 */

插入数据

在插入数据的时候,我们可以使用?占位符对sql语句进行预编译,然后使用setxxx()进行赋值。

在对sql语句中的占位符进行赋值的时候,索引是从1开始的。

val sql="insert into article(title,content) values(?,?)"
val instertPreparedStatement: PreparedStatement =mysqlConn.prepareStatement(sql)
instertPreparedStatement.setString(1,"newtitle")
instertPreparedStatement.setString(2,"newContent")
instertPreparedStatement.executeUpdate()

PrdparedStatement示例完整代码:

  def main(args: Array[String]): Unit = {

    //连接mysql
    val host="localhost"
    val port=3306
    val database="test"
    val jdbcUrl=s"jdbc:mysql://$host:$port/$database?useUnicode=true&characterEncoding=utf-8"
    val mysqlConn: Connection = DriverManager.getConnection(jdbcUrl, "root", "123")

    //插入数据
    val sql="insert into article(title,content) values(?,?)"
    val instertPreparedStatement: PreparedStatement =mysqlConn.prepareStatement(sql)
    instertPreparedStatement.setString(1,"newtitle")
    instertPreparedStatement.setString(2,"newContent")
    instertPreparedStatement.executeUpdate()

    //查询数据
    val selectSql="select * from article"
    val selectPreparedStatement: PreparedStatement = mysqlConn.prepareStatement(selectSql)
    val result: ResultSet =selectPreparedStatement.executeQuery()
    while (result.next()){
      println(result.getString("title"),result.getString("content"))
    }
  }