Skip to content

Commit 4f33e9b

Browse files
committed
DATAJDBC-106 - Support to specify a database object name using annotation
* Added @table * Added @column
1 parent 41e31b1 commit 4f33e9b

File tree

4 files changed

+218
-4
lines changed

4 files changed

+218
-4
lines changed
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/*
2+
* Copyright 2018 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.data.jdbc.mapping.model;
17+
18+
import java.lang.annotation.Documented;
19+
import java.lang.annotation.ElementType;
20+
import java.lang.annotation.Retention;
21+
import java.lang.annotation.RetentionPolicy;
22+
import java.lang.annotation.Target;
23+
24+
/**
25+
* The annotation to configure a mapping database column.
26+
*
27+
* @author Kazuki Shimizu
28+
* @since 1.0
29+
*/
30+
@Retention(RetentionPolicy.RUNTIME)
31+
@Target({ElementType.FIELD, ElementType.METHOD})
32+
@Documented
33+
public @interface Column {
34+
35+
/**
36+
* The mapping column name.
37+
*/
38+
String value();
39+
40+
}

src/main/java/org/springframework/data/jdbc/mapping/model/NamingStrategy.java

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@
1515
*/
1616
package org.springframework.data.jdbc.mapping.model;
1717

18+
import org.springframework.core.annotation.AnnotatedElementUtils;
19+
20+
import java.util.Optional;
21+
1822
/**
1923
* Interface and default implementation of a naming strategy. Defaults to no schema, table name based on {@link Class}
2024
* and column name based on {@link JdbcPersistentProperty}.
@@ -45,17 +49,23 @@ default String getSchema() {
4549
}
4650

4751
/**
48-
* Look up the {@link Class}'s simple name.
52+
* Look up the {@link Class}'s simple name or {@link Table#value()}.
4953
*/
5054
default String getTableName(Class<?> type) {
51-
return type.getSimpleName();
55+
Table table = AnnotatedElementUtils.findMergedAnnotation(type, Table.class);
56+
return Optional.ofNullable(table)//
57+
.map(Table::value)//
58+
.orElse(type.getSimpleName());
5259
}
5360

5461
/**
55-
* Look up the {@link JdbcPersistentProperty}'s name.
62+
* Look up the {@link JdbcPersistentProperty}'s name or {@link Column#value()}.
5663
*/
5764
default String getColumnName(JdbcPersistentProperty property) {
58-
return property.getName();
65+
Column column = property.findAnnotation(Column.class);
66+
return Optional.ofNullable(column)//
67+
.map(Column::value)//
68+
.orElse(property.getName());
5969
}
6070

6171
default String getQualifiedTableName(Class<?> type) {
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/*
2+
* Copyright 2018 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.data.jdbc.mapping.model;
17+
18+
import java.lang.annotation.Documented;
19+
import java.lang.annotation.ElementType;
20+
import java.lang.annotation.Inherited;
21+
import java.lang.annotation.Retention;
22+
import java.lang.annotation.RetentionPolicy;
23+
import java.lang.annotation.Target;
24+
25+
/**
26+
* The annotation to configure a mapping database table.
27+
*
28+
* @author Kazuki Shimizu
29+
* @since 1.0
30+
*/
31+
@Retention(RetentionPolicy.RUNTIME)
32+
@Target(ElementType.TYPE)
33+
@Documented
34+
@Inherited
35+
public @interface Table {
36+
37+
/**
38+
* The mapping table name.
39+
*/
40+
String value();
41+
42+
}
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
/*
2+
* Copyright 2018 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.data.jdbc.mapping.model;
17+
18+
import org.junit.Test;
19+
import org.springframework.data.annotation.Id;
20+
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations;
21+
22+
import java.time.LocalDateTime;
23+
import java.util.List;
24+
25+
import static org.assertj.core.api.Assertions.assertThat;
26+
import static org.mockito.Mockito.mock;
27+
28+
/**
29+
* Unit tests for the {@link NamingStrategy}.
30+
*
31+
* @author Kazuki Shimizu
32+
*/
33+
public class NamingStrategyUnitTests {
34+
35+
private final NamingStrategy target = NamingStrategy.INSTANCE;
36+
private final JdbcMappingContext context = new JdbcMappingContext(target, mock(NamedParameterJdbcOperations.class), mock(ConversionCustomizer.class));
37+
private final JdbcPersistentEntity<?> persistentEntity = context.getRequiredPersistentEntity(DummyEntity.class);
38+
39+
@Test
40+
public void getTableName() {
41+
assertThat(target.getTableName(persistentEntity.getType()))
42+
.isEqualTo("DummyEntity");
43+
assertThat(target.getTableName(DummySubEntity.class))
44+
.isEqualTo("dummy_sub_entity"); // DATAJDBC-106
45+
}
46+
47+
@Test // DATAJDBC-106
48+
public void getTableNameWithTableAnnotation() {
49+
assertThat(target.getTableName(DummySubEntity.class))
50+
.isEqualTo("dummy_sub_entity");
51+
}
52+
53+
@Test
54+
public void getColumnName() {
55+
assertThat(target.getColumnName(persistentEntity.getPersistentProperty("id")))
56+
.isEqualTo("id");
57+
assertThat(target.getColumnName(persistentEntity.getPersistentProperty("createdAt")))
58+
.isEqualTo("createdAt");
59+
assertThat(target.getColumnName(persistentEntity.getPersistentProperty("dummySubEntities")))
60+
.isEqualTo("dummySubEntities");
61+
}
62+
63+
@Test // DATAJDBC-106
64+
public void getColumnNameWithColumnAnnotation() {
65+
assertThat(target.getColumnName(persistentEntity.getPersistentProperty("name")))
66+
.isEqualTo("dummy_name");
67+
assertThat(target.getColumnName(persistentEntity.getPersistentProperty("lastUpdatedAt")))
68+
.isEqualTo("dummy_last_updated_at");
69+
}
70+
71+
@Test
72+
public void getReverseColumnName() {
73+
assertThat(target.getReverseColumnName(persistentEntity.getPersistentProperty("dummySubEntities")))
74+
.isEqualTo("DummyEntity");
75+
}
76+
77+
@Test
78+
public void getKeyColumn() {
79+
assertThat(target.getKeyColumn(persistentEntity.getPersistentProperty("dummySubEntities")))
80+
.isEqualTo("DummyEntity_key");
81+
}
82+
83+
@Test
84+
public void getSchema() {
85+
assertThat(target.getSchema())
86+
.isEmpty();
87+
}
88+
89+
@Test
90+
public void getQualifiedTableName() {
91+
assertThat(target.getQualifiedTableName(persistentEntity.getType()))
92+
.isEqualTo("DummyEntity");
93+
94+
NamingStrategy strategy = new NamingStrategy() {
95+
@Override
96+
public String getSchema() {
97+
return "schema";
98+
}
99+
};
100+
assertThat(strategy.getQualifiedTableName(persistentEntity.getType()))
101+
.isEqualTo("schema.DummyEntity");
102+
}
103+
104+
private static class DummyEntity {
105+
@Id
106+
private int id;
107+
@Column("dummy_name")
108+
private String name;
109+
private LocalDateTime createdAt;
110+
private LocalDateTime lastUpdatedAt;
111+
private List<DummySubEntity> dummySubEntities;
112+
@Column("dummy_last_updated_at")
113+
public LocalDateTime getLastUpdatedAt() {
114+
return LocalDateTime.now();
115+
}
116+
}
117+
118+
@Table("dummy_sub_entity")
119+
private static class DummySubEntity {
120+
}
121+
122+
}

0 commit comments

Comments
 (0)