Java 安卓&;SQL-SQL查询不断更新错误的列

Java 安卓&;SQL-SQL查询不断更新错误的列,java,php,android,mysql,wamp,Java,Php,Android,Mysql,Wamp,问题 我一直在尝试使用WAMP在本地数据库和MySQL数据库服务器之间创建同步。此同步以JSON格式发送数据库中的所有数据,并根据是否存在重复密钥插入或更新数据。之后,我从MySQL数据库中检索所有数据,清除应用程序创建的本地数据库,并将所有新数据存储在其中。但是,这并没有像我希望的那样起作用,因为我发送到数据库服务器的数据一直在覆盖具有不同键的列 文字示例 我有一个团队,两个数据库之间同步了密钥5024。我向本地数据库添加了一个带有3756键的新团队,然后尝试将本地数据库与MySQL数据库同步

问题
我一直在尝试使用WAMP在本地数据库和MySQL数据库服务器之间创建同步。此同步以JSON格式发送数据库中的所有数据,并根据是否存在重复密钥插入或更新数据。之后,我从MySQL数据库中检索所有数据,清除应用程序创建的本地数据库,并将所有新数据存储在其中。但是,这并没有像我希望的那样起作用,因为我发送到数据库服务器的数据一直在覆盖具有不同键的列

文字示例
我有一个团队,两个数据库之间同步了密钥5024。我向本地数据库添加了一个带有3756键的新团队,然后尝试将本地数据库与MySQL数据库同步。但是,同步并没有按计划进行,因为在大多数情况下,数据库不会插入带有键的新列。相反,它用发送给它的数据更新具有完全不同键的行

额外信息
有时,同步会按计划工作,并添加一个包含已发送信息的新列,但该数据会在下一次同步中被覆盖

示例JSON对象{“TeamNumber”:5024,“TeamName”:“Ramferno”,“AutoFuelow”:“是”,“AutoFuelHigh”:“否”,“AutoFuelPoints”:15,“AutoRotorEngaged”:“否”,“TeleFuelHigh”:“否”,“TeleFuelPoints”:20,“TeleRotorEngaged”:“是”,“Hang”:“是”,“PlayStyle”:“防御性”

WAMP服务器服务和语言
MySQL:5.7.14
PHP:5.6.25
Apache:2.4.23
PHPMyAdmin:4.6.6

数据的交付方式
我的android类从本地
SQLite
数据库检索数据,并将其存储在
游标
对象中。然后,它将遍历
光标中的每一行数据
,并将其传输到
JSONObject
,然后通过
BufferedWriter
发送到数据库服务器,只要存在连接(在每次同步时都建立了连接),它就可以访问输出流。数据库上的PHP脚本(在android类中连接到)获取所有信息,通过
$\u POST
对其进行解码,然后使用向数据库服务器发送一个
INSERT-in-DUPLICATE KEY
SQL查询,其中包含接收到的数据

我尝试过的事情

  • 增加延迟
  • 使用
    JSONArray
    只向数据库写入一次
  • 将表中的键作为主键或唯一键删除并重新添加
代码
java(从本地数据库发送数据的Android类)

package org.ramferno.ramfernoscouting2017.sql;
导入android.app.ProgressDialog;
导入android.content.ContentValues;
导入android.content.Context;
导入android.database.Cursor;
导入android.os.AsyncTask;
导入android.support.v4.app.Fragment;
导入android.util.Log;
导入android.widget.Toast;
导入org.json.JSONArray;
导入org.json.JSONException;
导入org.json.JSONObject;
导入org.ramferno.ramfernoscouting2017.LaunchActivity;
导入org.ramferno.ramfernoscouting2017.fragments.ScoutFragment;
导入java.io.BufferedInputStream;
导入java.io.BufferedReader;
导入java.io.BufferedWriter;
导入java.io.IOException;
导入java.io.InputStream;
导入java.io.InputStreamReader;
导入java.io.OutputStream;
导入java.io.OutputStreamWriter;
导入java.io.UnsupportedEncodingException;
导入java.net.HttpURLConnection;
导入java.net.MalformedURLException;
导入java.net.SocketTimeoutException;
导入java.net.URL;
导入java.net.urlcoder;
导入java.util.Iterator;
//开始数据库传输
@抑制警告({“FieldCanBeLocal”、“ConstantConditions”})
公共类数据库传输扩展异步任务{
//声明对象引用
私人语境;
私人对话;
私有片段;
//声明变量
私有字符串地址;
/**
*类的构造函数
*@param context是应用程序上下文
*@param urlAddress是具有可访问MySQL数据库的url地址
*/
公共数据库传输(上下文、字符串URL地址、片段){
this.context=上下文;
this.urlAddress=urlAddress;
this.fragment=片段;
}//构造函数的结尾
@凌驾
受保护的void onPreExecute(){
super.onPreExecute();
//显示对话框
pDialog=新建进度对话框(上下文);
setMessage(“同步数据…”);
pDialog.setUndeterminate(假);
pDialog.setCancelable(真);
pDialog.show();
}//方法结束
@凌驾
受保护的字符串doInBackground(字符串…args){
sendData();
getAndStoreData();
返回“真”;
}//方法结束
@凌驾
受保护的void onPostExecute(字符串s){
super.onPostExecute(s);
冲蚀碎片冲蚀碎片=(冲蚀碎片)碎片;
scoutFragment.refreshListView();
//制作土司,表明响应是否成功
Toast.makeText(上下文,s,Toast.LENGTH_LONG).show();
//取消对话框
pDialog.disclose();
}//方法结束
/**
*尝试与数据库服务器建立GET连接
*@返回连接对象
*/
私有HttpURLConnection attemptGetConnection(){
试一试{
//声明并实例化URL对象
URL URL=新URL(“http://“+urlAddress+”/ramfernoscout/database/retrieve.php”);
//开放连接
HttpURLConnection con=(HttpURLConnection)url.openConnection();
//设置请求属性
con.setRequestMethod(“GET”);
con.设置连接超时(20000);
con.设置读取超时(20000);
con.setDoInput(真);
//回路连接
package org.ramferno.ramfernoscouting2017.sql;

import android.app.ProgressDialog;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.os.AsyncTask;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.widget.Toast;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.ramferno.ramfernoscouting2017.LaunchActivity;
import org.ramferno.ramfernoscouting2017.fragments.ScoutFragment;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.SocketTimeoutException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.Iterator;

// Start of DatabaseTransfer
@SuppressWarnings({"FieldCanBeLocal", "ConstantConditions"})
public class DatabaseTransfer extends AsyncTask<String, String, String> {
    // Declare object references
    private Context context;
    private ProgressDialog pDialog;
    private Fragment fragment;

    // Declare variables
    private String urlAddress;

    /**
     * Constructor for the class
     * @param context is the application context
     * @param urlAddress is a url address with an accessible MySQL database
     */
    public DatabaseTransfer(Context context, String urlAddress, Fragment fragment) {
        this.context = context;
        this.urlAddress = urlAddress;
        this.fragment = fragment;
    } //End of constructor

    @Override
    protected void onPreExecute() {
        super.onPreExecute();

        // Display dialog
        pDialog = new ProgressDialog(context);
        pDialog.setMessage("Syncing Data ...");
        pDialog.setIndeterminate(false);
        pDialog.setCancelable(true);
        pDialog.show();
    } // End of method

    @Override
    protected String doInBackground(String... args) {
        sendData();
        getAndStoreData();
        return "true";
    } // End of method

    @Override
    protected void onPostExecute(String s) {
        super.onPostExecute(s);

        ScoutFragment scoutFragment = (ScoutFragment) fragment;
        scoutFragment.refreshListView();

        // Make toast which indicates if response was successful
        Toast.makeText(context, s, Toast.LENGTH_LONG).show();

        // Dismiss dialog
        pDialog.dismiss();
    } // End of method

    /**
     * Attempts a GET connection to a database server
     * @return a connection object
     */
    private HttpURLConnection attemptGetConnection() {
        try {
            // Declare and instantiate URL object
            URL url = new URL("http://" + urlAddress + "/ramfernoscout/database/retrieve.php");

            // Open connection
            HttpURLConnection con = (HttpURLConnection) url.openConnection();

            // Set request properties
            con.setRequestMethod("GET");
            con.setConnectTimeout(20000);
            con.setReadTimeout(20000);
            con.setDoInput(true);

            // Return connection
            return con;
        }
        catch (SocketTimeoutException errTO) {
            Log.e("ERROR TO", errTO.getMessage());
            return null;
        }
        catch (MalformedURLException errURL) {
            Log.e("ERROR URL", errURL.getMessage());
            return null;
        }
        catch (IOException errIO) {
            errIO.printStackTrace();
            return null;
        } // End of try statement
    } // End of method

    /**
     * Attempts a POST connection to a database server
     * @return a connection object
     */
    private HttpURLConnection attemptPostConnection() {
        try {
            URL url = new URL("http://" + urlAddress + "/ramfernoscout/database/updateadd.php");
            HttpURLConnection con = (HttpURLConnection) url.openConnection();

            // Set request properties
            con.setRequestMethod("POST");
            con.setConnectTimeout(20000);
            con.setReadTimeout(20000);
            con.setDoInput(true);
            con.setDoOutput(true);

            // Return connection
            return con;
        }
        catch (SocketTimeoutException errTO) {
            Log.e("ERROR TO", errTO.getMessage());
            return null;
        }
        catch (MalformedURLException errURL) {
            Log.e("ERROR URL", errURL.getMessage());
            return null;
        }
        catch (IOException errIO) {
            errIO.printStackTrace();
            return null;
        } // End of try statement
    } // End of method

    /**
     * Sends all data inside local database to database server
     * @return a response code as a string
     */
    @SuppressWarnings("static-access")
    private String sendData() {
        //Connect the server
        HttpURLConnection con = attemptPostConnection();

        //Check if connection was successful
        if(con == null) {
            return null;
        } //End of if statement

        // Attempt to insert data into the database
        try {
            // Declare and instantiate objects
            OutputStream os = con.getOutputStream();
            BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(os,"UTF-8"));
            final Cursor cursor = LaunchActivity.dbHelper.getData(LaunchActivity.dbHelper
                    .getReadableDatabase(), "*", 0);
            cursor.moveToFirst();

            // Iterate through the entire cursor and add data to database
            for (int i = 0; i < cursor.getCount(); i++) {
                // Write data to database server
                bw.write(packData(cursor));
                cursor.moveToNext();
            } // End of for loop

            // Close stream and writer
            bw.close();
            os.close();

            // Store response code in integer
            int responseCode = con.getResponseCode();

            // Check if data was successfully enter into the database
            if(responseCode == con.HTTP_OK) {
                // Declare and instantiate objects
                BufferedReader br = new BufferedReader(new InputStreamReader
                        (con.getInputStream()));
                StringBuilder response = new StringBuilder();
                String line;

                // Get full response
                while ((line=br.readLine()) != null) {
                    response.append(line);
                } // End of while statement

                // Close reader and return response
                br.close();
                return response.toString();
            } // End of if statement
        }
        catch (IOException errIO) {
            Log.e("ERROR IO", errIO.getMessage());
            errIO.printStackTrace();
        } //End of try statement
        return null;
    } // End of method

    /**
     * Packs database information into a string which can be sent to the database server
     * @param cursor is a Cursor object containing data
     * @return a string
     */
    private String packData(Cursor cursor) {
        //Declare and instantiate objects
        JSONObject jo = new JSONObject();
        StringBuilder packedData = new StringBuilder();

        // Attempt to send data to the server via JSON
        try {
            // Put all data in a json object
            jo.put(DatabaseContract.ScoutTable.TEAM_NUMBER, cursor.getInt(cursor
                    .getColumnIndexOrThrow(DatabaseContract.ScoutTable.TEAM_NUMBER)));
            jo.put(DatabaseContract.ScoutTable.TEAM_NAME, cursor.getString(cursor
                    .getColumnIndexOrThrow(DatabaseContract.ScoutTable.TEAM_NAME)));
            jo.put(DatabaseContract.ScoutTable.AUTO_FUEL_LOW, cursor.getString(cursor
                    .getColumnIndexOrThrow(DatabaseContract.ScoutTable.AUTO_FUEL_LOW)));
            jo.put(DatabaseContract.ScoutTable.AUTO_FUEL_HIGH, cursor.getString(cursor
                    .getColumnIndexOrThrow(DatabaseContract.ScoutTable.AUTO_FUEL_HIGH)));
            jo.put(DatabaseContract.ScoutTable.AUTO_FUEL_POINTS, cursor.getInt(cursor
                    .getColumnIndexOrThrow(DatabaseContract.ScoutTable.AUTO_FUEL_POINTS)));
            jo.put(DatabaseContract.ScoutTable.AUTO_ROTOR_ENGAGED, cursor.getString(cursor
                    .getColumnIndexOrThrow(DatabaseContract.ScoutTable.AUTO_ROTOR_ENGAGED)));
            jo.put(DatabaseContract.ScoutTable.TELE_FUEL_LOW, cursor.getString(cursor
                    .getColumnIndexOrThrow(DatabaseContract.ScoutTable.TELE_FUEL_LOW)));
            jo.put(DatabaseContract.ScoutTable.TELE_FUEL_HIGH, cursor.getString(cursor
                    .getColumnIndexOrThrow(DatabaseContract.ScoutTable.TELE_FUEL_HIGH)));
            jo.put(DatabaseContract.ScoutTable.TELE_FUEL_POINTS, cursor.getInt(cursor
                    .getColumnIndexOrThrow(DatabaseContract.ScoutTable.TELE_FUEL_POINTS)));
            jo.put(DatabaseContract.ScoutTable.TELE_ROTOR_ENGAGED, cursor.getString(cursor
                    .getColumnIndexOrThrow(DatabaseContract.ScoutTable.TELE_ROTOR_ENGAGED)));
            jo.put(DatabaseContract.ScoutTable.ENDGAME_HANG, cursor.getString(cursor
                    .getColumnIndexOrThrow(DatabaseContract.ScoutTable.ENDGAME_HANG)));
            jo.put(DatabaseContract.ScoutTable.PLAY_STYLE, cursor.getString(cursor
                    .getColumnIndexOrThrow(DatabaseContract.ScoutTable.PLAY_STYLE)));

            Log.e("Print JSON Object", jo.toString());

            // Declare and instantiate objects
            Boolean firstValue = true;
            Iterator it = jo.keys();

            // Organize data in JSON format
            do {
                // Go through each key and value in JSONObject
                String key = it.next().toString();
                String value = jo.get(key).toString();

                // Check if first value in the list
                if(firstValue) {
                    firstValue = false;
                }
                else {
                    packedData.append("&");
                } // End of if statement

                // Append to string in order to create JSON format
                packedData.append(URLEncoder.encode(key,"UTF-8"));
                packedData.append("=");
                packedData.append(URLEncoder.encode(value,"UTF-8"));
            } while (it.hasNext()); // End of do statement

            // Return packed data in string format
            return packedData.toString();
        }
        catch (JSONException errJSON) {
            // If occurs, log error
            Log.e("ERROR JSON", errJSON.getMessage());
        }
        catch (UnsupportedEncodingException errUEE) {
            // If occurs, log error
            Log.e("ERROR UEE", errUEE.getMessage());
        } // End of try statement

        // Return nothing
        return null;
    } // End of packData

    /**
     * Downloads data from the database server and stores it in local database
     */
    private String getAndStoreData() {
        // Attempt connection to server
        HttpURLConnection con = attemptGetConnection();

        // If no connection, return nothing
        if(con == null) {
            return "ERROR: Connection unsuccessful, please make sure you are properly connected " +
                    "to the right IP address which has access to the database server";
        } // End of if statement

        // Declare InputStream
        InputStream is = null;

        // Attempt to read the file of data
        try {
            // Declare and instantiate objects
            is = new BufferedInputStream(con.getInputStream());
            BufferedReader br = new BufferedReader(new InputStreamReader(is));
            StringBuilder response = new StringBuilder();

            // Declare object references
            String line;
            String responseString = "";

            // Read all lines of data until the end of the file is reached
            if(br != null) {
                while ((line = br.readLine()) != null) {
                    responseString += line;
                } //End of while statement

                // Add string to string builder
                response.append(responseString);

                // Close reader
                br.close();
            }
            else {
                throw new IOException();
            } //End of if statement

            // Declare and instantiate objects
            JSONArray jsonArray = new JSONArray(response.toString());
            JSONObject jsonObject;

            // Reset scout table
            LaunchActivity.dbHelper.onUpgrade(LaunchActivity.dbHelper.getWritableDatabase(), 0);

            // Iterate through JSON array and add each set to database
            for(int i = 0; i < jsonArray.length(); i++) {
                jsonObject = jsonArray.getJSONObject(i);

                // Store data in Content values
                ContentValues values = new ContentValues();
                values.put(DatabaseContract.ScoutTable.TEAM_NUMBER,
                        jsonObject.getInt(DatabaseContract.ScoutTable.TEAM_NUMBER));
                values.put(DatabaseContract.ScoutTable.TEAM_NAME,
                        jsonObject.getString(DatabaseContract.ScoutTable.TEAM_NAME));
                values.put(DatabaseContract.ScoutTable.AUTO_FUEL_LOW,
                        jsonObject.getString(DatabaseContract.ScoutTable.AUTO_FUEL_LOW));
                values.put(DatabaseContract.ScoutTable.AUTO_FUEL_HIGH,
                        jsonObject.getString(DatabaseContract.ScoutTable.AUTO_FUEL_HIGH));
                values.put(DatabaseContract.ScoutTable.AUTO_FUEL_POINTS,
                        jsonObject.getInt(DatabaseContract.ScoutTable.AUTO_FUEL_POINTS));
                values.put(DatabaseContract.ScoutTable.AUTO_ROTOR_ENGAGED,
                        jsonObject.getString(DatabaseContract.ScoutTable.AUTO_ROTOR_ENGAGED));
                values.put(DatabaseContract.ScoutTable.TELE_FUEL_LOW,
                        jsonObject.getString(DatabaseContract.ScoutTable.TELE_FUEL_LOW));
                values.put(DatabaseContract.ScoutTable.TELE_FUEL_HIGH,
                        jsonObject.getString(DatabaseContract.ScoutTable.TELE_FUEL_HIGH));
                values.put(DatabaseContract.ScoutTable.TELE_FUEL_POINTS,
                        jsonObject.getInt(DatabaseContract.ScoutTable.TELE_FUEL_POINTS));
                values.put(DatabaseContract.ScoutTable.TELE_ROTOR_ENGAGED,
                        jsonObject.getString(DatabaseContract.ScoutTable.TELE_ROTOR_ENGAGED));
                values.put(DatabaseContract.ScoutTable.ENDGAME_HANG,
                        jsonObject.getString(DatabaseContract.ScoutTable.ENDGAME_HANG));
                values.put(DatabaseContract.ScoutTable.PLAY_STYLE,
                        jsonObject.getString(DatabaseContract.ScoutTable.PLAY_STYLE));

                // Add data to database
                LaunchActivity.dbHelper.insert(LaunchActivity.dbHelper.getWritableDatabase(),
                        values, 0);
            } // End of for loop
        }
        catch (IOException errIO) {
            // If occurs, log error and return false
            Log.e("ERROR IO", errIO.getMessage());
            return "ERROR";
        }
        catch (JSONException errJSON) {
            // If occurs, log error and return false
            Log.e("ERROR JSON", errJSON.getMessage());
            return "ERROR";
        }
        finally {
            // Close input stream
            if(is != null) {
                try {
                    is.close();
                }
                catch (IOException e) {
                    e.printStackTrace();
                } // End of try statement
            } // End of if statement
        } // End of try statement

        // Return success message if no error occurs
        return "Sync successful!";
    } // End of method
} // End of class
<?php
/*
 * This script will add data into a database
 */

// Import the script that connects to the required database
require "init.php";

// Declare and initialize parameters (These parameters will have data entered into them by the android app)
$teamNumber = $_POST['TeamNumber'];
$teamName = $_POST['TeamName'];
$autoFuelLow = $_POST['AutoFuelLow'];
$autoFuelHigh = $_POST['AutoFuelHigh'];
$autoFuelPoints = $_POST['AutoFuelPoints'];
$autoRotorEngaged = $_POST['AutoRotorEngaged'];
$teleFuelLow = $_POST['TeleFuelLow'];
$teleFuelHigh = $_POST['TeleFuelHigh'];
$teleFuelPoints = $_POST['TeleFuelPoints'];
$teleRotorEngaged = $_POST['TeleRotorEngaged'];
$endgame = $_POST['Hang'];
$playStyle = $_POST['PlayStyle'];

// This query inserts data into the database
$sql_query = "INSERT INTO scoutdb (TeamNumber, TeamName, AutoFuelLow, AutoFuelHigh, AutoFuelPoints, AutoRotorEngaged, TeleFuelLow, TeleFuelHigh, TeleFuelPoints, TeleRotorEngaged, Hang, PlayStyle) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) ON DUPLICATE KEY UPDATE TeamName=VALUES(TeamName), AutoFuelLow=VALUES(AutoFuelLow), AutoFuelHigh=VALUES(AutoFuelHigh), AutoFuelPoints=VALUES(AutoFuelPoints), AutoRotorEngaged=VALUES(AutoRotorEngaged), TeleFuelLow=VALUES(TeleFuelLow), TeleFuelHigh=VALUES(TeleFuelHigh), TeleFuelPoints=VALUES(TeleFuelPoints), TeleRotorEngaged=VALUES(TeleRotorEngaged), Hang=VALUES(Hang), PlayStyle=VALUES(PlayStyle);";

// Prepare the SQL statement
if(!($stmt = $con->prepare($sql_query))) {
    echo "Statement could no be prepared: (".$con->errno.") ".$con->error;
} // End of if statement

// Bind parameters to the statement
if(!($stmt->bind_param("isssisssisss", $teamNumber, $teamName, $autoFuelLow, $autoFuelHigh, $autoFuelPoints,
    $autoRotorEngaged, $teleFuelLow, $teleFuelHigh, $teleFuelPoints, $teleRotorEngaged, $endgame, $playStyle))) {
    // Display a message if an error occurs when binding
    echo "Data could not be binded: (".$stmt->errno.") ".$stmt->error;;
} // End of if statement

// Execute statement
if (!($stmt->execute())) {
    // Display a message if an error occurs when executing
    echo "Execute failed: (".$stmt->errno.") ".$stmt->error;
} // End of if statement
?>