我想问一下在不对所有记录进行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循环?因为如果用户列表是一百万或更多,则可能会出现性能问题。
答案 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)