引言:
最近有个需求需要对数据库的某个字段去重,但是另外一个字段不需要去重,因为那个字段是永远不会重复的,但是呢,查询的时候需要查询到那个字段。当时我猜大家第一反应估计都是distinct 进行去重,但是这种去重手法不可取。请看以下分析。
一.从数据库层面进行去重
数据整理阶段
1.创建数据库及数据
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
DROP TABLE IF EXISTS `t1`;
CREATE TABLE `t1` (
`ID` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`VALUE` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
PRIMARY KEY (`ID`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
INSERT INTO `t1` VALUES ('1231', '12');
INSERT INTO `t1` VALUES ('1234', '21');
INSERT INTO `t1` VALUES ('1238', '21');
INSERT INTO `t1` VALUES ('1239', '81');
INSERT INTO `t1` VALUES ('1526', '81');
INSERT INTO `t1` VALUES ('1589', '66');
INSERT INTO `t1` VALUES ('2300', '82');
INSERT INTO `t1` VALUES ('2503', '82');
INSERT INTO `t1` VALUES ('2525', '21');
INSERT INTO `t1` VALUES ('263', '82');
SET FOREIGN_KEY_CHECKS = 1;
2.distinct关键字
如果只有一个字段使用distinct确实是一个不错的选择  假如我们有两个及其以上的字段再次使用distinct关键字就可能不是我们想要的结果 
3.分组函数
众所周知,分组函数去重,所以利用分组函数确实也能达到像distinct一样的去重手段  当然如果你只是筛选重复的进行处理,利用分组函数就再好不过了
SELECT
*
FROM
T1
WHERE
VALUE
IN ( SELECT VALUE FROM T1 GROUP BY VALUE HAVING count( VALUE ) > 1 )

这种可以把所有的重复的筛选出来然后进行下一步操作,当然这个跟我的需求有点出入,我要查出来所有的,因为我之后要根据ID进行删除信息,所以这时候就必须只能在java里面处理了
二.从java层面进行数据处理
数据整理阶段(只对name进行去重)
1.创建teacher类,这里不要使用lombok因为一会要重写equlas和hashcode
import java.util.Objects;
public class Teacher {
private String uid;
private String name;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Teacher teacher = (Teacher) o;
return Objects.equals(uid, teacher.uid) && Objects.equals(name, teacher.name);
}
@Override
public String toString() {
return "Teacher{" +
"uid='" + uid + '\'' +
", name='" + name + '\'' +
'}';
}
@Override
public int hashCode() {
return Objects.hash(uid, name);
}
public Teacher() {
}
public Teacher(String uid, String name) {
this.uid = uid;
this.name = name;
}
public String getUid() {
return uid;
}
public void setUid(String uid) {
this.uid = uid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
1.stream流
List<Teacher> ps=new ArrayList<>();
ps.add(new Teacher("11","tom"));
ps.add(new Teacher("124","张三"));
ps.add(new Teacher("12","tom"));
ps.add(new Teacher("111","tom"));
ps.add(new Teacher("1131","tom1"));
ps.add(new Teacher("1211","tom1"));
List<Teacher> list = ps.stream().collect(
Collectors.collectingAndThen(Collectors.toCollection(
() -> new TreeSet<>(Comparator.comparing(p -> p.getName()))), ArrayList::new)
);
list.forEach(System.out::println);
 看上去steam流应该是主流的去重最简便,效果最好的了,但是如果有小伙伴的公司项目比较老,是在JDK1.8之前的就没有办法使用这个方法了,怎么办呢,别急还有其他的办法。
2.对hashcode和equals重写


重写之后然后进行测试,我们用hashSet的无序不可重复原理进行测试,如图是可以去重的 
3.自定义方法去重
如果在公司不让动实体类的话我们可以自定义一个方法,因为我们需要所有的数据,那查出来的必定是个list集合,那我们可以利用上面的hashSet的原理进行字段去重,现在我以name字段进行操作,我把上面注释掉的equals和hashCode进行恢复到原本的位置。 这是定义的去重第二个属性的方法
public static HashSet<String> removeDuplicates(List<Teacher> list) {
HashSet<String> hashSet = new HashSet<>();
for (Teacher t1 : list) {
if (t1.getName() != null && "".equals(t1.getName())) {
hashSet.add(t1.getName());
}
}
return hashSet;
}
List<Teacher> ps = new ArrayList<>();
Teacher teacher = new Teacher();
teacher.setUid("123");
teacher.setName("wjs");
Teacher teacher1 = new Teacher();
teacher1.setUid("456");
teacher1.setName("wjs");
Teacher teacher2 = new Teacher();
teacher2.setUid("4567");
teacher2.setName("wyz");
Teacher teacher3 = new Teacher();
teacher3.setUid("45");
teacher3.setName("wyz");
ps.add(teacher);
ps.add(teacher1);
ps.add(teacher2);
ps.add(teacher3);
HashSet<String> strings = removeDuplicates(ps);
for (String str :
strings) {
System.out.println(str);
}
查看结果 
|