Skip to content

Commit f487eab

Browse files
committed
mybatis#101: Update testing by adding a large data load with a comparison between property- and constructor based mapping
1 parent f9dfb6b commit f487eab

22 files changed

+1201
-198
lines changed

src/test/java/org/apache/ibatis/immutable/ImmutableConstructorTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ void shouldSelectImmutableBlogUsingCollectionInConstructor() {
9696

9797
final ImmutablePost postTwo = posts.get(1);
9898
assertThat(postTwo).isNotNull().isInstanceOf(ImmutablePost.class);
99-
assertThat(postOne.getCreatedOn()).isNotNull();
99+
assertThat(postTwo.getCreatedOn()).isNotNull();
100100
assertThat(postTwo.getAuthor()).isNotNull();
101101
assertThat(postTwo.getSection()).isEqualTo(Section.VIDEOS);
102102
assertThat(postTwo.getSubject()).isEqualTo("Paul Hogan on Toy Dogs");
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
/*
2+
* Copyright 2009-2024 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+
* https://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.apache.ibatis.submitted.collection_injection;
17+
18+
import static org.assertj.core.api.Assertions.assertThat;
19+
20+
import java.io.Reader;
21+
22+
import org.apache.ibatis.BaseDataTest;
23+
import org.apache.ibatis.io.Resources;
24+
import org.apache.ibatis.session.SqlSession;
25+
import org.apache.ibatis.session.SqlSessionFactory;
26+
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
27+
import org.apache.ibatis.submitted.collection_injection.immutable.*;
28+
import org.apache.ibatis.submitted.collection_injection.immutable.ImmutableRoomDetail;
29+
import org.apache.ibatis.submitted.collection_injection.property.Defect;
30+
import org.apache.ibatis.submitted.collection_injection.property.Furniture;
31+
import org.apache.ibatis.submitted.collection_injection.property.House;
32+
import org.apache.ibatis.submitted.collection_injection.property.HouseMapper;
33+
import org.apache.ibatis.submitted.collection_injection.property.Room;
34+
import org.apache.ibatis.submitted.collection_injection.property.RoomDetail;
35+
import org.junit.jupiter.api.Assertions;
36+
import org.junit.jupiter.api.BeforeAll;
37+
import org.junit.jupiter.api.Test;
38+
39+
class CollectionInjectionTest {
40+
41+
private static SqlSessionFactory sqlSessionFactory;
42+
43+
@BeforeAll
44+
static void setUp() throws Exception {
45+
try (Reader reader = Resources
46+
.getResourceAsReader("org/apache/ibatis/submitted/collection_injection/mybatis_config.xml")) {
47+
sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
48+
}
49+
50+
BaseDataTest.runScript(sqlSessionFactory.getConfiguration().getEnvironment().getDataSource(),
51+
"org/apache/ibatis/submitted/collection_injection/create_db.sql");
52+
BaseDataTest.runScript(sqlSessionFactory.getConfiguration().getEnvironment().getDataSource(),
53+
"org/apache/ibatis/submitted/collection_injection/data_load_small.sql");
54+
}
55+
56+
@Test
57+
void shouldSelectAllHousesUsingConstructorInjection() {
58+
try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
59+
final ImmutableHouseMapper mapper = sqlSession.getMapper(ImmutableHouseMapper.class);
60+
ImmutableHouse house = mapper.getHouse(1);
61+
Assertions.assertNotNull(house);
62+
63+
final StringBuilder builder = new StringBuilder();
64+
builder.append("\n").append(house.getName());
65+
for (ImmutableRoom room : house.getRooms()) {
66+
ImmutableRoomDetail roomDetail = room.getRoomDetail();
67+
String detailString = String.format(" (size=%d, height=%d, type=%s)", roomDetail.getRoomSize(),
68+
roomDetail.getWallHeight(), roomDetail.getWallType());
69+
builder.append("\n").append("\t").append(room.getName()).append(detailString);
70+
for (ImmutableFurniture furniture : room.getFurniture()) {
71+
builder.append("\n").append("\t\t").append(furniture.getDescription());
72+
for (ImmutableDefect defect : furniture.getDefects()) {
73+
builder.append("\n").append("\t\t\t").append(defect.getDefect());
74+
}
75+
}
76+
}
77+
78+
assertResult(builder);
79+
}
80+
}
81+
82+
@Test
83+
void shouldSelectAllHousesUsingPropertyInjection() {
84+
try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
85+
final HouseMapper mapper = sqlSession.getMapper(HouseMapper.class);
86+
final House house = mapper.getHouse(1);
87+
Assertions.assertNotNull(house);
88+
89+
final StringBuilder builder = new StringBuilder();
90+
builder.append("\n").append(house.getName());
91+
for (Room room : house.getRooms()) {
92+
RoomDetail roomDetail = room.getRoomDetail();
93+
String detailString = String.format(" (size=%d, height=%d, type=%s)", roomDetail.getRoomSize(),
94+
roomDetail.getWallHeight(), roomDetail.getWallType());
95+
builder.append("\n").append("\t").append(room.getName()).append(detailString);
96+
for (Furniture furniture : room.getFurniture()) {
97+
builder.append("\n").append("\t\t").append(furniture.getDescription());
98+
for (Defect defect : furniture.getDefects()) {
99+
builder.append("\n").append("\t\t\t").append(defect.getDefect());
100+
}
101+
}
102+
}
103+
104+
assertResult(builder);
105+
}
106+
}
107+
108+
private static void assertResult(StringBuilder builder) {
109+
String expected = "\nMyBatis Headquarters" + "\n\tKitchen (size=25, height=20, type=Brick)" + "\n\t\tCoffee machine"
110+
+ "\n\t\t\tDoes not work" + "\n\t\tFridge" + "\n\tDining room (size=100, height=10, type=Wood)" + "\n\t\tTable"
111+
+ "\n\tProgramming room (size=200, height=15, type=Steel)" + "\n\t\tBig screen" + "\n\t\tLaptop"
112+
+ "\n\t\t\tCannot run intellij";
113+
114+
assertThat(builder.toString()).isNotEmpty().isEqualTo(expected);
115+
}
116+
}

src/test/java/org/apache/ibatis/submitted/collection_injection/ImmutableCollectionConstructorTest.java

Lines changed: 0 additions & 89 deletions
This file was deleted.
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
/*
2+
* Copyright 2009-2024 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+
* https://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.apache.ibatis.submitted.collection_injection;
17+
18+
import org.apache.ibatis.BaseDataTest;
19+
import org.apache.ibatis.io.Resources;
20+
import org.apache.ibatis.session.SqlSession;
21+
import org.apache.ibatis.session.SqlSessionFactory;
22+
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
23+
import org.apache.ibatis.submitted.collection_injection.immutable.*;
24+
import org.apache.ibatis.submitted.collection_injection.property.*;
25+
import org.junit.jupiter.api.BeforeAll;
26+
import org.junit.jupiter.api.Disabled;
27+
import org.junit.jupiter.api.Test;
28+
29+
import java.io.Reader;
30+
import java.util.HashMap;
31+
import java.util.List;
32+
import java.util.Map;
33+
import java.util.Random;
34+
import java.util.concurrent.atomic.AtomicLong;
35+
36+
import static org.assertj.core.api.Assertions.assertThat;
37+
38+
class PropertyVsConstructorPerformanceTest {
39+
40+
private static SqlSessionFactory sqlSessionFactory;
41+
42+
@BeforeAll
43+
static void setUp() throws Exception {
44+
try (Reader reader = Resources
45+
.getResourceAsReader("org/apache/ibatis/submitted/collection_injection/mybatis_config.xml")) {
46+
sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
47+
}
48+
49+
BaseDataTest.runScript(sqlSessionFactory.getConfiguration().getEnvironment().getDataSource(),
50+
"org/apache/ibatis/submitted/collection_injection/create_db.sql");
51+
52+
BaseDataTest.runScript(sqlSessionFactory.getConfiguration().getEnvironment().getDataSource(),
53+
"org/apache/ibatis/submitted/collection_injection/data_load_large.sql");
54+
55+
warmup();
56+
}
57+
58+
static void warmup() {
59+
for (int i = 0; i < 50; i++) {
60+
try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
61+
final HouseMapper mapper = sqlSession.getMapper(HouseMapper.class);
62+
final ImmutableHouseMapper immutableHouseMapper = sqlSession.getMapper(ImmutableHouseMapper.class);
63+
64+
mapper.getHouse(i);
65+
immutableHouseMapper.getHouse(i);
66+
}
67+
}
68+
}
69+
70+
@Test
71+
@Disabled
72+
void runPerformanceTest() {
73+
final Random random = new Random();
74+
final long iterations = 1_000;
75+
final Map<Class<?>, AtomicLong> times = new HashMap<>(2);
76+
times.put(HouseMapper.class, new AtomicLong());
77+
times.put(ImmutableHouseMapper.class, new AtomicLong());
78+
79+
for (int i = 0; i < iterations * 2; i++) {
80+
if (random.nextInt() % 2 == 0) {
81+
try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
82+
final HouseMapper mapper = sqlSession.getMapper(HouseMapper.class);
83+
final long startTime = System.currentTimeMillis();
84+
List<House> allHouses = mapper.getAllHouses();
85+
assertThat(allHouses).isNotNull().hasSize(100);
86+
times.get(HouseMapper.class).addAndGet(System.currentTimeMillis() - startTime);
87+
}
88+
} else {
89+
try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
90+
final ImmutableHouseMapper mapper = sqlSession.getMapper(ImmutableHouseMapper.class);
91+
final long startTime = System.currentTimeMillis();
92+
List<ImmutableHouse> allHouses = mapper.getAllHouses();
93+
assertThat(allHouses).isNotNull().hasSize(100);
94+
times.get(ImmutableHouseMapper.class).addAndGet(System.currentTimeMillis() - startTime);
95+
}
96+
}
97+
}
98+
99+
System.out.println(times);
100+
System.out.println("Property:" + calculateActualTime(times, HouseMapper.class, iterations) + "ms");
101+
System.out.println("Constructor:" + calculateActualTime(times, ImmutableHouseMapper.class, iterations) + "ms");
102+
}
103+
104+
private double calculateActualTime(Map<Class<?>, AtomicLong> times, Class<?> mapper, long iterations) {
105+
return (double) times.get(mapper).get() / (double) iterations;
106+
}
107+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/*
2+
* Copyright 2009-2024 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+
* https://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.apache.ibatis.submitted.collection_injection.immutable;
17+
18+
public class ImmutableDefect {
19+
private final int id;
20+
private final String defect;
21+
22+
public ImmutableDefect(int id, String defect) {
23+
this.id = id;
24+
this.defect = defect;
25+
}
26+
27+
public int getId() {
28+
return id;
29+
}
30+
31+
public String getDefect() {
32+
return defect;
33+
}
34+
35+
@Override
36+
public String toString() {
37+
return "ImmutableDefect{" + "id=" + id + ", defect='" + defect + '\'' + '}';
38+
}
39+
}

0 commit comments

Comments
 (0)