在不循环所有记录的情况下从数据库检索特定数据的最有效方法是什么?

时间:2018-10-15 07:46:13

标签: java sql database spring performance

我想问一下在不对所有记录进行for循环的情况下从数据库搜索特定数据的最有效方法是什么?

我有一个关于java spring的项目,并且我有这个实体:

@Entity  
@Table(name = "USERS") public class USERS  {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "UID") 
private Integer id;

@Column(name = "FName") 
private String firstName;

@Column(name = "SName") 
private String secondName;

@Column(name = "TName") 
private String thirdName;

@Column(name = "LName") 
private String fourthName;

@Column(name = "Email") 
private String email;

@Column(name = "PW") 
private String password;

@Column(name = "MNumber") 
private String mobileNumber;

@Column(name = "ISDeleted") 
private boolean isUserDeleted;


//---------------------- Getters and Setters ----------------------

我做了这项服务:

public List<USERS> findAllActive() {
    List<USERS> usersList = new ArrayList<USERS>();
    for (USERS users: usersRepository.findAll()){
        if (!users.isUserDeleted()){
            usersList.add(users);
        }
    }
    return usersList;
}

例如;无论用户是否处于活动状态,我都有一个属性。

所以,我的问题;什么是最有效的方式来获取特定数据,例如从数据库中检索所有活动用户而不进行上面的代码中的for循环?因为如果用户列表是一百万或更多,则可能会出现性能问题。

4 个答案:

答案 0 :(得分:2)

假设您正在使用JpaRepository,则可以创建自定义查询。

@Query("SELECT u FROM USERS u WHERE u.userDeleted = false") 

List<USERS> findNotDeletedUsers();

然后致电usersRepository.findNotDeletedUsers();

答案 1 :(得分:0)

首先,在要搜索的字段上使用索引(如果该列只有两个不同的值,这不会有多大帮助,但如果值具有很高的稀疏性。

@Entity 
@Table(name = "USERS",
       indexes = {
           // not a huge performance gain, since the column values are true/false
           @Index(name = "index_by_active",  columnList="ISDeleted", unique = false),
           // possible huge performance gain, since only the relevant records are scanned        
           @Index(name = "index_by_first_name", columnList="FName", unique = false)})
public class USERS {...}

然后,定义一个使用索引字段的查询方法(如果您正在使用spring数据,则其外观如下)。

public interface UsersRepository extends CrudRepository<USERS, Long> {

    List<USERS> findUsersByISDeleted(boolean deleted);

    List<USERS> findUsersByFName(String name); 

    List<USERS> findUsersByFNameAndISDeleted(String name, boolean deleted); 

}

对索引字段的查询将利用基础索引并提供有效的访问计划(因此,您最终不会扫描整个表以提取与给定条件匹配的实体子集)。

答案 2 :(得分:0)

@Madis的解决方案还可以。但是,如果您始终希望获得未在所有查询中都删除的用户,则可以在Entity上指定它:

@Entity 
@Table(name = "USERS")
@Where("ISDeleted = false")
public class USERS  {

因此,现在条件“ ISDeleted = false”会自动附加到UserRepository的所有查询中。您可以使用usersRepository.findAll()代替。

答案 3 :(得分:0)

您不需要指定任何sql查询或where子句。 CrudRepository会自动为您完成。只需使用以下代码并根据需要传递true / false

List<Users> findIsUserDeleted(boolean isDeleted)
相关问题