Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何同时插入和选择mysql_Java_Mysql_Sql_Jdbc - Fatal编程技术网

Java 如何同时插入和选择mysql

Java 如何同时插入和选择mysql,java,mysql,sql,jdbc,Java,Mysql,Sql,Jdbc,我有一个要求,我需要在mysql中插入手机号码,当且仅当该号码不存在时。为此,我首先使用select查询检查mysql中是否存在号码。如果该号码不存在,则插入。以下是我的代码 PreparedStatement pt1=con.prepareStatement("select * from registerSmsUsers where mobile='"+mobile+"'"); PreparedStatement pt=con.prepareStatement("insert into reg

我有一个要求,我需要在mysql中插入手机号码,当且仅当该号码不存在时。为此,我首先使用select查询检查mysql中是否存在号码。如果该号码不存在,则插入。以下是我的代码

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();}

我不知道这是否是一种有效的方法。请建议我一种比这更好的方法。我认为最好创建一个存储过程,然后在该存储过程中,您可以首先使用IF not EXISTS子句,使用select语句检查用户是否存在。如果用户不在场,则可以在数据库中插入该用户

大概是这样的:

IF NOT EXISTS(SELECT 1 FROM `registerSmsUsers` WHERE mobile= @mobile) THEN
    BEGIN
    INSERT INTO 
        `registerSmsUsers`
        (
            //column names
        ) 
        VALUES 
        (
            //values
        );
    END;
END IF;
insert ignore into registerSmsUsers values(?,?,?)
还有一条语句,您可以这样使用:

IF NOT EXISTS(SELECT 1 FROM `registerSmsUsers` WHERE mobile= @mobile) THEN
    BEGIN
    INSERT INTO 
        `registerSmsUsers`
        (
            //column names
        ) 
        VALUES 
        (
            //values
        );
    END;
END IF;
insert ignore into registerSmsUsers values(?,?,?)
这也是一个有效的方法来检查您的方法是否也工作良好,但这也是可以做到的 不同之处在于,这里只有一个查询 我希望这对你有帮助,谢谢

[编辑]

你的问题有答案


Ya您和我的查询之间存在执行时间差异取决于您使用的数据库大小如果您使用的是小型数据库可能有1000人,那么您将不会看到您的查询和我的查询之间存在任何差异,但是如果您使用的是10万用户,那么您将有一个性能问题检查,包括执行计划mysql您将获得两个之间的实时差异可能mysql中最简单的方法是:

insert ignore into registerSmsUsers values(?,?,?)
假设您在手机上有唯一的密钥

您可以在这里查看:


或者在这里:

许多建议的解决方案,包括您的解决方案,都有可能导致主键或唯一约束冲突的竞争条件。通过连接SQL而不是使用准备好的语句参数,您的代码还可能受到SQL注入攻击。使用“选择…”进行更新

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:添加了光标/结果集选项。

根据要求,以下是我对brettw答案的调整版本:

导入java.sql.*; 公共类MySQLtest{ 公共静态无效字符串[]args{ 连接con; 试一试{ con=DriverManager.getConnection jdbc:mysql://192.168.1.3/zzzTest? + useUnicode=yes&characterEncoding=UTF-8+ &user=root&密码=whatever; 字符串newName=Gord; 字符串newEmail=gord@example.com; 字符串newMobile=416-555-1212; 字符串sql= 挑选+ 身份证+ 名字+ 电子邮件+ 流动的+ 来自注册表MSUsers+ 移动设备=+ 更新; PreparedStatement pst=con.prepareStatement sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_可更新; pst.setString1,newMobile; 结果集rs=pst.executeQuery; 如果是下一个{ rs.moveToCurrentRow; rs.updateStringname,newName; rs.updateStringemail、newEmail; rs.updateRow; System.out.PRINTLN现有行已更新。; } 否则{ rs.moveToInsertRow; rs.updateStringname,newName; rs.updateStringemail、newEmail; rs.updateStringmobile、newMobile; rs.insertRow; System.out.PrintLn插入新行。; } }捕获SQLException-ex{ 例如,打印跟踪; } } }
请注意,id是表的主键:int11 NOT NULL AUTO_INCREMENT

谢谢您的回复,+1。那么它的jdbc代码是什么?@java初学者:-我想这对您会有帮助:-谢谢您的回答,+1谢谢你的帮助。你能告诉我如何知道上面的方法比我的方法好。我们能知道执行时间吗?或者如果不存在,我用这种方法做的任何事情吗?从registerSmsUsers where mobile='232323'->begin->insert into registerSmsUsers values?,?,?->终止错误是您的SQL语法有错误;查看与您的MySQL服务器版本对应的手册,了解要使用的正确语法,请在第1行的“if not exists select*from registerSmsUsers where mobile='232323'begin inse'附近查看您正在使用的版本?让我们知道它可能不是主键。但是这样使用它应该是唯一的键谢谢你的回答+1,我需要知道它以哪种方式快速。假设我有大约1000000条记录,那么插入一条记录时,它将检查1000000条。是的,如果registerSmsUsers已经创建了声明移动唯一,那么将有一个现有的索引,它应该非常有用
快速的当你发现这个答案有效时,请接受它。我发现你的答案很有用,所以已经对它进行了升级,请给我一些时间在我的应用程序中实现你的想法。这将是rs.setString1,name;rs.setString2,电子邮件;rs.setString3,移动式;rs.updateString而不是setString,对吗?我刚刚将您的代码复制到eclipse。在eclipse中,它给出了复制错误,并建议将rs.setString使用到rs.updateString。此错误显示在else循环中