1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.mybatis.dynamic.sql.insert.render;
17
18 import static org.mybatis.dynamic.sql.util.StringUtilities.spaceBefore;
19
20 import java.util.Objects;
21
22 import org.jspecify.annotations.Nullable;
23 import org.mybatis.dynamic.sql.insert.MultiRowInsertModel;
24 import org.mybatis.dynamic.sql.render.RenderingStrategy;
25
26 public class MultiRowInsertRenderer<T> {
27
28 private final MultiRowInsertModel<T> model;
29 private final MultiRowValuePhraseVisitor visitor;
30
31 private MultiRowInsertRenderer(Builder<T> builder) {
32 model = Objects.requireNonNull(builder.model);
33
34 visitor = new MultiRowValuePhraseVisitor(Objects.requireNonNull(builder.renderingStrategy),
35 "records[%s]");
36 }
37
38 public MultiRowInsertStatementProvider<T> render() {
39 FieldAndValueCollector collector = model.columnMappings()
40 .map(m -> m.accept(visitor))
41 .collect(FieldAndValueCollector.collect());
42
43 String insertStatement = calculateInsertStatement(collector);
44
45 return new DefaultMultiRowInsertStatementProvider.Builder<T>().withRecords(model.records())
46 .withInsertStatement(insertStatement)
47 .build();
48 }
49
50 private String calculateInsertStatement(FieldAndValueCollector collector) {
51 String statementStart = InsertRenderingUtilities.calculateInsertStatementStart(model.table());
52 String columnsPhrase = collector.columnsPhrase();
53 String valuesPhrase = collector.multiRowInsertValuesPhrase(model.recordCount());
54
55 return statementStart + spaceBefore(columnsPhrase) + spaceBefore(valuesPhrase);
56 }
57
58 public static <T> Builder<T> withMultiRowInsertModel(MultiRowInsertModel<T> model) {
59 return new Builder<T>().withMultiRowInsertModel(model);
60 }
61
62 public static class Builder<T> {
63 private @Nullable MultiRowInsertModel<T> model;
64 private @Nullable RenderingStrategy renderingStrategy;
65
66 public Builder<T> withMultiRowInsertModel(MultiRowInsertModel<T> model) {
67 this.model = model;
68 return this;
69 }
70
71 public Builder<T> withRenderingStrategy(RenderingStrategy renderingStrategy) {
72 this.renderingStrategy = renderingStrategy;
73 return this;
74 }
75
76 public MultiRowInsertRenderer<T> build() {
77 return new MultiRowInsertRenderer<>(this);
78 }
79 }
80 }