1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.springframework.batch.item.database;
18
19 import java.sql.Connection;
20 import java.sql.PreparedStatement;
21 import java.sql.ResultSet;
22 import java.sql.SQLException;
23
24 import org.springframework.jdbc.core.PreparedStatementSetter;
25 import org.springframework.jdbc.core.RowMapper;
26 import org.springframework.jdbc.support.JdbcUtils;
27 import org.springframework.util.Assert;
28 import org.springframework.util.ClassUtils;
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53 @SuppressWarnings("rawtypes")
54 public class JdbcCursorItemReader<T> extends AbstractCursorItemReader<T> {
55
56 PreparedStatement preparedStatement;
57
58 PreparedStatementSetter preparedStatementSetter;
59
60 String sql;
61
62 RowMapper rowMapper;
63
64 public JdbcCursorItemReader() {
65 super();
66 setName(ClassUtils.getShortName(JdbcCursorItemReader.class));
67 }
68
69
70
71
72
73
74 public void setRowMapper(RowMapper rowMapper) {
75 this.rowMapper = rowMapper;
76 }
77
78
79
80
81
82
83
84
85 public void setSql(String sql) {
86 this.sql = sql;
87 }
88
89
90
91
92
93
94
95 public void setPreparedStatementSetter(PreparedStatementSetter preparedStatementSetter) {
96 this.preparedStatementSetter = preparedStatementSetter;
97 }
98
99
100
101
102
103
104
105 @Override
106 public void afterPropertiesSet() throws Exception {
107 super.afterPropertiesSet();
108 Assert.notNull(sql, "The SQL query must be provided");
109 Assert.notNull(rowMapper, "RowMapper must be provided");
110 }
111
112
113 @Override
114 protected void openCursor(Connection con) {
115 try {
116 if (isUseSharedExtendedConnection()) {
117 preparedStatement = con.prepareStatement(sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY,
118 ResultSet.HOLD_CURSORS_OVER_COMMIT);
119 }
120 else {
121 preparedStatement = con.prepareStatement(sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
122 }
123 applyStatementSettings(preparedStatement);
124 if (this.preparedStatementSetter != null) {
125 preparedStatementSetter.setValues(preparedStatement);
126 }
127 this.rs = preparedStatement.executeQuery();
128 handleWarnings(preparedStatement);
129 }
130 catch (SQLException se) {
131 close();
132 throw getExceptionTranslator().translate("Executing query", getSql(), se);
133 }
134
135 }
136
137
138 @Override
139 @SuppressWarnings("unchecked")
140 protected T readCursor(ResultSet rs, int currentRow) throws SQLException {
141 return (T) rowMapper.mapRow(rs, currentRow);
142 }
143
144
145
146
147 @Override
148 protected void cleanupOnClose() throws Exception {
149 JdbcUtils.closeStatement(this.preparedStatement);
150 }
151
152 @Override
153 public String getSql() {
154 return this.sql;
155 }
156 }