使用query()方法进行模糊查询

本文介绍了一个使用Android平台上的SQLite数据库进行数据存储和查询的完整示例,包括创建数据库、定义表结构、实现数据查询并将结果显示在界面上的过程。



 

 

 

在main.xml中:

 

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

    android:id="@+id/mylayout"

    android:layout_width="fill_parent"

    android:layout_height="fill_parent"

    android:orientation="vertical"

    android:gravity="center_horizontal">

 

    <Button

        android:id="@+id/findBut"

        android:layout_marginTop="8dp"

        android:background="#0066ff"

        android:textColor="#ffffff"

        android:layout_width="100dp"

        android:layout_height="40dp"

        android:text="查询全部数据" />

 

</LinearLayout>

 

 

 

在MyDatabaseHelper.java类中:

 

package com.li.sqlite;

//数据库的辅助操作类

import android.content.Context;

import android.database.sqlite.SQLiteDatabase;

import android.database.sqlite.SQLiteOpenHelper;

 

public class MyDatabaseHelper extends SQLiteOpenHelper {

  private static final String DATABASENAME = "liyewen.db" ;

  private static final int DATABASERVERSION = 1 ;  // 设置数据库的版本

  private static final String TABLENAME = "mytab" ;

 

  public MyDatabaseHelper(Context context) {  // 用户最关心的也肯定只是Context

     super(context, DATABASENAME, null, DATABASERVERSION);

  }

 

  @Override

  public void onCreate(SQLiteDatabase db) { // 创建数据表

     String sql = "CREATE TABLE " + TABLENAME + "("

         + "id    INTEGER       PRIMARY KEY ,"   // 在SQLite中设置为Integer、PRIMARY KEY则ID自动增长

         + "name   VARCHAR(50)   NOT NULL ,"

         + "birthday DATE NOT    NULL" + ")";

     db.execSQL(sql) ;  // 执行SQL

     System.out.println("****************** 创建:onCreate()。");

  }

 

  @Override

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

     String sql = "DROP TABLE IF EXISTS " + TABLENAME ;

     db.execSQL(sql) ;

     System.out.println("****************** 更新:onUpgrade()。");

     this.onCreate(db) ;

  }

 

}

 

 

 

 

在MytabCursor.java类中:

 

package com.li.sqlite;

 

import java.util.ArrayList;

import java.util.List;

 

import android.database.Cursor;

import android.database.sqlite.SQLiteDatabase;

 

public class MytabCursor {

  private static final String TABLENAME = "mytab" ;

  private SQLiteDatabase db = null ;

  public MytabCursor(SQLiteDatabase db) {

     this.db = db ;

  }

  public List<String> find(){

     List<String> all = new ArrayList<String>() ; // 此时只是String

     String columns[] = new String[] { "id", "name", "birthday" };

     String keyWord = "5" ; // 查询关键字 ,应该由方法定义

     String selectionArgs[] = new String[] { "%" + keyWord + "%", "%" + keyWord + "%" };

     String selection = "name LIKE ? OR birthday LIKE ?" ;

     Cursor result = this.db.query(TABLENAME, columns, selection, selectionArgs, null,

         null, null);  // 这些条件根据自己的情况增加

     for (result.moveToFirst(); !result.isAfterLast(); result.moveToNext()) { // 采用循环的方式检索数据

       all.add("【" + result.getInt(0) + "】" + " " + result.getString(1)

            + "," + result.getString(2));

     }

     this.db.close() ;

     return all ;

  }

}

 

 

在MySQLiteDemo.java中:

 

package com.li.sqlite;

 

import android.app.Activity;

import android.database.sqlite.SQLiteOpenHelper;

import android.os.Bundle;

import android.view.View;

import android.view.View.OnClickListener;

import android.widget.ArrayAdapter;

import android.widget.Button;

import android.widget.LinearLayout;

import android.widget.ListView;

 

public class MySQLiteDemo extends Activity {

  private Button findBut = null;

  private SQLiteOpenHelper helper = null;

  private LinearLayout mylayout = null;

  @Override

  public void onCreate(Bundle savedInstanceState) {

     super.onCreate(savedInstanceState);

     super.setContentView(R.layout.main);

     this.findBut = (Button)super.findViewById(R.id.findBut);

     this.mylayout = (LinearLayout)super.findViewById(R.id.mylayout);

     this.findBut.setOnClickListener(new OnClickListenerImpl());

  }

  private class OnClickListenerImpl implements OnClickListener{

     public void onClick(View v) {

       MySQLiteDemo.this.helper = new MyDatabaseHelper(MySQLiteDemo.this);

       ListView listView = new ListView(MySQLiteDemo.this);

       listView.setAdapter( //设置数据

            new ArrayAdapter<String>  //所有的数据是字符串

            (MySQLiteDemo.this,       //上下文

            android.R.layout.simple_list_item_1, //列表显示的布局

            new MytabCursor(     //实例化查询

            MySQLiteDemo.this.helper.getReadableDatabase())  //取得SQLiteDatabase对象

            .find()));    //调用find()方法,返回List<String>

       MySQLiteDemo.this.mylayout.addView(listView);

     }

  }

}

 

<think>在Java中,使用Spring Data JPA的`@Query`注解编写模糊查询时,可以在JPQL或原生SQL中使用`LIKE`关键字,并配合通配符`%`来实现。下面我将分别展示使用JPQL和原生SQL的示例。 ### 1. 使用JPQL编写模糊查询 在JPQL中,我们可以使用`LIKE`关键字和`%`通配符。注意,JPQL的参数绑定可以使用命名参数或位置参数。 #### 示例代码: ```java import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; public interface UserRepository extends JpaRepository<User, Long> { // 使用命名参数 @Query("SELECT u FROM User u WHERE u.name LIKE %:name%") List<User> findByNameContaining(@Param("name") String name); // 或者使用位置参数(不推荐,因为容易出错) @Query("SELECT u FROM User u WHERE u.name LIKE %?1%") List<User> findByNameContaining2(String name); } ``` ### 2. 使用原生SQL编写模糊查询 如果你需要编写原生SQL查询,同样可以使用`LIKE`和`%`通配符。 #### 示例代码: ```java public interface UserRepository extends JpaRepository<User, Long> { @Query(value = "SELECT * FROM users WHERE name LIKE %:name%", nativeQuery = true) List<User> findByNameNative(@Param("name") String name); } ``` ### 解释: - `%`通配符表示任意字符出现任意次数(包括0次)。所以`%:name%`表示在字符串的任意位置匹配`:name`。 - 在JPQL中,我们使用命名参数`:name`,并通过`@Param("name")`将方法参数绑定到查询中的命名参数。这样更清晰,不易出错。 - 在原生SQL中,我们设置`nativeQuery=true`,然后编写SQL语句。 ### 注意事项: - 在传递参数时,我们不需要在参数两边添加`%`,因为在查询语句中已经添加了。但是,如果你想要在调用方法时控制通配符的位置,也可以在方法参数中添加`%`,然后在查询语句中不使用`%`,例如: ```java @Query("SELECT u FROM User u WHERE u.name LIKE :name") List<User> findByNameContaining(@Param("name") String name); ``` 调用时:`repository.findByNameContaining("%" + name + "%");` 这种方式更灵活,但调用方需要处理通配符。 ### 推荐方式: 通常,我们推荐在查询语句中直接包含通配符,这样调用方只需传递要搜索的字符串即可,而不需要关心通配符。 ### 模糊查询的其他方式: 除了使用`@Query`,Spring Data JPA还提供了通过方法名自动生成查询的方式,例如: ```java List<User> findByNameContaining(String name); List<User> findByNameLike(String name); // 注意,这里的参数需要自己加通配符,比如"%name%" ``` 但是,本问题要求使用`@Query`,所以这里不再展开。 ### 总结: 使用`@Query`编写模糊查询,关键是在查询语句中使用`LIKE`和`%`通配符,并正确绑定参数。 §§相关问题§§: 1. 在Spring Data JPA中,@Query注解支持哪些类型的查询? 2. 使用@Query注解进行参数绑定时,命名参数和位置参数有什么区别? 3. 在JPQL中,LIKE关键字的使用有哪些注意事项? 4. 除了@Query注解,Spring Data JPA还有哪些方式可以实现模糊查询?</think>在Spring Data JPA中使用`@Query`进行模糊查询时,可以通过JPQL(Java Persistence Query Language)或原生SQL结合`LIKE`关键字和通配符`%`实现。以下是详细实现方式和解释: ### 1. JPQL模糊查询实现 ```java public interface UserRepository extends JpaRepository<User, Long> { // 方式1:直接在注解中拼接通配符(推荐) @Query("SELECT u FROM User u WHERE u.username LIKE %:keyword%") List<User> findByUsernameContaining(@Param("keyword") String keyword); // 方式2:在参数中传递带通配符的值 @Query("SELECT u FROM User u WHERE u.email LIKE :pattern") List<User> findByEmailPattern(@Param("pattern") String pattern); } ``` **调用示例:** ```java // 方式1调用:自动在keyword两侧添加% List<User> users = userRepository.findByUsernameContaining("john"); // 方式2调用:手动添加通配符 List<User> users = userRepository.findByEmailPattern("%@gmail.com"); ``` ### 2. 原生SQL模糊查询 ```java @Query(value = "SELECT * FROM users WHERE first_name LIKE %:name%", nativeQuery = true) List<User> findByFirstNameNative(@Param("name") String name); ``` ### 关键点解释: 1. **通配符`%`的作用**: - `%keyword%`:匹配包含"keyword"的任意字符串(最常用) - `keyword%`:匹配以"keyword"开头的字符串 - `%keyword`:匹配以"keyword"结尾的字符串 2. **参数绑定的两种方式**: - **推荐方式**:在JPQL语句中直接使用`%:param%`,Spring会自动处理参数绑定 - 备选方式:在调用时手动拼接通配符(需注意SQL注入风险) 3. **`@Param`注解必要性**: 当使用命名参数(如`:keyword`)时,必须使用`@Param`绑定方法参数 4. **防SQL注入**: Spring Data JPA会自动对参数进行转义处理,但需避免在参数中直接拼接通配符: ```java // 危险!可能引发SQL注入 @Query("SELECT u FROM User u WHERE u.username LIKE '%' || :keyword || '%'") ``` ### 模糊查询原理 JPQL的`LIKE`最终会被转换为SQL的`LIKE`语句。例如: ```sql -- JPQL转换结果 SELECT * FROM users WHERE username LIKE '%john%' ``` ### 性能注意事项 1. 前导通配符(如`%john`)会导致全表扫描,大数据表需谨慎使用 2. 建议对频繁查询的字段添加数据库索引 3. 考虑使用全文搜索引擎(如Elasticsearch)处理复杂模糊查询
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值