根据时间过滤器从sqlite中获取数据

get the data from sqlite based on time filter

我正在开发显示表单数据列表的应用程序,我正在该列表中添加一个过滤器按钮,它根据源部门和日期(从日期 1 到日期 2)等各种过滤器来过滤数据。 我的部门和源过滤器工作正常,但当我 select 日期时什么也得不到。

sqlite 中的日期以整数格式存储,我正在尝试比较来自 sqlite 的日期和来自用户的日期。但它什么也没显示。

数据库助手class

public class DbHelper extends SQLiteOpenHelper {

    public static final int DATABASE_VERSION = 13;
    public static final String DATABASE_NAME = "LoinReg.db";

    public DbHelper(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
       db.execSQL(SQL_CREATE_REG_ENTRIES);
       db.execSQL(SQL_CREATE_FORM_ENTRIES);
       db.execSQL(SQL_ADD_HISTORY);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

        if(newVersion > oldVersion){
            db.execSQL(SQL_REG_DELETE_ENTRIES);
            db.execSQL(SQL_FORM_DELETE);
            db.execSQL(SQL_HISTORY_DELETE);
            onCreate(db);
         }
    }

    private static final String SQL_CREATE_FORM_ENTRIES =
            "CREATE TABLE IF NOT EXISTS " + FormEntry.COLUMN_TABLE_NAME +
                    " (" + FormEntry._ID + " INTEGER PRIMARY KEY AUTOINCREMENT,"
                    + FormEntry.COLUMN_NAME_NAME + " TEXT,"
                    + FormEntry.COLUMN_NAME_EMAIL + " TEXT,"
                    + FormEntry.COLUMN_NAME_MOBILE + " TEXT,"
                    + FormEntry.COLUMN_NAME_ALTERNATE_NUMBER + " TEXT,"
                    + FormEntry.COLUMN_NAME_JEE + " TEXT,"
                    + COLUNM_NAME_JEERANK + " TEXT,"
                    + FormEntry.COLUMN_NAME_PERCENTAGE + " TEXT,"
                    + FormEntry.COLUMN_NAME_CITY + " TEXT,"
                    + FormEntry.COLUMN_NAME_DEPT + " TEXT,"
                    + FormEntry.COLUMN_NAME_SOURCE + " TEXT,"
                    + FormEntry.TIMESTAMP + " INTEGER )";
 public boolean insertForm(String name, String email, String phone, String alternate, String jee, String jeeRank, String percentage, String city, String dept, String source){
        SQLiteDatabase db = this.getWritableDatabase();

        ContentValues values = new ContentValues();
        values.put(FormContract.FormEntry.COLUMN_NAME_NAME,name);
        values.put(FormContract.FormEntry.COLUMN_NAME_EMAIL,email);
        values.put(FormContract.FormEntry.COLUMN_NAME_MOBILE,phone);
        values.put(FormContract.FormEntry.COLUMN_NAME_ALTERNATE_NUMBER, alternate);
        values.put(FormContract.FormEntry.COLUMN_NAME_JEE,jee);
        values.put(FormContract.FormEntry.COLUNM_NAME_JEERANK,jeeRank);
        values.put(FormContract.FormEntry.COLUMN_NAME_PERCENTAGE,percentage);
        values.put(FormContract.FormEntry.COLUMN_NAME_CITY,city);
        values.put(FormContract.FormEntry.COLUMN_NAME_DEPT,dept);
        values.put(FormContract.FormEntry.COLUMN_NAME_SOURCE,source);
        values.put(FormEntry.TIMESTAMP,System.currentTimeMillis());

        long newRowId = db.insert(FormContract.FormEntry.COLUMN_TABLE_NAME,null,values);

        if(newRowId == -1){
            return false;
        }else{
            return true;
        }
}
}

MainActivity.java

public class MainActivity extends AppCompatActivity
        implements NavigationView.OnNavigationItemSelectedListener, EnquiryAdapter.OnItemClickListener {

    DbHelper mDbHelper;
    public static final String FORM_ID = "form_id";
    public static final String SQL = "sql";
    public static final String DEPT = "dept";
    public static final String SOURCE = "source";
    public static final String STARTDATE = "start_date";
    public static final String ENDDATE = "end_date";
    private static String sql, department, source;
    long StartDate, EndDate;


    private RecyclerView mRecyclerView;
    private EnquiryAdapter mAdapter;
   private EditText mStartDate, mEndDate;
    private Spinner mDeptSpinner, mSourceSpinner;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        mDbHelper = new DbHelper(this);


        FloatingActionButton fab = findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
               Intent intent = new Intent(MainActivity.this,FormActivity.class);
               startActivity(intent);
            }
        });

        DrawerLayout drawer = findViewById(R.id.drawer_layout);
        ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
                this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
        drawer.addDrawerListener(toggle);
        toggle.syncState();

        NavigationView navigationView = findViewById(R.id.nav_view);
        navigationView.setNavigationItemSelectedListener(this);
        View headerView = navigationView.getHeaderView(0);

        Intent intent = getIntent();
        String email = intent.getStringExtra(LoginActivity.EXTRA_EMAIL);
        TextView mEmail = headerView.findViewById(R.id.email);
        mEmail.setText(email);

        //RecyclerView Setup
        mRecyclerView = findViewById(R.id.recyclerview);
        mRecyclerView.setHasFixedSize(true);
        mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
        mAdapter = new EnquiryAdapter(MainActivity.this,mDbHelper.getFormData());
        mRecyclerView.setAdapter(mAdapter);
        mAdapter.setOnItemClickListener(MainActivity.this);
   }
private void showFilterDialog(){

        LayoutInflater layoutInflater = LayoutInflater.from(MainActivity.this);
        View filterDialog = layoutInflater.inflate(R.layout.filters,null);

        /**
         * getting the reference to the @View
         * */
        mStartDate = filterDialog.findViewById(R.id.editText);
        mEndDate = filterDialog.findViewById(R.id.editText2);
        mDeptSpinner = filterDialog.findViewById(R.id.filter_dept);
        mSourceSpinner = filterDialog.findViewById(R.id.filter_source);

        AlertDialog.Builder alertBuilder = new AlertDialog.Builder(MainActivity.this);
        alertBuilder.setTitle("Filters");
        alertBuilder.setView(filterDialog);


        mStartDate.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                showDatePicker(v);
                hideKeyboard(v);

            }
        });

        mEndDate.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                showEndDatePicker(v);
                hideKeyboard(v);
            }
        });

        /**
         * Assigning the list of items to the @Spinner.
         * */
        ArrayAdapter<CharSequence> deptAdapter = ArrayAdapter.createFromResource(this,R.array.Department,android.R.layout.simple_spinner_dropdown_item);
        deptAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        mDeptSpinner.setAdapter(deptAdapter);

        ArrayAdapter<CharSequence> sourceAdapter = ArrayAdapter.createFromResource(this,R.array.Source,android.R.layout.simple_spinner_dropdown_item);
        sourceAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        mSourceSpinner.setAdapter(sourceAdapter);

        /**
         * @sql statement.
         * */
        sql = "Select * from " +FormEntry.COLUMN_TABLE_NAME+ " where ";


        alertBuilder.setPositiveButton("Apply", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {

                Log.d("Date in milisec", String.valueOf(StartDate));
                Log.d("Date 2 in milisec", String.valueOf(EndDate));

                if(sd != null && ed != null){


                    sql = sql + FormEntry.TIMESTAMP+ " BETWEEN" + " ?" + " AND" + " ?";
                }else{
                    sql = "Select * from " +FormEntry.COLUMN_TABLE_NAME+ " where ";
                }

                department = mDeptSpinner.getSelectedItem().toString();
                source = mSourceSpinner.getSelectedItem().toString();

                if(mDeptSpinner.getSelectedItem() != null){
                    sql = sql + FormEntry.COLUMN_NAME_DEPT + " = ?";
                }

                if(mSourceSpinner.getSelectedItem() != null){
                    sql = sql + " OR "+ FormEntry.COLUMN_NAME_SOURCE + " = ?";
                }

                Intent intent = new Intent(MainActivity.this, FilterActivity.class);


               intent.putExtra(STARTDATE, StartDate);
               intent.putExtra(ENDDATE, EndDate);
                intent.putExtra(DEPT,department);
                intent.putExtra(SOURCE, source);
                intent.putExtra(SQL,sql);

                startActivity(intent);
            }
        })
        .setNegativeButton("Cancel",
                        new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog, int id) {
                                dialog.cancel();
                            }
                        });

        AlertDialog alertDialog = alertBuilder.create();
        alertDialog.show();
        Button pos = alertDialog.getButton(DialogInterface.BUTTON_POSITIVE);
        pos.setTextColor(Color.BLUE);
        Button neg = alertDialog.getButton(DialogInterface.BUTTON_NEGATIVE);
        neg.setTextColor(Color.BLUE);
    }
    public void showDatePicker(View view) {
        DialogFragment newFragment = new DateFragment();
        newFragment.show(getSupportFragmentManager(),"datePicker");
    }
    public void showEndDatePicker(View v){
        DialogFragment dialogFragment = new EndDateFragment();
        dialogFragment.show(getSupportFragmentManager(),"End Date");
    }
    public void processDatePickerResult(int year,int month,int day){
        String month_string = Integer.toString(month +1);
        String day_string = Integer.toString(day);
        String year_string = Integer.toString(year);
        String dateMessage = (year_string + "-" + month_string +
                "-" + day_string);
        mStartDate.setText(dateMessage);
        StartDate = getTimeInMillis(day,month,year);

    }
    public void processEndDatePickerResult(int year, int month, int day){
        String month_string = Integer.toString(month + 1);
        String day_string  = Integer.toString(day);
        String year_String = Integer.toString(year);
        String dateMessage = (year_String + "-" + month_string +
                "-" + day_string);
        mEndDate.setText(dateMessage);
        EndDate = getTimeInMillis(day,month,year);
    }

    private void hideKeyboard(View view){
        InputMethodManager imm = (InputMethodManager) getSystemService(Activity.INPUT_METHOD_SERVICE);
        imm.hideSoftInputFromWindow(view.getWindowToken(), 0);

    }

    public static long getTimeInMillis(int day, int month, int year) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(year, month, day);
        return calendar.getTimeInMillis();
    }
}

FilterActivity.java

public class FilterActivity extends AppCompatActivity implements EnquiryAdapter.OnItemClickListener {
    private RecyclerView mRecyclerView;
    private EnquiryAdapter mAdapter;
    private DbHelper mDbHelper;
    public static final String FORM_ID = "form_id";


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_filter);

        mRecyclerView = findViewById(R.id.filter_recyclerview);
        mDbHelper = new DbHelper(this);


        SQLiteDatabase db = mDbHelper.getReadableDatabase();

        Intent intent = getIntent();
        intent.getExtras();

        String sql = intent.getStringExtra(MainActivity.SQL);
       String dept = intent.getStringExtra(MainActivity.DEPT);
       String source = intent.getStringExtra(MainActivity.SOURCE);
      long startDate = intent.getIntExtra(MainActivity.STARTDATE,0);
      long endDate = intent.getIntExtra(MainActivity.ENDDATE,0);


        Cursor cursor = db.rawQuery(sql,new String[]{String.valueOf(startDate), String.valueOf(endDate), dept, source});

        mAdapter = new EnquiryAdapter(FilterActivity.this, cursor);

        //RecyclerView Setup
        mRecyclerView.setHasFixedSize(true);
        mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
        //mAdapter = new EnquiryAdapter(FilterActivity.this,mDbHelper.getFormData());
        mRecyclerView.setAdapter(mAdapter);
        mAdapter.setOnItemClickListener(FilterActivity.this);
    }
    @Override
    public void onItemClick(int position) {
        Intent intent = new Intent(this, DetailedActivity.class);
        int id = EnquiryAdapter.id;
        intent.putExtra(FORM_ID,id);
        startActivity(intent);
    }
}

您的问题似乎是 BETWEEN 子句和生成的 SQL 中 WHERE 子句的其他部分没有逻辑连接

如果变量sded都不为空(在代码,前提是它们似乎没有被声明或实例化),因此 SQL 将包含 BETWEEN 子句,不会有 AND 或 OR(我猜前者是必需的)。因此,通过 Intent Extra 传递的 SQL 将遵循 :-

SELECT * FROM your_table WHERE your_timestamp_column BETWEEN ? AND ? your_dept_column = ? OR your_source_column = ?

虽然它应该是(假设 AND):-

SELECT * FROM your_table WHERE your_timestamp_column BETWEEN ? AND ? 
    AND ( -- <<<<<<<<<<<< MISSING CONJUNCTION
        your_dept_column = ? OR your_source_column = ?
    )
  • 其中 your_table、your_timestamp_column、your_dept_column 和 your_source_column 是从您的变量解析的标识符。

我猜你的代码可能是这样的:-

            String time_filter_end_char = ""; //<<<<<<<<<< NO ) at end if no time_filter
            String sd = String.valueOf(StartDate); //<<<<<<<<<< ?????????
            String ed = String.valueOf(EndDate); //<<<<<<<<<< ??????????
            if(sd != null && ed != null && sd.length() >  0 && ed.length() > 0 ){
                time_filter_end_char = ")";
                sql = sql + FormEntry.TIMESTAMP+ " BETWEEN" + " ?" + " AND" + " ? AND("; //<<<<<<<<<< CONJUNCTION ADDED
            }
            //<<<<<<<<<< else construct/clause REMOVED as it does nothing
            department = mDeptSpinner.getSelectedItem().toString();
            source = mSourceSpinner.getSelectedItem().toString();

            if(mDeptSpinner.getSelectedItem() != null){
                sql = sql + FormEntry.COLUMN_NAME_DEPT + " = ?";
            }

            if(mSourceSpinner.getSelectedItem() != null){
                sql = sql + " OR "+ FormEntry.COLUMN_NAME_SOURCE + " = ?";
            }
            sql = sql + time_filter_end_char;

但是,如果 dept 或 source 都为 null 或为空,则上述情况会成为问题。

所以也许更正确的代码应该是这样的:-

    String sd = String.valueOf(StartDate);
    String ed = String.valueOf(EndDate);
    String department = mDeptSpinner.getSelectedItem().toString();
    String source = mSourceSpinner.getSelectedItem().toString();
    String sql = "SELECT * FROM " + FormEntry.COLUMN_TABLE_NAME; //<<<<<<< no filtering
    String time_filter = "";
    String department_filter = "";
    String source_filter = "";
    if (sd != null && ed != null && sd.length() > 0 && ed.length() > 0) {
        time_filter = FormEntry.TIMESTAMP + " BETWEEN" + " ?" + " AND" + " ? ";
    }
    if (department != null && department.length() > 0) {
        department_filter = FormEntry.COLUMN_NAME_DEPT + " = ?";
    }
    if (source != null && source.length() > 0) {
        source_filter = FormEntry.COLUMN_NAME_SOURCE + " = ?";
    }
    String dept_source_conjunction = "";
    if (department_filter.length() > 0 && source_filter.length() > 0) {
        dept_source_conjunction = " OR ";
    }
    if (time_filter.length() > 0 || department_filter.length() > 0 || source_filter.length() > 0) {
        sql = sql + " WHERE ";
    }
    String end_dept_source_char = "";
    if (time_filter.length() > 0) {
        sql = sql + time_filter;
        if (department_filter.length() > 0 || source_filter.length() > 0) {
            sql = sql + " AND ";
            if (dept_source_conjunction.length() > 0) {
                sql = sql + "(";
                end_dept_source_char = ")";
            }
        }
    }
    sql = sql + department_filter + dept_source_conjunction + source_filter  + end_dept_source_char;

测试:-

上面的以下改编用于测试代码:-

private String testit(String StartDate, String EndDate, String mDS, String mSS) {
        //String sd = String.valueOf(StartDate);
        //String ed = String.valueOf(EndDate);
        String sd = StartDate; //<<<<<<<<<< FOR TESTING
        String ed = EndDate; //<<<<<<<<<< FOR TESTING
        //String department = mDeptSpinner.getSelectedItem().toString();
        //String source = mSourceSpinner.getSelectedItem().toString();
        String department = mDS; //<<<<<<<<<< FOR TESTING
        String source = mSS; //<<<<<<<<<< FOR TESTING
        String sql = "SELECT * FROM " + FormEntry.COLUMN_TABLE_NAME; //<<<<<<< no filtering
        String time_filter = "";
        String department_filter = "";
        String source_filter = "";
        if (sd != null && ed != null && sd.length() > 0 && ed.length() > 0) {
            time_filter = FormEntry.TIMESTAMP + " BETWEEN" + " ?" + " AND" + " ? ";
        }
        if (department != null && department.length() > 0) {
            department_filter = FormEntry.COLUMN_NAME_DEPT + " = ?";
        }
        if (source != null && source.length() > 0) {
            source_filter = FormEntry.COLUMN_NAME_SOURCE + " = ?";
        }
        String dept_source_conjunction = "";
        if (department_filter.length() > 0 && source_filter.length() > 0) {
            dept_source_conjunction = " OR ";
        }
        if (time_filter.length() > 0 || department_filter.length() > 0 || source_filter.length() > 0) {
            sql = sql + " WHERE ";
        }
        String end_dept_source_char = "";
        if (time_filter.length() > 0) {
            sql = sql + time_filter;
            if (department_filter.length() > 0 || source_filter.length() > 0) {
                sql = sql + " AND ";
                if (dept_source_conjunction.length() > 0) {
                    sql = sql + "(";
                    end_dept_source_char = ")";
                }
            }
        }
        sql = sql + department_filter + dept_source_conjunction + source_filter  + end_dept_source_char;
        return sql;
    }

然后使用了以下内容:-

    Log.d("TEST2", testit(null,null,null,null)); //<<<<<<<<<< no filter
    Log.d("TEST1",testit("1111111111","2222222222",null,null)); // time filter only
    Log.d("TEST3", testit("1111111111","2222222222","d1","s1")); // full filter
    Log.d("TEST4",testit("1111111111","2222222222",null,"s1")); // time and source
    Log.d("TEST5",testit("1111111111","2222222222","d1","")); // time and dept

结果是:-

D/TEST2: SELECT * FROM your_table_name
D/TEST1: SELECT * FROM your_table_name WHERE your_timestamp_column BETWEEN ? AND ? 
D/TEST3: SELECT * FROM your_table_name WHERE your_timestamp_column BETWEEN ? AND ?  AND (your_department_column = ? OR your_source_column = ?)
D/TEST4: SELECT * FROM your_table_name WHERE your_timestamp_column BETWEEN ? AND ?  AND your_source_column = ?
D/TEST5: SELECT * FROM your_table_name WHERE your_timestamp_column BETWEEN ? AND ?  AND your_department_column = ?