Skip to content

Commit 3bf2e1a

Browse files
DiligentNezhaabel533
authored andcommitted
扩展一些根据属性及条件值删除的通用方法
1 parent 570ef15 commit 3bf2e1a

File tree

7 files changed

+445
-0
lines changed

7 files changed

+445
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package tk.mybatis.mapper.additional.delete;
2+
3+
import org.apache.ibatis.annotations.DeleteProvider;
4+
import org.apache.ibatis.annotations.Param;
5+
import org.apache.ibatis.annotations.SelectProvider;
6+
import tk.mybatis.mapper.annotation.RegisterMapper;
7+
import tk.mybatis.mapper.weekend.Fn;
8+
9+
import java.util.List;
10+
11+
/**
12+
* @param <T> 不能为空
13+
* @author jingkaihui
14+
* @date 2020/3/30
15+
*/
16+
@RegisterMapper
17+
public interface DeleteByPropertyMapper<T> {
18+
19+
/**
20+
* 根据实体中的属性删除,条件使用等号
21+
*
22+
* @param fn 属性
23+
* @param value 属性值
24+
* @return
25+
*/
26+
@DeleteProvider(type = DeletePropertyProvider.class, method = "dynamicSQL")
27+
int deleteByProperty(@Param("fn") Fn<T, ?> fn, @Param("value") Object value);
28+
29+
/**
30+
* 根据实体中的属性删除,条件使用 in
31+
*
32+
* @param fn 属性
33+
* @param value 属性值
34+
* @return
35+
*/
36+
@DeleteProvider(type = DeletePropertyProvider.class, method = "dynamicSQL")
37+
int deleteInByProperty(@Param("fn") Fn<T, ?> fn, @Param("values") Object value);
38+
39+
/**
40+
* 根据属性及对应值进行删除,删除条件使用 between
41+
*
42+
* @param fn 属性
43+
* @param begin 开始值
44+
* @param end 开始值
45+
* @return
46+
*/
47+
@SelectProvider(type = DeletePropertyProvider.class, method = "dynamicSQL")
48+
int deleteBetweenByProperty(@Param("fn") Fn<T, ?> fn, @Param("begin") Object begin, @Param("end") Object end);
49+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
package tk.mybatis.mapper.additional.delete;
2+
3+
import org.apache.ibatis.mapping.MappedStatement;
4+
import org.apache.ibatis.mapping.SqlCommandType;
5+
import tk.mybatis.mapper.MapperException;
6+
import tk.mybatis.mapper.additional.select.SelectPropertyProvider;
7+
import tk.mybatis.mapper.entity.EntityColumn;
8+
import tk.mybatis.mapper.entity.EntityTable;
9+
import tk.mybatis.mapper.mapperhelper.EntityHelper;
10+
import tk.mybatis.mapper.mapperhelper.MapperHelper;
11+
import tk.mybatis.mapper.mapperhelper.MapperTemplate;
12+
import tk.mybatis.mapper.mapperhelper.SqlHelper;
13+
import tk.mybatis.mapper.util.MetaObjectUtil;
14+
15+
/**
16+
* @author jingkaihui
17+
* @date 2020/3/30
18+
*/
19+
public class DeletePropertyProvider extends MapperTemplate {
20+
21+
public DeletePropertyProvider(Class<?> mapperClass, MapperHelper mapperHelper) {
22+
super(mapperClass, mapperHelper);
23+
}
24+
25+
/**
26+
* 根据属性删除,条件使用等号
27+
*
28+
* @param ms
29+
* @return
30+
*/
31+
public String deleteByProperty(MappedStatement ms) {
32+
String propertyHelper = DeletePropertyProvider.class.getName();
33+
Class<?> entityClass = getEntityClass(ms);
34+
StringBuilder sql = new StringBuilder();
35+
// 如果是逻辑删除,则修改为更新表,修改逻辑删除字段的值
36+
if (SqlHelper.hasLogicDeleteColumn(entityClass)) {
37+
sql.append(SqlHelper.updateTable(entityClass, tableName(entityClass)));
38+
sql.append("<set>");
39+
sql.append(SqlHelper.logicDeleteColumnEqualsValue(entityClass, true));
40+
sql.append("</set>");
41+
MetaObjectUtil.forObject(ms).setValue("sqlCommandType", SqlCommandType.UPDATE);
42+
} else {
43+
sql.append(SqlHelper.deleteFromTable(entityClass, tableName(entityClass)));
44+
}
45+
sql.append("<where>\n");
46+
sql.append("<if test=\"false==");
47+
sql.append("@");
48+
sql.append(propertyHelper);
49+
sql.append("@isNull(value, ");
50+
sql.append(getConfig().isSafeDelete());
51+
sql.append(")");
52+
sql.append("\">\n");
53+
String entityClassName = entityClass.getName();
54+
//通过实体类名获取运行时属性对应的字段
55+
String ognl = new StringBuilder("${@")
56+
.append(propertyHelper)
57+
.append("@getColumnByProperty(@java.lang.Class@forName(\"")
58+
.append(entityClassName)
59+
.append("\"), @tk.mybatis.mapper.weekend.reflection.Reflections@fnToFieldName(fn))}").toString();
60+
sql.append(ognl + " = #{value}\n");
61+
sql.append("</if>\n");
62+
sql.append("</where>");
63+
return sql.toString();
64+
}
65+
66+
/**
67+
* 根据属性删除,条件使用等号
68+
*
69+
* @param ms
70+
* @return
71+
*/
72+
public String deleteInByProperty(MappedStatement ms) {
73+
String propertyHelper = DeletePropertyProvider.class.getName();
74+
Class<?> entityClass = getEntityClass(ms);
75+
StringBuilder sql = new StringBuilder();
76+
// 如果是逻辑删除,则修改为更新表,修改逻辑删除字段的值
77+
if (SqlHelper.hasLogicDeleteColumn(entityClass)) {
78+
sql.append(SqlHelper.updateTable(entityClass, tableName(entityClass)));
79+
sql.append("<set>");
80+
sql.append(SqlHelper.logicDeleteColumnEqualsValue(entityClass, true));
81+
sql.append("</set>");
82+
MetaObjectUtil.forObject(ms).setValue("sqlCommandType", SqlCommandType.UPDATE);
83+
} else {
84+
sql.append(SqlHelper.deleteFromTable(entityClass, tableName(entityClass)));
85+
}
86+
sql.append("<where>\n");
87+
String entityClassName = entityClass.getName();
88+
String sqlSegment =
89+
"${@" + propertyHelper + "@getColumnByProperty(@java.lang.Class@forName(\"" + entityClassName + "\"),"
90+
+ "@tk.mybatis.mapper.weekend.reflection.Reflections@fnToFieldName(fn))} in"
91+
+ "<foreach open=\"(\" close=\")\" separator=\",\" collection=\"values\" item=\"obj\">\n"
92+
+ "#{obj}\n"
93+
+ "</foreach>\n";
94+
sql.append(sqlSegment);
95+
// 逻辑删除的未删除查询条件
96+
sql.append(SqlHelper.whereLogicDelete(entityClass, false));
97+
sql.append("</where>");
98+
return sql.toString();
99+
}
100+
101+
/**
102+
* 根据属性删除,删除条件使用 between
103+
*
104+
* @param ms
105+
* @return
106+
*/
107+
public String deleteBetweenByProperty(MappedStatement ms) {
108+
String propertyHelper = DeletePropertyProvider.class.getName();
109+
Class<?> entityClass = getEntityClass(ms);
110+
StringBuilder sql = new StringBuilder();
111+
// 如果是逻辑删除,则修改为更新表,修改逻辑删除字段的值
112+
if (SqlHelper.hasLogicDeleteColumn(entityClass)) {
113+
sql.append(SqlHelper.updateTable(entityClass, tableName(entityClass)));
114+
sql.append("<set>");
115+
sql.append(SqlHelper.logicDeleteColumnEqualsValue(entityClass, true));
116+
sql.append("</set>");
117+
MetaObjectUtil.forObject(ms).setValue("sqlCommandType", SqlCommandType.UPDATE);
118+
} else {
119+
sql.append(SqlHelper.deleteFromTable(entityClass, tableName(entityClass)));
120+
}
121+
sql.append("<where>\n");
122+
String entityClassName = entityClass.getName();
123+
String sqlSegment =
124+
"${@" + propertyHelper + "@getColumnByProperty(@java.lang.Class@forName(\"" + entityClassName + "\"),"
125+
+ "@tk.mybatis.mapper.weekend.reflection.Reflections@fnToFieldName(fn))} "
126+
+ "between #{begin} and #{end}";
127+
sql.append(sqlSegment);
128+
// 逻辑删除的未删除查询条件
129+
sql.append(SqlHelper.whereLogicDelete(entityClass, false));
130+
sql.append("</where>");
131+
return sql.toString();
132+
}
133+
134+
/**
135+
* 根据实体Class和属性名获取对应的表字段名
136+
* @param entityClass 实体Class对象
137+
* @param property 属性名
138+
* @return
139+
*/
140+
public static String getColumnByProperty(Class<?> entityClass, String property) {
141+
EntityTable entityTable = EntityHelper.getEntityTable(entityClass);
142+
EntityColumn entityColumn = entityTable.getPropertyMap().get(property);
143+
return entityColumn.getColumn();
144+
}
145+
146+
public static boolean isNull(Object value, boolean safeDelete) {
147+
boolean isNull = false;
148+
if (safeDelete) {
149+
if (null == value) {
150+
throw new MapperException("安全删除模式下,不允许执行不带查询条件的 delete 方法");
151+
}
152+
} else {
153+
if (null == value) {
154+
isNull = true;
155+
}
156+
}
157+
return isNull;
158+
}
159+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
package tk.mybatis.mapper.additional.delete;
2+
3+
import tk.mybatis.mapper.annotation.LogicDelete;
4+
5+
import javax.persistence.Column;
6+
import javax.persistence.Id;
7+
import java.time.LocalDate;
8+
9+
/**
10+
* @author jingkaihui
11+
* @date 2019/10/19
12+
*/
13+
public class Course {
14+
15+
@Id
16+
private Integer id;
17+
18+
private String name;
19+
20+
private Integer price;
21+
22+
private LocalDate published;
23+
24+
@LogicDelete
25+
@Column(name = "is_deleted")
26+
private Boolean isDeleted;
27+
28+
public Integer getId() {
29+
return id;
30+
}
31+
32+
public void setId(Integer id) {
33+
this.id = id;
34+
}
35+
36+
public String getName() {
37+
return name;
38+
}
39+
40+
public void setName(String name) {
41+
this.name = name;
42+
}
43+
44+
public Integer getPrice() {
45+
return price;
46+
}
47+
48+
public void setPrice(Integer price) {
49+
this.price = price;
50+
}
51+
52+
public LocalDate getPublished() {
53+
return published;
54+
}
55+
56+
public void setPublished(LocalDate published) {
57+
this.published = published;
58+
}
59+
60+
public Boolean getDeleted() {
61+
return isDeleted;
62+
}
63+
64+
public void setDeleted(Boolean deleted) {
65+
isDeleted = deleted;
66+
}
67+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package tk.mybatis.mapper.additional.delete;
2+
3+
import tk.mybatis.mapper.common.base.BaseSelectMapper;
4+
5+
/**
6+
* @author jingkaihui
7+
* @date 2019/10/19
8+
*/
9+
public interface CourseMapper extends BaseSelectMapper<Course>, DeleteByPropertyMapper<Course> {
10+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
drop table course if exists;
2+
3+
create table course (
4+
id integer NOT NULL PRIMARY KEY,
5+
name varchar(32),
6+
price integer,
7+
published date,
8+
is_deleted integer
9+
);
10+
11+
INSERT INTO course VALUES (1, 'Java入门1', '50', '2015-11-11', '0');
12+
INSERT INTO course VALUES (2, 'Java入门2', '50', '2015-11-11', '0');
13+
INSERT INTO course VALUES (3, 'Java中级', '80', '2017-11-11', '0');
14+
INSERT INTO course VALUES (4, 'Java高级', '100', '2019-11-11', '0');
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
package tk.mybatis.mapper.additional.delete;
2+
3+
import org.apache.ibatis.session.SqlSession;
4+
import org.junit.Assert;
5+
import org.junit.Test;
6+
import tk.mybatis.mapper.additional.BaseTest;
7+
8+
import java.io.IOException;
9+
import java.io.Reader;
10+
import java.net.URL;
11+
import java.util.Arrays;
12+
import java.util.List;
13+
14+
public class DeleteByPropertyMapperTest extends BaseTest {
15+
16+
/**
17+
* 获取 mybatis 配置
18+
*
19+
* @return
20+
*/
21+
protected Reader getConfigFileAsReader() throws IOException {
22+
URL url = getClass().getResource("mybatis-config.xml");
23+
return toReader(url);
24+
}
25+
26+
/**
27+
* 获取初始化 sql
28+
*
29+
* @return
30+
*/
31+
protected Reader getSqlFileAsReader() throws IOException {
32+
URL url = getClass().getResource("CreateDB.sql");
33+
return toReader(url);
34+
}
35+
36+
@Test
37+
public void deleteByPropertyTest() {
38+
SqlSession sqlSession = getSqlSession();
39+
try {
40+
CourseMapper mapper = sqlSession.getMapper(CourseMapper.class);
41+
42+
Course beforeDelete = mapper.selectByPrimaryKey(2);
43+
Assert.assertNotNull(beforeDelete);
44+
Assert.assertEquals("Java入门2", beforeDelete.getName());
45+
46+
int deletedCount = mapper.deleteByProperty(Course::getName, "Java入门2");
47+
Assert.assertEquals(1, deletedCount);
48+
49+
Course afterDelete = mapper.selectByPrimaryKey(2);
50+
Assert.assertNull(afterDelete);
51+
} finally {
52+
sqlSession.close();
53+
}
54+
}
55+
56+
@Test
57+
public void deleteInByPropertyTest() {
58+
SqlSession sqlSession = getSqlSession();
59+
try {
60+
CourseMapper mapper = sqlSession.getMapper(CourseMapper.class);
61+
62+
List<Course> beforeDelete = mapper.selectAll();
63+
Assert.assertEquals(4, beforeDelete.size());
64+
65+
int deletedCount = mapper.deleteInByProperty(Course::getPrice, Arrays.asList(50, 80, 100));
66+
67+
Assert.assertEquals(4, deletedCount);
68+
69+
List<Course> afterDelete = mapper.selectAll();
70+
Assert.assertEquals(0, afterDelete.size());
71+
} finally {
72+
sqlSession.close();
73+
}
74+
}
75+
76+
@Test
77+
public void deleteBetweenByPropertyTest() {
78+
SqlSession sqlSession = getSqlSession();
79+
try {
80+
CourseMapper mapper = sqlSession.getMapper(CourseMapper.class);
81+
82+
List<Course> beforeDelete = mapper.selectAll();
83+
Assert.assertEquals(4, beforeDelete.size());
84+
85+
int deletedCount = mapper.deleteBetweenByProperty(Course::getPrice, 80, 100);
86+
87+
Assert.assertEquals(2, deletedCount);
88+
89+
List<Course> afterDelete = mapper.selectAll();
90+
Assert.assertEquals(2, afterDelete.size());
91+
} finally {
92+
sqlSession.close();
93+
}
94+
}
95+
}

0 commit comments

Comments
 (0)