10.3 java_10.3:Java:JDBC插入

[TOC]

## JDBC插入

数据库操作总结起来就四个字:增删改查,行话叫CRUD:Create,Retrieve,Update和Delete。

插入操作是`INSERT`,即插入一条新记录。通过JDBC进行插入,本质上也是用`PreparedStatement`执行一条SQL语句,不过最后执行的不是`executeQuery()`,而是`executeUpdate()`。示例代码如下:

```

package day07;

import org.apache.log4j.Logger;

import java.io.File;

import java.io.FileInputStream;

import java.io.InputStream;

import java.sql.*;

import java.util.Properties;

public class day02jdbc {

// 日志

private static Logger logger = Logger.getLogger(day02jdbc.class);

// 配置文件

private static String JDBC_MYSQL(String jdbcPATH,String jdbcData) throws Exception{

Properties properties = new Properties();

InputStream iStream = new FileInputStream(new File(jdbcPATH));

properties.load(iStream);

String str = properties.getProperty(jdbcData);

return str;

}

// mysql操作

private static String MYSQL() throws Exception {

Statement stmt = null;

String DB_URL = JDBC_MYSQL("src/day07/jdbcmysql.properties","jdbc.DB_URL");

String USER = JDBC_MYSQL("src/day07/jdbcmysql.properties","jdbc.USER");

String PASS = JDBC_MYSQL("src/day07/jdbcmysql.properties","jdbc.PASS");

String JDBC_DRIVER = JDBC_MYSQL("src/day07/jdbcmysql.properties","jdbc.JDBC_DRIVER");

try {

logger.info(Class.forName(JDBC_DRIVER));

Connection conn = DriverManager.getConnection(DB_URL,USER,PASS);

logger.info(conn);

String sql = "INSERT INTO gin_user(id,name,age,money,Department_id,bonus) values(?,?,?,?,?,?)";

PreparedStatement pr = conn.prepareStatement(sql);

pr.setObject(1,25); // id

pr.setObject(2,"linda"); // name

pr.setObject(3,21); // age

pr.setDouble(4,3492.40); // money

pr.setObject(5,2390);

pr.setObject(6,123);

logger.info(pr);

int res = pr.executeUpdate();

if (res > 0) {

logger.info(res);

System.out.println("insert success.");

} else {

System.out.println("insert faild.");

}

pr.close();

conn.close();

} catch (Exception e) {

System.out.println(e.getMessage());

}

return null;

}

public static void main(String args[]) throws Exception{

MYSQL();

}

}

```

```

public static void main(String args[]) throws Exception{

// MYSQL();

String DB_URL = JDBC_MYSQL("src/day07/jdbcmysql.properties","jdbc.DB_URL");

String USER = JDBC_MYSQL("src/day07/jdbcmysql.properties","jdbc.USER");

String PASS = JDBC_MYSQL("src/day07/jdbcmysql.properties","jdbc.PASS");

String JDBC_DRIVER = JDBC_MYSQL("src/day07/jdbcmysql.properties","jdbc.JDBC_DRIVER");

try (Connection conn = DriverManager.getConnection(DB_URL, USER, PASS)) {

try (PreparedStatement pr = conn.prepareStatement(

"INSERT INTO gin_user(id,name,age,money,Department_id,bonus) values(?,?,?,?,?,?)")) {

pr.setObject(1,26); // id

pr.setObject(2,"kkxi"); // name

pr.setObject(3,23); // age

pr.setDouble(4,1492.40); // money

pr.setObject(5,2590);

pr.setObject(6,133);

int n = pr.executeUpdate(); // 1

}

}

}

}

```

设置参数与查询是一样的,有几个`?`占位符就必须设置对应的参数。虽然`Statement`也可以执行插入操作,但我们仍然要严格遵循*绝不能手动拼SQL字符串*的原则,以避免安全漏洞。

当成功执行`executeUpdate()`后,返回值是`int`,表示插入的记录数量。此处总是`1`,因为只插入了一条记录。

## 插入并获取主键

如果数据库的表设置了自增主键,那么在执行`INSERT`语句时,并不需要指定主键,数据库会自动分配主键。对于使用自增主键的程序,有个额外的步骤,就是如何获取插入后的自增主键的值。

要获取自增主键,不能先插入,再查询。因为两条SQL执行期间可能有别的程序也插入了同一个表。获取自增主键的正确写法是在创建`PreparedStatement`的时候,指定一个`RETURN_GENERATED_KEYS`标志位,表示JDBC驱动必须返回插入的自增主键。示例代码如下:

```

public static void main(String args[]) throws Exception {

// MYSQL();

String DB_URL = JDBC_MYSQL("src/day07/jdbcmysql.properties", "jdbc.DB_URL");

String USER = JDBC_MYSQL("src/day07/jdbcmysql.properties", "jdbc.USER");

String PASS = JDBC_MYSQL("src/day07/jdbcmysql.properties", "jdbc.PASS");

String JDBC_DRIVER = JDBC_MYSQL("src/day07/jdbcmysql.properties", "jdbc.JDBC_DRIVER");

try (Connection conn = DriverManager.getConnection(DB_URL, USER, PASS)) {

try (PreparedStatement pr = conn.prepareStatement(

"INSERT INTO gin_user(id,name,age,money,Department_id,bonus) values(?,?,?,?,?,?)",

Statement.RETURN_GENERATED_KEYS)) {

pr.setObject(1, 27); // id

pr.setObject(2, "mmc"); // name

pr.setObject(3, 25); // age

pr.setDouble(4, 9821.40); // money

pr.setObject(5, 3922);

pr.setObject(6, 102);

int n = pr.executeUpdate(); // 1

try (ResultSet rs = pr.getGeneratedKeys()) {

if (rs.next()) {

long id = rs.getLong(1); // 注意:索引从1开始

}

}

}

}

}

```

观察上述代码,有两点注意事项:

一是调用`prepareStatement()`时,第二个参数必须传入常量`Statement.RETURN_GENERATED_KEYS`,否则JDBC驱动不会返回自增主键;

二是执行`executeUpdate()`方法后,必须调用`getGeneratedKeys()`获取一个`ResultSet`对象,这个对象包含了数据库自动生成的主键的值,读取该对象的每一行来获取自增主键的值。如果一次插入多条记录,那么这个`ResultSet`对象就会有多行返回值。如果插入时有多列自增,那么`ResultSet`对象的每一行都会对应多个自增值(自增列不一定必须是主键)。

## 更新

更新操作是`UPDATE`语句,它可以一次更新若干列的记录。更新操作和插入操作在JDBC代码的层面上实际上没有区别,除了SQL语句不同:

```

try (Connection conn = DriverManager.getConnection(JDBC_URL, JDBC_USER, JDBC_PASSWORD)) {

try (PreparedStatement ps = conn.prepareStatement("UPDATE students SET name=? WHERE id=?")) {

ps.setObject(1, "Bob"); // 注意:索引从1开始

ps.setObject(2, 999);

int n = ps.executeUpdate(); // 返回更新的行数

}

}

```

`executeUpdate()`返回数据库实际更新的行数。返回结果可能是正数,也可能是0(表示没有任何记录更新)。

### 删除

删除操作是`DELETE`语句,它可以一次删除若干列。和更新一样,除了SQL语句不同外,JDBC代码都是相同的:

~~~

try (Connection conn = DriverManager.getConnection(JDBC_URL, JDBC_USER, JDBC_PASSWORD)) {

try (PreparedStatement ps = conn.prepareStatement("DELETE FROM students WHERE id=?")) {

ps.setObject(1, 999); // 注意:索引从1开始

int n = ps.executeUpdate(); // 删除的行数

}

}

~~~

### 小结

使用JDBC执行`INSERT`、`UPDATE`和`DELETE`都可视为更新操作;

更新操作使用`PreparedStatement`的`executeUpdate()`进行,返回受影响的行数。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值