我有一个要求,我需要在mysql中插入手机号码,当且仅当号码不存在时。为此,我首先检查mysql中是否存在使用select查询的号码。如果号码不存在然后插入。以下是我的代码
PreparedStatement pt1=con.prepareStatement("select * from registerSmsUsers where mobile='"+mobile+"'");
PreparedStatement pt=con.prepareStatement("insert into registerSmsUsers values(?,?,?)");
pt.setString(1, name);
pt.setString(2, email);
pt.setString(3, mobile);
ResultSet rs1=pt1.executeQuery();
if(rs1.next())
{pt.executeUpdate();}
我不知道这是否是一种有效的方法。请给我一个更好的方法然后这个
答案 0 :(得分:2)
可能是mysql中最简单的方法是:
insert ignore into registerSmsUsers values(?,?,?)
假设您在移动设备上有唯一的密钥
答案 1 :(得分:2)
许多提议的解决方案(包括您的解决方案)都存在可能导致主键或唯一约束违规的竞争条件。您的代码也可能通过连接SQL而不是使用预准备语句参数来进行SQL注入攻击。使用SELECT ... FOR UPDATE。
PreparedStatement ps = con.prepareStatement("SELECT name, email, mobile FROM registerSmsUsers WHERE mobile=? FOR UPDATE",
ResultSet.TYPE_FORWARD_ONLY,
ResultSet.CONCUR_UPDATABLE);
ps.setString(1, mobile);
ResultSet rs = ps.executeQuery();
if (rs.next()) { // it exists already
rs.moveToCurrentRow();
rs.updateString(3, mobile);
rs.updateRow();
} else { // it does NOT exist
rs.moveToInsertRow();
rs.updateString(1, name);
rs.updateString(2, email);
rs.updateString(3, mobile);
rs.insertRow();
}
rs.close();
ps.close();
编辑:请确保您在registerSmsUsers上有索引。
CREATE INDEX registerSmsUsers_mobile_ndx ON registerSmsUsers(mobile)
或唯一的约束(隐式创建索引):
ALTER TABLE registerSmsUsers ADD CONSTRAINT registerSmsUsers_mobile_unq UNIQUE (mobile)
使用索引,即使有数百万条记录,更新/插入也基本上是即时的。
EDIT2:添加了光标/结果集选项。
答案 2 :(得分:1)
我认为创建存储过程会更好,然后在该存储过程中,您可以首先使用IF NOT EXISTS
子句使用select
语句检查用户是否存在。如果用户不在,您可以insert
数据库中的用户。
这样的事情:
IF NOT EXISTS(SELECT 1 FROM `registerSmsUsers` WHERE mobile= @mobile) THEN
BEGIN
INSERT INTO
`registerSmsUsers`
(
//column names
)
VALUES
(
//values
);
END;
END IF;
还有一个INSERT IGNORE语句可以像这样使用:
insert ignore into registerSmsUsers values(?,?,?)
答案 3 :(得分:1)
if not exists(select * from registerSmsUsers where mobile='232323') <-- will check your mobile no
begin
insert into registerSmsUsers values(?,?,?)
end
这个也是一种有效的方法来检查你的方法也工作正常,但这也可以做到 看到区别是你在这里只有一个查询 我希望这会对你有所帮助
[编辑]
您的问题回答
是否在您和我的查询之间存在执行 time diff ,这取决于数据库大小如果您使用的是小型数据库(可能是1000人)然后你不会在你的查询和我的查询之间看到任何差异,但是如果你正在使用十万用户那么你将有一个性能问题检查包括在mysql中执行计划你会得到两个实时差异< / p>
答案 4 :(得分:1)
根据要求,这是我调整的brettw的答案:
import java.sql.*;
public class MySQLtest {
public static void main(String[] args) {
Connection con;
try {
con = DriverManager.getConnection(
"jdbc:mysql://192.168.1.3/zzzTest?" +
"useUnicode=yes&characterEncoding=UTF-8" +
"&user=root&password=whatever");
String newName = "Gord";
String newEmail = "gord@example.com";
String newMobile = "416-555-1212";
String sql =
"SELECT " +
"id, " +
"name, " +
"email, " +
"mobile " +
"FROM registerSmsUsers " +
"WHERE mobile = ? " +
"FOR UPDATE";
PreparedStatement pst = con.prepareStatement(
sql,
ResultSet.TYPE_FORWARD_ONLY,
ResultSet.CONCUR_UPDATABLE);
pst.setString(1, newMobile);
ResultSet rs = pst.executeQuery();
if (rs.next()) {
rs.moveToCurrentRow();
rs.updateString("name", newName);
rs.updateString("email", newEmail);
rs.updateRow();
System.out.println("Existing row updated.");
}
else {
rs.moveToInsertRow();
rs.updateString("name", newName);
rs.updateString("email", newEmail);
rs.updateString("mobile", newMobile);
rs.insertRow();
System.out.println("New row inserted.");
}
} catch (SQLException ex) {
ex.printStackTrace();
}
}
}
请注意,id
是表格的主键:int(11) NOT NULL AUTO_INCREMENT