File notes/code/java/AdvancedProg.java changed (mode: 100644) (index d39ae04..22a3910) |
... |
... |
import java.sql.*; |
17 |
17 |
public class AdvancedProg { |
public class AdvancedProg { |
18 |
18 |
public static void main(String[] args) { |
public static void main(String[] args) { |
19 |
19 |
try ( |
try ( |
20 |
|
|
|
21 |
|
// I. Passing options to the dababse |
|
22 |
|
|
|
23 |
|
// start snippet passing-options |
|
24 |
|
Connection conn = |
|
25 |
|
DriverManager.getConnection( |
|
26 |
|
"jdbc:mysql://localhost:3306/HW_DBPROG" |
|
27 |
|
+ "?user=testuser" |
|
28 |
|
+ "&password=password" |
|
29 |
|
+ "&allowMultiQueries=true" |
|
30 |
|
+ "&createDatabaseIfNotExist=true" |
|
31 |
|
+ "&useSSL=true"); |
|
|
20 |
|
// I. Passing options to the database |
|
21 |
|
|
|
22 |
|
// start snippet passing-options |
|
23 |
|
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/HW_DBPROG" |
|
24 |
|
+ "?user=testuser" |
|
25 |
|
+ "&password=password" |
|
26 |
|
+ "&allowMultiQueries=true" |
|
27 |
|
+ "&createDatabaseIfNotExist=true" |
|
28 |
|
+ "&useSSL=true"); |
32 |
29 |
// end snippet passing-options |
// end snippet passing-options |
33 |
30 |
|
|
34 |
31 |
Statement stmt = conn.createStatement(); ) { |
Statement stmt = conn.createStatement(); ) { |
35 |
|
/* |
|
36 |
|
* Below, we drop the schema and re-create it to allow multiple execution of the |
|
37 |
|
* program. You can ignore this part if you want. |
|
38 |
|
*/ |
|
|
32 |
|
|
|
33 |
|
/* |
|
34 |
|
* Below, we drop the schema and re-create it to allow multiple execution of the |
|
35 |
|
* program. You can ignore this part if you want. |
|
36 |
|
*/ |
39 |
37 |
|
|
40 |
|
stmt.execute( |
|
|
38 |
|
stmt.execute( |
41 |
39 |
"DROP SCHEMA IF EXISTS HW_DBPROG;" + "CREATE SCHEMA HW_DBPROG;" + "USE HW_DBPROG;"); |
"DROP SCHEMA IF EXISTS HW_DBPROG;" + "CREATE SCHEMA HW_DBPROG;" + "USE HW_DBPROG;"); |
42 |
40 |
|
|
43 |
|
// II. Creating a table and reading its meta-data |
|
|
41 |
|
// II. Creating a table and reading its meta-data |
44 |
42 |
|
|
45 |
|
// start snippet table-creation |
|
46 |
|
stmt.execute( |
|
47 |
|
"CREATE TABLE DVD (" |
|
|
43 |
|
// start snippet table-creation |
|
44 |
|
stmt.execute( |
|
45 |
|
"CREATE TABLE DVD (" |
48 |
46 |
+ "Title CHAR(25) PRIMARY KEY, " |
+ "Title CHAR(25) PRIMARY KEY, " |
49 |
47 |
+ "Minutes INTEGER, " |
+ "Minutes INTEGER, " |
50 |
48 |
+ "Price DOUBLE)"); |
+ "Price DOUBLE)"); |
51 |
|
// end snippet table-creation |
|
52 |
|
|
|
53 |
|
// start snippet table-metadata-1 |
|
54 |
|
DatabaseMetaData md = conn.getMetaData(); |
|
55 |
|
|
|
56 |
|
ResultSet rs = md.getTables("HW_DBPROG", null, "%", null); |
|
57 |
|
// end snippet table-metadata-1 |
|
58 |
|
|
|
59 |
|
// start snippet table-metadata-2 |
|
60 |
|
while (rs.next()) { |
|
61 |
|
System.out.println(rs.getString(3)); |
|
62 |
|
} |
|
63 |
|
// end snippet table-metadata-2 |
|
64 |
|
|
|
65 |
|
// III. Inserting values |
|
66 |
|
|
|
67 |
|
// start snippet inserting-1 |
|
68 |
|
String sqlStatement = "INSERT INTO DVD VALUES ('Gone With The Wind', 221, 3);"; |
|
69 |
|
int rowsAffected = stmt.executeUpdate(sqlStatement); |
|
70 |
|
System.out.print(sqlStatement + " changed " + rowsAffected + " row(s).\n"); |
|
71 |
|
// end snippet inserting-1 |
|
72 |
|
|
|
73 |
|
// start snippet inserting-2 |
|
74 |
|
String insert1 = "INSERT INTO DVD VALUES ('Aa', 129, 0.2)"; |
|
75 |
|
String insert2 = "INSERT INTO DVD VALUES ('Bb', 129, 0.2)"; |
|
76 |
|
|
|
77 |
|
stmt.executeUpdate(insert1 + ";" + insert2); |
|
78 |
|
// end snippet inserting-2 |
|
79 |
|
|
|
80 |
|
// start snippet inserting-3 |
|
81 |
|
String insert3 = "INSERT INTO DVD VALUES ('Cc', 129, 0.2)"; |
|
82 |
|
String insert4 = "INSERT INTO DVD VALUES ('DD', 129, 0.2)"; |
|
83 |
|
stmt.addBatch(insert3); |
|
84 |
|
stmt.addBatch(insert4); |
|
85 |
|
stmt.executeBatch(); |
|
86 |
|
// end snippet inserting-3 |
|
87 |
|
|
|
88 |
|
// IV. Prepared Statements |
|
89 |
|
|
|
90 |
|
// start snippet prepared-queries-1 |
|
91 |
|
/* |
|
92 |
|
* We create a string with an empty slot, |
|
93 |
|
* represented by "?". |
|
94 |
|
*/ |
|
95 |
|
sqlStatement = "SELECT title FROM DVD WHERE Price <= ?"; |
|
96 |
|
/* |
|
97 |
|
* We create a PreparedStatement object, using that string with an |
|
98 |
|
* empty slot. |
|
99 |
|
*/ |
|
100 |
|
PreparedStatement ps = conn.prepareStatement(sqlStatement); |
|
101 |
|
|
|
102 |
|
/* |
|
103 |
|
* Then, we "fill" the first slot with the value of a variable. |
|
104 |
|
*/ |
|
105 |
|
double maxprice = 0.5; |
|
106 |
|
ps.setDouble(1, maxprice); |
|
107 |
|
/* |
|
108 |
|
* Finally, we can execute the query, and display the results. |
|
109 |
|
*/ |
|
110 |
|
ResultSet result = ps.executeQuery(); |
|
111 |
|
|
|
112 |
|
System.out.printf("For %.2f you can get:\n", maxprice); |
|
113 |
|
|
|
114 |
|
while (result.next()) { |
|
115 |
|
System.out.printf("\t %s \n", result.getString(1)); |
|
116 |
|
} |
|
117 |
|
// end snippet prepared-queries-1 |
|
118 |
|
|
|
119 |
|
// start snippet prepared-queries-2 |
|
120 |
|
sqlStatement = |
|
121 |
|
"INSERT INTO DVD VALUES (?, ?, ?)"; // Now, our string has 3 empty slots, and it is an |
|
122 |
|
// INSERT statement. |
|
123 |
|
PreparedStatement preparedStatement = conn.prepareStatement(sqlStatement); |
|
124 |
|
|
|
125 |
|
preparedStatement.setString(1, "The Great Dictator"); |
|
126 |
|
preparedStatement.setInt(2, 124); |
|
127 |
|
preparedStatement.setDouble(3, 5.4); |
|
128 |
|
|
|
129 |
|
rowsAffected = preparedStatement.executeUpdate(); |
|
130 |
|
// You can check "by hand" that this statement was correctly |
|
131 |
|
// executed. Note that the toString method is quite verbose. |
|
132 |
|
System.out.print(preparedStatement.toString() + " changed " + rowsAffected + " row(s).\n"); |
|
133 |
|
// end snippet prepared-queries-2 |
|
134 |
|
|
|
135 |
|
// start snippet prepared-queries-3 |
|
136 |
|
preparedStatement.setString(1, "The Great Dictator"); |
|
137 |
|
preparedStatement.setString(2, "Not-an-integer"); |
|
138 |
|
preparedStatement.setString(3, "Not-a-double"); |
|
139 |
|
// This command will make your program crash. |
|
140 |
|
// rowsAffected = preparedStatement.executeUpdate(); |
|
141 |
|
// end snippet prepared-queries-3 |
|
142 |
|
|
|
143 |
|
// start snippet prepared-queries-4 |
|
144 |
|
for (int i = 1; i < 5; i++) { |
|
145 |
|
preparedStatement.setString(1, "Saw " + i); |
|
146 |
|
preparedStatement.setInt(2, 100); |
|
147 |
|
preparedStatement.setDouble(3, .5); |
|
148 |
|
preparedStatement.executeUpdate(); |
|
149 |
|
} |
|
150 |
|
// end snippet prepared-queries-4 |
|
151 |
|
|
|
152 |
|
// V. Reading backward and writing in ResultSets |
|
153 |
|
|
|
154 |
|
// start snippet new-statement-1 |
|
155 |
|
Statement stmtNew = |
|
156 |
|
conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE); |
|
157 |
|
// end snippet new-statement-1 |
|
158 |
|
|
|
159 |
|
// Reading backward |
|
160 |
|
|
|
161 |
|
sqlStatement = "SELECT title FROM DVD WHERE Price < 1;"; |
|
162 |
|
result = stmtNew.executeQuery(sqlStatement); |
|
163 |
|
|
|
164 |
|
System.out.println("For $1, you can get:"); |
|
165 |
|
|
|
166 |
|
if (result.last()) { // We can jump to the end of the ResultSet |
|
167 |
|
System.out.print(result.getString("Title") + " "); |
|
168 |
|
} |
|
169 |
|
|
|
170 |
|
System.out.print("and also, (in reverse order)"); |
|
171 |
|
|
|
172 |
|
while (result.previous()) { // Now we can scroll back! |
|
173 |
|
System.out.print(result.getString("Title") + " "); |
|
174 |
|
} |
|
175 |
|
|
|
176 |
|
// Changing the values |
|
177 |
|
|
|
178 |
|
System.out.print("\n\nLet us apply a 50% discount. Currently, the prices are:\n"); |
|
179 |
|
|
|
180 |
|
sqlStatement = "SELECT title, price FROM DVD;"; |
|
181 |
|
result = stmtNew.executeQuery(sqlStatement); |
|
182 |
|
while (result.next()) { |
|
183 |
|
System.out.printf("%20s \t $%3.2f\n", result.getString("title"), result.getDouble("price")); |
|
184 |
|
} |
|
185 |
|
|
|
186 |
|
result.absolute(0); // We need to scroll back! |
|
187 |
|
|
|
188 |
|
while (result.next()) { |
|
189 |
|
double current = result.getDouble("price"); |
|
190 |
|
result.updateDouble("price", (current * 0.5)); |
|
191 |
|
result.updateRow(); |
|
192 |
|
} |
|
193 |
|
System.out.print("\n\nAfter update, the prices are:\n"); |
|
194 |
|
|
|
195 |
|
result.absolute(0); // We need to scroll back! |
|
196 |
|
|
|
197 |
|
while (result.next()) { |
|
198 |
|
System.out.printf("%20s \t $%3.2f\n", result.getString("title"), result.getDouble("price")); |
|
199 |
|
} |
|
200 |
|
|
|
201 |
|
conn.close(); |
|
202 |
|
} catch (SQLException ex) { |
|
203 |
|
ex.printStackTrace(); |
|
204 |
|
} |
|
|
49 |
|
// end snippet table-creation |
|
50 |
|
|
|
51 |
|
// start snippet table-metadata-1 |
|
52 |
|
DatabaseMetaData md = conn.getMetaData(); |
|
53 |
|
|
|
54 |
|
ResultSet rs = md.getTables("HW_DBPROG", null, "%", null); |
|
55 |
|
// end snippet table-metadata-1 |
|
56 |
|
|
|
57 |
|
// start snippet table-metadata-2 |
|
58 |
|
while (rs.next()) { |
|
59 |
|
System.out.println(rs.getString(3)); |
|
60 |
|
} |
|
61 |
|
// end snippet table-metadata-2 |
|
62 |
|
|
|
63 |
|
// III. Inserting values |
|
64 |
|
|
|
65 |
|
// start snippet inserting-1 |
|
66 |
|
String sqlStatement = "INSERT INTO DVD VALUES ('Gone With The Wind', 221, 3);"; |
|
67 |
|
int rowsAffected = stmt.executeUpdate(sqlStatement); |
|
68 |
|
System.out.print(sqlStatement + " changed " + rowsAffected + " row(s).\n"); |
|
69 |
|
// end snippet inserting-1 |
|
70 |
|
|
|
71 |
|
// start snippet inserting-2 |
|
72 |
|
String insert1 = "INSERT INTO DVD VALUES ('Aa', 129, 0.2)"; |
|
73 |
|
String insert2 = "INSERT INTO DVD VALUES ('Bb', 129, 0.2)"; |
|
74 |
|
|
|
75 |
|
stmt.executeUpdate(insert1 + ";" + insert2); |
|
76 |
|
// end snippet inserting-2 |
|
77 |
|
|
|
78 |
|
// start snippet inserting-3 |
|
79 |
|
String insert3 = "INSERT INTO DVD VALUES ('Cc', 129, 0.2)"; |
|
80 |
|
String insert4 = "INSERT INTO DVD VALUES ('DD', 129, 0.2)"; |
|
81 |
|
stmt.addBatch(insert3); |
|
82 |
|
stmt.addBatch(insert4); |
|
83 |
|
stmt.executeBatch(); |
|
84 |
|
// end snippet inserting-3 |
|
85 |
|
|
|
86 |
|
// IV. Prepared Statements |
|
87 |
|
|
|
88 |
|
// start snippet prepared-queries-1 |
|
89 |
|
|
|
90 |
|
/* |
|
91 |
|
* We create a string with an empty slot, |
|
92 |
|
* represented by "?". |
|
93 |
|
*/ |
|
94 |
|
sqlStatement = "SELECT title FROM DVD WHERE Price <= ?"; |
|
95 |
|
/* |
|
96 |
|
* We create a PreparedStatement object, using that string with an |
|
97 |
|
* empty slot. |
|
98 |
|
*/ |
|
99 |
|
PreparedStatement ps = conn.prepareStatement(sqlStatement); |
|
100 |
|
|
|
101 |
|
/* |
|
102 |
|
* Then, we "fill" the first slot with the value of a variable. |
|
103 |
|
*/ |
|
104 |
|
double maxprice = 0.5; |
|
105 |
|
ps.setDouble(1, maxprice); |
|
106 |
|
/* |
|
107 |
|
* Finally, we can execute the query, and display the results. |
|
108 |
|
*/ |
|
109 |
|
ResultSet result = ps.executeQuery(); |
|
110 |
|
|
|
111 |
|
System.out.printf("For %.2f you can get:\n", maxprice); |
|
112 |
|
|
|
113 |
|
while (result.next()) { |
|
114 |
|
System.out.printf("\t %s \n", result.getString(1)); |
|
115 |
|
} |
|
116 |
|
// end snippet prepared-queries-1 |
|
117 |
|
|
|
118 |
|
// start snippet prepared-queries-2 |
|
119 |
|
sqlStatement = "INSERT INTO DVD VALUES (?, ?, ?)"; |
|
120 |
|
// Now, our string has 3 empty slots, and it is an INSERT statement. |
|
121 |
|
PreparedStatement preparedStatement = conn.prepareStatement(sqlStatement); |
|
122 |
|
|
|
123 |
|
preparedStatement.setString(1, "The Great Dictator"); |
|
124 |
|
preparedStatement.setInt(2, 124); |
|
125 |
|
preparedStatement.setDouble(3, 5.4); |
|
126 |
|
|
|
127 |
|
rowsAffected = preparedStatement.executeUpdate(); |
|
128 |
|
/* You can check "by hand" that this statement was correctly |
|
129 |
|
* executed. Note that the toString method is quite verbose. |
|
130 |
|
*/ |
|
131 |
|
System.out.print(preparedStatement.toString() + " changed " + rowsAffected + " row(s).\n"); |
|
132 |
|
// end snippet prepared-queries-2 |
|
133 |
|
|
|
134 |
|
// start snippet prepared-queries-3 |
|
135 |
|
preparedStatement.setString(1, "The Great Dictator"); |
|
136 |
|
preparedStatement.setString(2, "Not-an-integer"); |
|
137 |
|
preparedStatement.setString(3, "Not-a-double"); |
|
138 |
|
|
|
139 |
|
/* This command will make your program crash: |
|
140 |
|
* rowsAffected = preparedStatement.executeUpdate(); |
|
141 |
|
*/ |
|
142 |
|
// end snippet prepared-queries-3 |
|
143 |
|
|
|
144 |
|
|
|
145 |
|
// start snippet prepared-queries-4 |
|
146 |
|
for (int i = 1; i < 5; i++) { |
|
147 |
|
preparedStatement.setString(1, "Saw " + i); |
|
148 |
|
preparedStatement.setInt(2, 100); |
|
149 |
|
preparedStatement.setDouble(3, .5); |
|
150 |
|
preparedStatement.executeUpdate(); |
|
151 |
|
} |
|
152 |
|
// end snippet prepared-queries-4 |
|
153 |
|
|
|
154 |
|
// V. Reading backward and writing in ResultSets |
|
155 |
|
|
|
156 |
|
// start snippet new-statement-1 |
|
157 |
|
Statement stmtNew = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE); |
|
158 |
|
// end snippet new-statement-1 |
|
159 |
|
|
|
160 |
|
// Reading backward |
|
161 |
|
sqlStatement = "SELECT title FROM DVD WHERE Price < 1;"; |
|
162 |
|
result = stmtNew.executeQuery(sqlStatement); |
|
163 |
|
|
|
164 |
|
System.out.println("For $1, you can get:"); |
|
165 |
|
|
|
166 |
|
if (result.last()) { |
|
167 |
|
// We can jump to the end of the ResultSet |
|
168 |
|
System.out.print(result.getString("Title") + " "); |
|
169 |
|
} |
|
170 |
|
|
|
171 |
|
System.out.print("and also, (in reverse order)"); |
|
172 |
|
|
|
173 |
|
while (result.previous()) { |
|
174 |
|
// Now we can scroll back! |
|
175 |
|
System.out.print(result.getString("Title") + " "); |
|
176 |
|
} |
|
177 |
|
|
|
178 |
|
// Changing the values |
|
179 |
|
System.out.print("\n\nLet us apply a 50% discount. Currently, the prices are:\n"); |
|
180 |
|
|
|
181 |
|
sqlStatement = "SELECT title, price FROM DVD;"; |
|
182 |
|
result = stmtNew.executeQuery(sqlStatement); |
|
183 |
|
while (result.next()) { |
|
184 |
|
System.out.printf("%20s \t $%3.2f\n", result.getString("title"), result.getDouble("price")); |
|
185 |
|
} |
|
186 |
|
|
|
187 |
|
// We need to scroll back! |
|
188 |
|
result.absolute(0); |
|
189 |
|
|
|
190 |
|
while (result.next()) { |
|
191 |
|
double current = result.getDouble("price"); |
|
192 |
|
result.updateDouble("price", (current * 0.5)); |
|
193 |
|
result.updateRow(); |
|
194 |
|
} |
|
195 |
|
System.out.print("\n\nAfter update, the prices are:\n"); |
|
196 |
|
|
|
197 |
|
// We need to scroll back! |
|
198 |
|
result.absolute(0); |
|
199 |
|
|
|
200 |
|
while (result.next()) { |
|
201 |
|
System.out.printf("%20s \t $%3.2f\n", result.getString("title"), result.getDouble("price")); |
|
202 |
|
} |
|
203 |
|
|
|
204 |
|
conn.close(); |
|
205 |
|
} catch (SQLException ex) { |
|
206 |
|
ex.printStackTrace(); |
|
207 |
|
} |
205 |
208 |
} |
} |
206 |
209 |
} |
} |
File notes/code/java/FirstProg.java changed (mode: 100644) (index 008b067..1792982) |
... |
... |
import java.sql.*; |
4 |
4 |
|
|
5 |
5 |
public class FirstProg { |
public class FirstProg { |
6 |
6 |
public static void main(String[] args) { |
public static void main(String[] args) { |
7 |
|
try (Connection conn = |
|
8 |
|
DriverManager.getConnection( |
|
9 |
|
"jdbc:mysql://localhost:3306/HW_EBOOKSHOP", "testuser", "password"); |
|
|
7 |
|
try (Connection conn = DriverManager.getConnection( |
|
8 |
|
"jdbc:mysql://localhost:3306/HW_EBOOKSHOP", "testuser", "password"); |
10 |
9 |
/* |
/* |
11 |
10 |
* If at execution time you receive an error that starts with |
* If at execution time you receive an error that starts with |
12 |
11 |
* "java.sql.SQLException: The server time zone value 'EDT' is unrecognized or |
* "java.sql.SQLException: The server time zone value 'EDT' is unrecognized or |
13 |
12 |
* represents more than one time zone. You must configure either the server ..." |
* represents more than one time zone. You must configure either the server ..." |
14 |
13 |
* add ?serverTimezone=UTC at the end of the previous string, |
* add ?serverTimezone=UTC at the end of the previous string, |
15 |
14 |
* i.e., replace the previous lines of code with: |
* i.e., replace the previous lines of code with: |
16 |
|
* Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/HW_EBOOKSHOP?serverTimezone=UTC", "testuser","password"); |
|
|
15 |
|
* Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/HW_EBOOKSHOP?serverTimezone=UTC", |
|
16 |
|
* "testuser","password"); |
17 |
17 |
* cf. for instance https://stackoverflow.com/q/26515700 |
* cf. for instance https://stackoverflow.com/q/26515700 |
18 |
18 |
* Or, change your server's configuration, cf. |
* Or, change your server's configuration, cf. |
19 |
19 |
* https://stackoverflow.com/a/44720416 |
* https://stackoverflow.com/a/44720416 |
20 |
20 |
*/ |
*/ |
21 |
|
Statement stmt = conn.createStatement(); ) { |
|
22 |
|
String strSelect = "SELECT title, price, qty FROM BOOKS WHERE qty > 40"; |
|
23 |
|
System.out.print("The SQL query is: " + strSelect + "\n"); |
|
24 |
|
ResultSet rset = stmt.executeQuery(strSelect); |
|
|
21 |
|
Statement stmt = conn.createStatement(); ) { |
|
22 |
|
String strSelect = "SELECT title, price, qty FROM BOOKS WHERE qty > 40"; |
|
23 |
|
System.out.print("The SQL query is: " + strSelect + "\n"); |
|
24 |
|
ResultSet rset = stmt.executeQuery(strSelect); |
25 |
25 |
|
|
26 |
|
System.out.println("The records selected are:"); |
|
27 |
|
int rowCount = 0; |
|
28 |
|
String title; |
|
29 |
|
double price; |
|
30 |
|
int qty; |
|
|
26 |
|
System.out.println("The records selected are:"); |
|
27 |
|
int rowCount = 0; |
|
28 |
|
String title; |
|
29 |
|
double price; |
|
30 |
|
int qty; |
31 |
31 |
|
|
32 |
|
while (rset.next()) { |
|
33 |
|
title = rset.getString("title"); |
|
34 |
|
price = rset.getDouble("price"); |
|
35 |
|
qty = rset.getInt("qty"); |
|
36 |
|
System.out.println(title + ", " + price + ", " + qty); |
|
37 |
|
rowCount++; |
|
38 |
|
} |
|
|
32 |
|
while (rset.next()) { |
|
33 |
|
title = rset.getString("title"); |
|
34 |
|
price = rset.getDouble("price"); |
|
35 |
|
qty = rset.getInt("qty"); |
|
36 |
|
System.out.println(title + ", " + price + ", " + qty); |
|
37 |
|
rowCount++; |
|
38 |
|
} |
39 |
39 |
|
|
40 |
|
System.out.println("Total number of records = " + rowCount); |
|
41 |
|
conn.close(); |
|
|
40 |
|
System.out.println("Total number of records = " + rowCount); |
|
41 |
|
conn.close(); |
42 |
42 |
|
|
43 |
|
} catch (SQLException ex) { |
|
44 |
|
ex.printStackTrace(); |
|
45 |
|
} |
|
|
43 |
|
} catch (SQLException ex) { |
|
44 |
|
ex.printStackTrace(); |
|
45 |
|
} |
46 |
46 |
} |
} |
47 |
47 |
} |
} |
File notes/code/java/GuestProgramSolution.java changed (mode: 100644) (index e9492ca..35bfb55) |
... |
... |
import java.util.Scanner; // Importing a java API to read from the keyboard. |
10 |
10 |
|
|
11 |
11 |
public class GuestProgram_Solution { |
public class GuestProgram_Solution { |
12 |
12 |
public static void main(String[] args) { |
public static void main(String[] args) { |
13 |
|
try (Connection conn = |
|
14 |
|
DriverManager.getConnection( |
|
15 |
|
"jdbc:mysql://localhost:3306/?user=testuser&password=password&allowMultiQueries=true"); |
|
16 |
|
Statement stmt = |
|
17 |
|
conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY); ) { |
|
18 |
|
stmt.execute( |
|
19 |
|
"DROP SCHEMA IF EXISTS HW_GUEST_PROGRAM;" |
|
|
13 |
|
try (Connection conn = DriverManager.getConnection( |
|
14 |
|
"jdbc:mysql://localhost:3306/?user=testuser&password=password&allowMultiQueries=true"); |
|
15 |
|
Statement stmt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY); ) { |
|
16 |
|
stmt.execute( |
|
17 |
|
"DROP SCHEMA IF EXISTS HW_GUEST_PROGRAM;" |
20 |
18 |
+ "CREATE SCHEMA HW_GUEST_PROGRAM;" |
+ "CREATE SCHEMA HW_GUEST_PROGRAM;" |
21 |
19 |
+ "USE HW_GUEST_PROGRAM;" |
+ "USE HW_GUEST_PROGRAM;" |
22 |
20 |
+ "CREATE TABLE GUEST(" |
+ "CREATE TABLE GUEST(" |
|
... |
... |
public class GuestProgram_Solution { |
29 |
27 |
+ ");" |
+ ");" |
30 |
28 |
+ "INSERT INTO BLACKLIST VALUES (\"Marcus Hells\");"); |
+ "INSERT INTO BLACKLIST VALUES (\"Marcus Hells\");"); |
31 |
29 |
|
|
32 |
|
System.out.print("How many guests do you have?\n"); |
|
33 |
|
Scanner key = new Scanner(System.in); |
|
34 |
|
int guest_total = key.nextInt(); |
|
|
30 |
|
System.out.print("How many guests do you have?\n"); |
|
31 |
|
Scanner key = new Scanner(System.in); |
|
32 |
|
int guest_total = key.nextInt(); |
35 |
33 |
|
|
36 |
|
key.nextLine(); // "Hack" to flush the buffer. Please ignore. |
|
|
34 |
|
key.nextLine(); // "Hack" to flush the buffer. Please ignore. |
37 |
35 |
|
|
38 |
|
// EXERCISE 1 |
|
39 |
|
// start snippet exercise-1-intro |
|
40 |
|
int guest_id; |
|
41 |
|
String guest_name; |
|
42 |
|
int counter = 0; |
|
43 |
|
// end snippet exercise-1-intro |
|
|
36 |
|
// EXERCISE 1 |
44 |
37 |
|
|
45 |
|
// start snippet exercise-1-batch |
|
46 |
|
while (counter < guest_total) { |
|
47 |
|
System.out.print( |
|
48 |
|
"Enter name of guest " + (counter + 1) + ".\n"); // Ask the name of the guest. |
|
49 |
|
guest_name = key.nextLine(); // Read the name of the guest. |
|
50 |
|
stmt.addBatch("INSERT INTO GUEST VALUES (" + counter + ", \"" + guest_name + "\", NULL)"); |
|
51 |
|
// Add to the batch the statement to insert the required data in the table |
|
52 |
|
counter++; |
|
53 |
|
} |
|
54 |
|
stmt.executeBatch(); // Execute the batch statement. |
|
|
38 |
|
// start snippet exercise-1-intro |
|
39 |
|
int guest_id; |
|
40 |
|
String guest_name; |
|
41 |
|
int counter = 0; |
|
42 |
|
// end snippet exercise-1-intro |
55 |
43 |
|
|
56 |
|
// end snippet exercise-1-batch |
|
|
44 |
|
// start snippet exercise-1-batch |
|
45 |
|
while (counter < guest_total) { |
|
46 |
|
// Ask the name of the guest. |
|
47 |
|
System.out.print("Enter name of guest " + (counter + 1) + ".\n"); |
|
48 |
|
// Read the name of the guest. |
|
49 |
|
guest_name = key.nextLine(); |
|
50 |
|
stmt.addBatch("INSERT INTO GUEST VALUES (" + counter + ", \"" + guest_name + "\", NULL)"); |
|
51 |
|
// Add to the batch the statement to insert the required data in the table |
|
52 |
|
counter++; |
|
53 |
|
} |
|
54 |
|
stmt.executeBatch(); // Execute the batch statement. |
|
55 |
|
// end snippet exercise-1-batch |
57 |
56 |
|
|
58 |
|
// Solution B |
|
59 |
|
/* |
|
60 |
|
* PreparedStatement ps = conn.prepareStatement("INSERT INTO GUEST VALUES(?, ?, NULL);"); |
|
61 |
|
* while (counter < guest_total) { |
|
62 |
|
* System.out.print("Enter name of guest " + (counter + 1) + ".\n"); |
|
63 |
|
* guest_name = key.nextLine(); |
|
64 |
|
* ps.setInt(1, counter); |
|
65 |
|
* ps.setString(2, guest_name); |
|
66 |
|
* ps.executeUpdate(); |
|
67 |
|
* counter++; |
|
68 |
|
* } |
|
69 |
|
*/ |
|
70 |
|
// Needed to test our solution to the following two exercises. |
|
71 |
|
stmt.execute("INSERT INTO GUEST VALUES (-1, \"Marcus Hells\", true);"); |
|
72 |
|
stmt.execute("INSERT INTO GUEST VALUES (-2, \"Marcus Hells\", false);"); |
|
|
57 |
|
// Solution B |
|
58 |
|
/* |
|
59 |
|
* PreparedStatement ps = conn.prepareStatement("INSERT INTO GUEST VALUES(?, ?, NULL);"); |
|
60 |
|
* while (counter < guest_total) { |
|
61 |
|
* System.out.print("Enter name of guest " + (counter + 1) + ".\n"); |
|
62 |
|
* guest_name = key.nextLine(); |
|
63 |
|
* ps.setInt(1, counter); |
|
64 |
|
* ps.setString(2, guest_name); |
|
65 |
|
* ps.executeUpdate(); |
|
66 |
|
* counter++; |
|
67 |
|
* } |
|
68 |
|
*/ |
|
69 |
|
// Needed to test our solution to the following two exercises. |
|
70 |
|
stmt.execute("INSERT INTO GUEST VALUES (-1, \"Marcus Hells\", true);"); |
|
71 |
|
stmt.execute("INSERT INTO GUEST VALUES (-2, \"Marcus Hells\", false);"); |
73 |
72 |
|
|
74 |
|
// start snippet exercise-2 |
|
75 |
|
ResultSet rset = |
|
76 |
|
stmt.executeQuery( |
|
77 |
|
"SELECT * FROM GUEST, BLACKLIST WHERE GUEST.Name = BLACKLIST.Name AND GUEST.Confirmed = true"); |
|
78 |
|
if (rset.next()) { |
|
79 |
|
System.out.print( |
|
|
73 |
|
// start snippet exercise-2 |
|
74 |
|
ResultSet rset = stmt.executeQuery( |
|
75 |
|
"SELECT * FROM GUEST, BLACKLIST WHERE GUEST.Name = BLACKLIST.Name AND GUEST.Confirmed = true"); |
|
76 |
|
if (rset.next()) { |
|
77 |
|
System.out.print( |
80 |
78 |
"Oh no, (at least) one of the guest from the black list confirmed their presence!\nThe name of the first one is " |
"Oh no, (at least) one of the guest from the black list confirmed their presence!\nThe name of the first one is " |
81 |
|
+ rset.getString(2) |
|
82 |
|
+ ".\n"); |
|
83 |
|
} |
|
84 |
|
// end snippet exercise-2 |
|
|
79 |
|
+ rset.getString(2) |
|
80 |
|
+ ".\n"); |
|
81 |
|
} |
|
82 |
|
// end snippet exercise-2 |
85 |
83 |
|
|
86 |
|
// start snippet exercise-3 |
|
87 |
|
System.out.print( |
|
|
84 |
|
// start snippet exercise-3 |
|
85 |
|
System.out.print( |
88 |
86 |
"Do you want to remove all the guests that are on the black list and confirmed their presence? Enter \"Y\" for yes, anything else for no.\n"); |
"Do you want to remove all the guests that are on the black list and confirmed their presence? Enter \"Y\" for yes, anything else for no.\n"); |
89 |
|
if (key.nextLine().equals("Y")) { |
|
90 |
|
stmt.execute( |
|
91 |
|
"DELETE FROM GUEST WHERE NAME IN (SELECT NAME FROM BLACKLIST) AND Confirmed = true;"); |
|
92 |
|
} |
|
93 |
|
// end snippet exercise-3 |
|
|
87 |
|
if (key.nextLine().equals("Y")) { |
|
88 |
|
stmt.execute("DELETE FROM GUEST WHERE NAME IN (SELECT NAME FROM BLACKLIST) AND Confirmed = true;"); |
|
89 |
|
} |
|
90 |
|
// end snippet exercise-3 |
94 |
91 |
|
|
95 |
|
} catch (SQLException ex) { |
|
96 |
|
ex.printStackTrace(); |
|
97 |
|
} |
|
|
92 |
|
} catch (SQLException ex) { |
|
93 |
|
ex.printStackTrace(); |
|
94 |
|
} |
98 |
95 |
} |
} |
99 |
96 |
} |
} |
File notes/code/java/InsecureProgram.java changed (mode: 100644) (index bfdd8ce..aa846cb) |
... |
... |
import java.util.Scanner; |
5 |
5 |
|
|
6 |
6 |
public class InsecureProgram { |
public class InsecureProgram { |
7 |
7 |
public static void main(String[] args) { |
public static void main(String[] args) { |
8 |
|
try (Connection conn = |
|
9 |
|
DriverManager.getConnection( |
|
10 |
|
"jdbc:mysql://localhost:3306/?user=testuser&password=password"); |
|
11 |
|
Statement stmt = conn.createStatement(); ) { |
|
|
8 |
|
try (Connection conn = DriverManager.getConnection( |
|
9 |
|
"jdbc:mysql://localhost:3306/?user=testuser&password=password"); |
|
10 |
|
Statement stmt = conn.createStatement(); ) { |
12 |
11 |
|
|
13 |
|
stmt.addBatch("DROP SCHEMA IF EXISTS HW_InsecureProgram"); |
|
14 |
|
stmt.addBatch("CREATE SCHEMA HW_InsecureProgram"); |
|
15 |
|
stmt.addBatch("USE HW_InsecureProgram"); |
|
16 |
|
stmt.addBatch("CREATE TABLE DISK(Title VARCHAR(30), Price DOUBLE)"); |
|
17 |
|
stmt.addBatch("CREATE TABLE BOOK(Title VARCHAR(30), Price DOUBLE)"); |
|
18 |
|
stmt.addBatch("CREATE TABLE VINYL(Title VARCHAR(30), Price DOUBLE)"); |
|
19 |
|
stmt.addBatch("INSERT INTO DISK VALUES('test', 12)"); |
|
20 |
|
stmt.addBatch("INSERT INTO DISK VALUES('Hidden', NULL)"); |
|
21 |
|
stmt.executeBatch(); |
|
|
12 |
|
stmt.addBatch("DROP SCHEMA IF EXISTS HW_InsecureProgram"); |
|
13 |
|
stmt.addBatch("CREATE SCHEMA HW_InsecureProgram"); |
|
14 |
|
stmt.addBatch("USE HW_InsecureProgram"); |
|
15 |
|
stmt.addBatch("CREATE TABLE DISK(Title VARCHAR(30), Price DOUBLE)"); |
|
16 |
|
stmt.addBatch("CREATE TABLE BOOK(Title VARCHAR(30), Price DOUBLE)"); |
|
17 |
|
stmt.addBatch("CREATE TABLE VINYL(Title VARCHAR(30), Price DOUBLE)"); |
|
18 |
|
stmt.addBatch("INSERT INTO DISK VALUES('test', 12)"); |
|
19 |
|
stmt.addBatch("INSERT INTO DISK VALUES('Hidden', NULL)"); |
|
20 |
|
stmt.executeBatch(); |
22 |
21 |
|
|
23 |
22 |
// start snippet gist |
// start snippet gist |
24 |
23 |
Scanner key = new Scanner(System.in); |
Scanner key = new Scanner(System.in); |
25 |
24 |
System.out.print( |
System.out.print( |
26 |
|
"Do you want to browse the table containing DISK, BOOK or VINYL? (please enter exactly the table name)?\n"); |
|
|
25 |
|
"Do you want to browse the table containing DISK, BOOK or VINYL? (please enter exactly the table name)?\n"); |
27 |
26 |
String table = key.nextLine(); |
String table = key.nextLine(); |
28 |
27 |
System.out.print("How much money do you have?\n"); |
System.out.print("How much money do you have?\n"); |
29 |
28 |
String max = key.nextLine(); |
String max = key.nextLine(); |
30 |
29 |
ResultSet rst = |
ResultSet rst = |
31 |
|
stmt.executeQuery("SELECT Title FROM " + table + " WHERE PRICE <= " + max + ";"); |
|
|
30 |
|
stmt.executeQuery("SELECT Title FROM " + table + " WHERE PRICE <= " + max + ";"); |
32 |
31 |
System.out.printf("Here are the %s you can afford with %s: \n", table, max); |
System.out.printf("Here are the %s you can afford with %s: \n", table, max); |
33 |
32 |
while (rst.next()) { |
while (rst.next()) { |
34 |
33 |
System.out.printf("\t- %s \n", rst.getString(1)); |
System.out.printf("\t- %s \n", rst.getString(1)); |
35 |
34 |
} |
} |
36 |
35 |
// end snippet gist |
// end snippet gist |
37 |
36 |
|
|
38 |
|
} catch (SQLException ex) { |
|
39 |
|
ex.printStackTrace(); |
|
40 |
|
} |
|
|
37 |
|
} catch (SQLException ex) { |
|
38 |
|
ex.printStackTrace(); |
|
39 |
|
} |
41 |
40 |
} |
} |
42 |
41 |
} |
} |
File notes/code/java/ScrollingProgram.java changed (mode: 100644) (index 5c68078..3c06293) |
... |
... |
import java.sql.*; |
4 |
4 |
|
|
5 |
5 |
public class ScrollingProgram { |
public class ScrollingProgram { |
6 |
6 |
public static void main(String[] args) { |
public static void main(String[] args) { |
7 |
|
try (Connection conn = |
|
8 |
|
DriverManager.getConnection( |
|
9 |
|
"jdbc:mysql://localhost:3306/" |
|
10 |
|
// We connect to the database, not to a particular schema. |
|
11 |
|
+ "?user=testuser" |
|
12 |
|
+ "&password=password" |
|
13 |
|
+ "&allowMultiQueries=true" |
|
14 |
|
|
|
15 |
|
/* |
|
16 |
|
* We want to allow multiple statements |
|
17 |
|
* to be shipped in one execute() call. |
|
18 |
|
*/ |
|
19 |
|
|
|
20 |
|
); |
|
21 |
|
Statement stmt = |
|
22 |
|
conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY); |
|
23 |
|
/* |
|
24 |
|
* Finally, we want to be able to move back and forth in our |
|
25 |
|
* ResultSets. This implies that we have to also chose if the |
|
26 |
|
* ResultSets will be updatable or not: we chose to have them |
|
27 |
|
* to be "read-only". |
|
28 |
|
*/ |
|
|
7 |
|
try (Connection conn = DriverManager.getConnection( |
|
8 |
|
// We connect to the database, not to a particular schema. |
|
9 |
|
"jdbc:mysql://localhost:3306/" |
|
10 |
|
+ "?user=testuser" |
|
11 |
|
+ "&password=password" |
|
12 |
|
+ "&allowMultiQueries=true" |
|
13 |
|
/* |
|
14 |
|
* We want to allow multiple statements |
|
15 |
|
* to be shipped in one execute() call. |
|
16 |
|
*/ |
|
17 |
|
); |
|
18 |
|
Statement stmt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY); |
|
19 |
|
/* |
|
20 |
|
* Finally, we want to be able to move back and forth in our |
|
21 |
|
* ResultSets. This implies that we have to also chose if the |
|
22 |
|
* ResultSets will be updatable or not: we chose to have them |
|
23 |
|
* to be "read-only". |
|
24 |
|
*/ |
29 |
25 |
) { |
) { |
30 |
|
|
|
31 |
|
/* |
|
32 |
|
* Before you ask: no, there are no "simple" way of |
|
33 |
|
* constructing a string over multiple lines, |
|
34 |
|
* besides concatenating them, |
|
35 |
|
* cf. e.g. https://stackoverflow.com/q/878573 |
|
36 |
|
*/ |
|
37 |
|
|
|
38 |
|
stmt.execute( |
|
39 |
|
"DROP SCHEMA IF EXISTS HW_SCROLLABLE_DEMO;" |
|
|
26 |
|
/* |
|
27 |
|
* Before you ask: no, there are no "simple" way of |
|
28 |
|
* constructing a string over multiple lines, |
|
29 |
|
* besides concatenating them, |
|
30 |
|
* cf. e.g. https://stackoverflow.com/q/878573 |
|
31 |
|
*/ |
|
32 |
|
|
|
33 |
|
stmt.execute( |
|
34 |
|
"DROP SCHEMA IF EXISTS HW_SCROLLABLE_DEMO;" |
40 |
35 |
+ |
+ |
41 |
|
/* |
|
42 |
|
* We drop the schema we want to use if it already exists. |
|
43 |
|
* (This allows to execute the same program multiple times.) |
|
44 |
|
*/ |
|
45 |
|
|
|
|
36 |
|
/* |
|
37 |
|
* We drop the schema we want to use if it already exists. |
|
38 |
|
* (This allows to execute the same program multiple times.) |
|
39 |
|
*/ |
46 |
40 |
"CREATE SCHEMA HW_SCROLLABLE_DEMO;" |
"CREATE SCHEMA HW_SCROLLABLE_DEMO;" |
47 |
41 |
+ "USE HW_SCROLLABLE_DEMO;" |
+ "USE HW_SCROLLABLE_DEMO;" |
48 |
42 |
+ |
+ |
|
... |
... |
public class ScrollingProgram { |
50 |
44 |
"CREATE TABLE TEST(" |
"CREATE TABLE TEST(" |
51 |
45 |
+ " Id INT" |
+ " Id INT" |
52 |
46 |
+ ");" |
+ ");" |
53 |
|
// The schema contains only one very simple table. |
|
|
47 |
|
// The schema contains only one very simple table. |
54 |
48 |
); |
); |
55 |
|
/* |
|
56 |
|
* We can execute all those queries at once |
|
57 |
|
* because we passed the "allowMultiQueries=true" |
|
58 |
|
* token when we created the Connection object. |
|
59 |
|
*/ |
|
60 |
|
|
|
61 |
|
// Let us insert some dummy values in this dummy table: |
|
62 |
|
for (int i = 0; i < 10; i++) stmt.addBatch("INSERT INTO TEST VALUES (" + i + ")"); |
|
63 |
|
/* |
|
64 |
|
* no ";" in the statements that we add |
|
65 |
|
* to the batch! |
|
66 |
|
*/ |
|
67 |
|
stmt.executeBatch(); |
|
68 |
|
// We execute the 10 statements that were loaded at once. |
|
69 |
|
|
|
70 |
|
// Now, let us write a simple query, and navigate in the result: |
|
71 |
|
|
|
72 |
|
ResultSet rs = stmt.executeQuery("SELECT * FROM TEST"); |
|
73 |
|
/* |
|
74 |
|
* We select all the tuples in the table. |
|
75 |
|
* If we were to execute this instruction on the |
|
76 |
|
* command-line interface, we would get: |
|
77 |
|
|
|
78 |
|
* MariaDB [HW_SCROLLABLE_DEMO]> SELECT * FROM TEST; |
|
79 |
|
* +----+ |
|
80 |
|
* | Id | |
|
81 |
|
* +----+ |
|
82 |
|
* | 0 | |
|
83 |
|
* | 1 | |
|
84 |
|
* | 2 | |
|
85 |
|
* | 3 | |
|
86 |
|
* | 4 | |
|
87 |
|
* | 5 | |
|
88 |
|
* | 6 | |
|
89 |
|
* | 7 | |
|
90 |
|
* | 8 | |
|
91 |
|
* | 9 | |
|
92 |
|
* +----+ |
|
93 |
|
* 10 rows in set (0.001 sec) |
|
94 |
|
*/ |
|
95 |
|
|
|
96 |
|
// We can "jump" to the 8th result in the set: |
|
97 |
|
rs.absolute(8); |
|
98 |
|
System.out.printf("%-22s %s %d.\n", "After absolute(8),", "we are at Id", rs.getInt(1)); |
|
99 |
|
/* Note that this would display "7" since the |
|
100 |
|
* 8th result contains the value 7 (sql starts |
|
101 |
|
* counting at 1. |
|
102 |
|
*/ |
|
103 |
|
|
|
104 |
|
// We can move back 1 item: |
|
105 |
|
rs.relative(-1); |
|
106 |
|
System.out.printf("%-22s %s %d.\n", "After relative(-1),", "we are at Id", rs.getInt(1)); |
|
107 |
|
|
|
108 |
|
// We can move to the last item: |
|
109 |
|
rs.last(); |
|
110 |
|
System.out.printf("%-22s %s %d.\n", "After last(),", "we are at Id", rs.getInt(1)); |
|
111 |
|
|
|
112 |
|
// We can move to the first item: |
|
113 |
|
rs.first(); |
|
114 |
|
System.out.printf("%-22s %s %d.\n", "After first(),", "we are at Id", rs.getInt(1)); |
|
115 |
|
|
|
116 |
|
conn.close(); |
|
117 |
|
} catch (SQLException ex) { |
|
118 |
|
ex.printStackTrace(); |
|
119 |
|
} |
|
|
49 |
|
/* |
|
50 |
|
* We can execute all those queries at once |
|
51 |
|
* because we passed the "allowMultiQueries=true" |
|
52 |
|
* token when we created the Connection object. |
|
53 |
|
*/ |
|
54 |
|
|
|
55 |
|
// Let us insert some dummy values in this dummy table: |
|
56 |
|
for (int i = 0; i < 10; i++) stmt.addBatch("INSERT INTO TEST VALUES (" + i + ")"); |
|
57 |
|
/* |
|
58 |
|
* no ";" in the statements that we add |
|
59 |
|
* to the batch! |
|
60 |
|
*/ |
|
61 |
|
stmt.executeBatch(); |
|
62 |
|
// We execute the 10 statements that were loaded at once. |
|
63 |
|
|
|
64 |
|
// Now, let us write a simple query, and navigate in the result: |
|
65 |
|
ResultSet rs = stmt.executeQuery("SELECT * FROM TEST"); |
|
66 |
|
/* |
|
67 |
|
* We select all the tuples in the table. |
|
68 |
|
* If we were to execute this instruction on the |
|
69 |
|
* command-line interface, we would get: |
|
70 |
|
|
|
71 |
|
* MariaDB [HW_SCROLLABLE_DEMO]> SELECT * FROM TEST; |
|
72 |
|
* +----+ |
|
73 |
|
* | Id | |
|
74 |
|
* +----+ |
|
75 |
|
* | 0 | |
|
76 |
|
* | 1 | |
|
77 |
|
* | 2 | |
|
78 |
|
* | 3 | |
|
79 |
|
* | 4 | |
|
80 |
|
* | 5 | |
|
81 |
|
* | 6 | |
|
82 |
|
* | 7 | |
|
83 |
|
* | 8 | |
|
84 |
|
* | 9 | |
|
85 |
|
* +----+ |
|
86 |
|
* 10 rows in set (0.001 sec) |
|
87 |
|
*/ |
|
88 |
|
|
|
89 |
|
// We can "jump" to the 8th result in the set: |
|
90 |
|
rs.absolute(8); |
|
91 |
|
System.out.printf("%-22s %s %d.\n", "After absolute(8),", "we are at Id", rs.getInt(1)); |
|
92 |
|
/* Note that this would display "7" since the |
|
93 |
|
* 8th result contains the value 7 (sql starts |
|
94 |
|
* counting at 1. |
|
95 |
|
*/ |
|
96 |
|
|
|
97 |
|
// We can move back 1 item: |
|
98 |
|
rs.relative(-1); |
|
99 |
|
System.out.printf("%-22s %s %d.\n", "After relative(-1),", "we are at Id", rs.getInt(1)); |
|
100 |
|
|
|
101 |
|
// We can move to the last item: |
|
102 |
|
rs.last(); |
|
103 |
|
System.out.printf("%-22s %s %d.\n", "After last(),", "we are at Id", rs.getInt(1)); |
|
104 |
|
|
|
105 |
|
// We can move to the first item: |
|
106 |
|
rs.first(); |
|
107 |
|
System.out.printf("%-22s %s %d.\n", "After first(),", "we are at Id", rs.getInt(1)); |
|
108 |
|
|
|
109 |
|
conn.close(); |
|
110 |
|
} catch (SQLException ex) { |
|
111 |
|
ex.printStackTrace(); |
|
112 |
|
} |
120 |
113 |
} |
} |
121 |
114 |
} |
} |
File notes/code/java/SimpleInjection01.java changed (mode: 100644) (index b4dfcf8..d61f219) |
... |
... |
import java.util.Scanner; // Importing a java API to read from the keyboard. |
5 |
5 |
|
|
6 |
6 |
public class SimpleInjection01 { |
public class SimpleInjection01 { |
7 |
7 |
public static void main(String[] args) { |
public static void main(String[] args) { |
8 |
|
try (Connection conn = |
|
9 |
|
DriverManager.getConnection( |
|
10 |
|
"jdbc:mysql://localhost:3306/?user=testuser&password=password" |
|
11 |
|
+ "&allowMultiQueries=true"); |
|
12 |
|
Statement stmt = |
|
13 |
|
conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY); ) { |
|
14 |
|
stmt.addBatch("DROP SCHEMA IF EXISTS HW_SIMPLE_INJECTION_1"); |
|
15 |
|
stmt.addBatch("CREATE SCHEMA HW_SIMPLE_INJECTION_1"); |
|
16 |
|
stmt.addBatch("USE HW_SIMPLE_INJECTION_1"); |
|
17 |
|
stmt.addBatch("CREATE TABLE SECRETVIP(Name VARCHAR(30))"); |
|
18 |
|
stmt.addBatch("INSERT INTO SECRETVIP VALUES (\"Marcus Hells\")"); |
|
19 |
|
stmt.executeBatch(); |
|
20 |
|
|
|
21 |
|
Scanner key = new Scanner(System.in); |
|
22 |
|
|
|
23 |
|
System.out.print( |
|
24 |
|
"\n\nTo test the program, enter\n" |
|
25 |
|
+ "\t• \"Marcus Hells\" (without the quotes) to confirm that guessing correctly triggers the correct result,\n" |
|
26 |
|
+ "\t• \"n' OR '1' = '1\" (without the double quotes (\")) to perform an SQL injection.\n" |
|
27 |
|
+ "\t• anything else to confirm that guessing correctly triggers the correct result,\n"); |
|
28 |
|
|
|
29 |
|
while (true) { |
|
30 |
|
System.out.print("\n\nType the name of someone who may be the secret VIP.\n"); |
|
31 |
|
|
|
32 |
|
String entered = key.nextLine(); |
|
33 |
|
|
|
34 |
|
// start snippet gist |
|
35 |
|
ResultSet rset = |
|
36 |
|
stmt.executeQuery("SELECT * FROM SECRETVIP WHERE Name ='" + entered + "';"); |
|
37 |
|
// end snippet gist |
|
38 |
|
if (rset.next()) { |
|
39 |
|
System.out.print("Yes," + rset.getString(1) + " is our secret VIP!\n"); |
|
40 |
|
} else { |
|
41 |
|
System.out.print("Nope, \"" + entered + "\" is not our secret VIP.\n"); |
|
42 |
|
} |
|
43 |
|
} |
|
44 |
|
|
|
45 |
|
} catch (SQLException ex) { |
|
46 |
|
ex.printStackTrace(); |
|
47 |
|
} |
|
|
8 |
|
try (Connection conn = DriverManager.getConnection( |
|
9 |
|
"jdbc:mysql://localhost:3306/?user=testuser&password=password" |
|
10 |
|
+ "&allowMultiQueries=true"); |
|
11 |
|
Statement stmt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY); ) { |
|
12 |
|
stmt.addBatch("DROP SCHEMA IF EXISTS HW_SIMPLE_INJECTION_1"); |
|
13 |
|
stmt.addBatch("CREATE SCHEMA HW_SIMPLE_INJECTION_1"); |
|
14 |
|
stmt.addBatch("USE HW_SIMPLE_INJECTION_1"); |
|
15 |
|
stmt.addBatch("CREATE TABLE SECRETVIP(Name VARCHAR(30))"); |
|
16 |
|
stmt.addBatch("INSERT INTO SECRETVIP VALUES (\"Marcus Hells\")"); |
|
17 |
|
stmt.executeBatch(); |
|
18 |
|
|
|
19 |
|
Scanner key = new Scanner(System.in); |
|
20 |
|
|
|
21 |
|
System.out.print("\n\nTo test the program, enter\n" |
|
22 |
|
+ "\t• \"Marcus Hells\" (without the quotes) to confirm that guessing correctly triggers the correct result,\n" |
|
23 |
|
+ "\t• \"n' OR '1' = '1\" (without the double quotes (\")) to perform an SQL injection.\n" |
|
24 |
|
+ "\t• anything else to confirm that guessing correctly triggers the correct result,\n"); |
|
25 |
|
|
|
26 |
|
while (true) { |
|
27 |
|
System.out.print("\n\nType the name of someone who may be the secret VIP.\n"); |
|
28 |
|
|
|
29 |
|
String entered = key.nextLine(); |
|
30 |
|
|
|
31 |
|
// start snippet gist |
|
32 |
|
ResultSet rset = |
|
33 |
|
stmt.executeQuery("SELECT * FROM SECRETVIP WHERE Name ='" + entered + "';"); |
|
34 |
|
// end snippet gist |
|
35 |
|
if (rset.next()) { |
|
36 |
|
System.out.print("Yes," + rset.getString(1) + " is our secret VIP!\n"); |
|
37 |
|
} else { |
|
38 |
|
System.out.print("Nope, \"" + entered + "\" is not our secret VIP.\n"); |
|
39 |
|
} |
|
40 |
|
} |
|
41 |
|
} catch (SQLException ex) { |
|
42 |
|
ex.printStackTrace(); |
|
43 |
|
} |
48 |
44 |
} |
} |
49 |
45 |
} |
} |
File notes/code/java/SimpleInjection02.java changed (mode: 100644) (index cd40b56..054824c) |
... |
... |
import java.util.Scanner; // Importing a java API to read from the keyboard. |
5 |
5 |
|
|
6 |
6 |
public class SimpleInjection02 { |
public class SimpleInjection02 { |
7 |
7 |
public static void main(String[] args) { |
public static void main(String[] args) { |
8 |
|
try (Connection conn = |
|
9 |
|
DriverManager.getConnection( |
|
10 |
|
"jdbc:mysql://localhost:3306/?user=testuser&password=password" |
|
11 |
|
+ "&allowMultiQueries=true"); |
|
12 |
|
Statement stmt = |
|
13 |
|
conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY); ) { |
|
14 |
|
stmt.addBatch("DROP SCHEMA IF EXISTS HW_SIMPLE_INJECTION_2"); |
|
15 |
|
stmt.addBatch("CREATE SCHEMA HW_SIMPLE_INJECTION_2"); |
|
16 |
|
stmt.addBatch("USE HW_SIMPLE_INJECTION_2"); |
|
17 |
|
stmt.addBatch("CREATE TABLE SECRETVIP(Name VARCHAR(30))"); |
|
18 |
|
stmt.addBatch("INSERT INTO SECRETVIP VALUES (\"Marcus Hells\")"); |
|
19 |
|
stmt.executeBatch(); |
|
20 |
|
|
|
21 |
|
Scanner key = new Scanner(System.in); |
|
22 |
|
|
|
23 |
|
System.out.print( |
|
24 |
|
"\n\nTo test the program, enter\n" |
|
25 |
|
+ "\t• \"Marcus Hells\" (without the quotes) to confirm that guessing correctly triggers the correct result,\n" |
|
26 |
|
+ "\t• \"nope'; DROP SCHEMA HW_SIMPLE_INJECTION_2;\" (without the double quotes (\")) to perform an SQL injection.\n" |
|
27 |
|
+ "\t• anything else to confirm that guessing correctly triggers the correct result,\n"); |
|
28 |
|
|
|
29 |
|
while (true) { |
|
30 |
|
System.out.print("\n\nType the name of someone who may be the secret VIP.\n"); |
|
31 |
|
|
|
32 |
|
String entered = key.nextLine(); |
|
33 |
|
|
|
34 |
|
// start snippet gist |
|
35 |
|
stmt.execute("SELECT * FROM SECRETVIP WHERE Name ='" + entered + "';"); |
|
36 |
|
// end snippet gist |
|
37 |
|
|
|
38 |
|
ResultSet rst = stmt.getResultSet(); |
|
39 |
|
|
|
40 |
|
boolean found = rst.first(); |
|
41 |
|
|
|
42 |
|
if (found) { |
|
43 |
|
System.out.print("Yes, you found it!\n"); |
|
44 |
|
} else { |
|
45 |
|
System.out.print("Nope, " + entered + " is not our secret VIP.\n"); |
|
|
8 |
|
try (Connection conn = DriverManager.getConnection( |
|
9 |
|
"jdbc:mysql://localhost:3306/?user=testuser&password=password" |
|
10 |
|
+ "&allowMultiQueries=true"); |
|
11 |
|
Statement stmt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY); ) { |
|
12 |
|
stmt.addBatch("DROP SCHEMA IF EXISTS HW_SIMPLE_INJECTION_2"); |
|
13 |
|
stmt.addBatch("CREATE SCHEMA HW_SIMPLE_INJECTION_2"); |
|
14 |
|
stmt.addBatch("USE HW_SIMPLE_INJECTION_2"); |
|
15 |
|
stmt.addBatch("CREATE TABLE SECRETVIP(Name VARCHAR(30))"); |
|
16 |
|
stmt.addBatch("INSERT INTO SECRETVIP VALUES (\"Marcus Hells\")"); |
|
17 |
|
stmt.executeBatch(); |
|
18 |
|
|
|
19 |
|
Scanner key = new Scanner(System.in); |
|
20 |
|
|
|
21 |
|
System.out.print("\n\nTo test the program, enter\n" |
|
22 |
|
+ "\t• \"Marcus Hells\" (without the quotes) to confirm that guessing correctly triggers the correct result,\n" |
|
23 |
|
+ "\t• \"nope'; DROP SCHEMA HW_SIMPLE_INJECTION_2;\" (without the double quotes (\")) to perform an SQL injection.\n" |
|
24 |
|
+ "\t• anything else to confirm that guessing correctly triggers the correct result,\n"); |
|
25 |
|
|
|
26 |
|
while (true) { |
|
27 |
|
System.out.print("\n\nType the name of someone who may be the secret VIP.\n"); |
|
28 |
|
|
|
29 |
|
String entered = key.nextLine(); |
|
30 |
|
|
|
31 |
|
// start snippet gist |
|
32 |
|
stmt.execute("SELECT * FROM SECRETVIP WHERE Name ='" + entered + "';"); |
|
33 |
|
// end snippet gist |
|
34 |
|
|
|
35 |
|
ResultSet rst = stmt.getResultSet(); |
|
36 |
|
|
|
37 |
|
boolean found = rst.first(); |
|
38 |
|
|
|
39 |
|
if (found) { |
|
40 |
|
System.out.print("Yes, you found it!\n"); |
|
41 |
|
} else { |
|
42 |
|
System.out.print("Nope, " + entered + " is not our secret VIP.\n"); |
|
43 |
|
} |
46 |
44 |
} |
} |
47 |
|
} |
|
48 |
45 |
|
|
49 |
46 |
} catch (SQLException ex) { |
} catch (SQLException ex) { |
50 |
|
ex.printStackTrace(); |
|
51 |
|
} |
|
|
47 |
|
ex.printStackTrace(); |
|
48 |
|
} |
52 |
49 |
} |
} |
53 |
50 |
} |
} |
File notes/code/java/SimpleInjection03.java changed (mode: 100644) (index 7cc7643..4c8635d) |
1 |
1 |
// code/java/SimpleInjection03.java |
// code/java/SimpleInjection03.java |
2 |
2 |
|
|
3 |
3 |
import java.sql.*; |
import java.sql.*; |
4 |
|
import java.util.Scanner; // Importing a java API to read from the keyboard. |
|
|
4 |
|
// Importing a java API to read from the keyboard. |
|
5 |
|
import java.util.Scanner; |
5 |
6 |
|
|
6 |
7 |
public class SimpleInjection03 { |
public class SimpleInjection03 { |
7 |
8 |
public static void main(String[] args) { |
public static void main(String[] args) { |
8 |
|
try (Connection conn = |
|
9 |
|
DriverManager.getConnection( |
|
10 |
|
"jdbc:mysql://localhost:3306/?user=testuser&password=password" |
|
11 |
|
+ "&allowMultiQueries=true"); |
|
12 |
|
Statement stmt = |
|
13 |
|
conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY); ) { |
|
14 |
|
stmt.addBatch("DROP SCHEMA IF EXISTS HW_SIMPLE_INJECTION_3"); |
|
15 |
|
stmt.addBatch("CREATE SCHEMA HW_SIMPLE_INJECTION_3"); |
|
16 |
|
stmt.addBatch("USE HW_SIMPLE_INJECTION_3"); |
|
17 |
|
stmt.addBatch("CREATE TABLE SECRETVIP(Name VARCHAR(30))"); |
|
18 |
|
stmt.addBatch("INSERT INTO SECRETVIP VALUES (\"Marcus Hells\")"); |
|
19 |
|
stmt.executeBatch(); |
|
20 |
|
|
|
21 |
|
Scanner key = new Scanner(System.in); |
|
22 |
|
|
|
23 |
|
System.out.print( |
|
24 |
|
"\n\nTo test the program, enter\n" |
|
25 |
|
+ "\t• \"Marcus Hells\" (without the quotes) to confirm that guessing correctly triggers the correct result,\n" |
|
26 |
|
+ "\t• anything else to confirm that guessing correctly triggers the correct result.\n\n" |
|
27 |
|
+ "This program uses prepared statement, and as such is extremely good at preventing SQL injections.\n\n"); |
|
28 |
|
|
|
29 |
|
PreparedStatement ps = conn.prepareStatement("SELECT * FROM SECRETVIP WHERE Name = ?;"); |
|
30 |
|
|
|
31 |
|
while (true) { |
|
32 |
|
System.out.print("\n\nType the name of someone who may be the secret VIP.\n"); |
|
33 |
|
|
|
34 |
|
String entered = key.nextLine(); |
|
35 |
|
|
|
36 |
|
ps.setString(1, entered); |
|
37 |
|
ResultSet rset = ps.executeQuery(); |
|
38 |
|
|
|
39 |
|
if (rset.next()) { |
|
40 |
|
System.out.print("Yes, " + rset.getString(1) + "is our secret VIP!\n"); |
|
41 |
|
} else { |
|
42 |
|
System.out.print("Nope, " + entered + " is not our secret VIP.\n"); |
|
|
9 |
|
try (Connection conn = DriverManager.getConnection( |
|
10 |
|
"jdbc:mysql://localhost:3306/?user=testuser&password=password" |
|
11 |
|
+ "&allowMultiQueries=true"); |
|
12 |
|
Statement stmt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY); ) { |
|
13 |
|
stmt.addBatch("DROP SCHEMA IF EXISTS HW_SIMPLE_INJECTION_3"); |
|
14 |
|
stmt.addBatch("CREATE SCHEMA HW_SIMPLE_INJECTION_3"); |
|
15 |
|
stmt.addBatch("USE HW_SIMPLE_INJECTION_3"); |
|
16 |
|
stmt.addBatch("CREATE TABLE SECRETVIP(Name VARCHAR(30))"); |
|
17 |
|
stmt.addBatch("INSERT INTO SECRETVIP VALUES (\"Marcus Hells\")"); |
|
18 |
|
stmt.executeBatch(); |
|
19 |
|
|
|
20 |
|
Scanner key = new Scanner(System.in); |
|
21 |
|
|
|
22 |
|
System.out.print("\n\nTo test the program, enter\n" |
|
23 |
|
+ "\t• \"Marcus Hells\" (without the quotes) to confirm that guessing correctly triggers the correct result,\n" |
|
24 |
|
+ "\t• anything else to confirm that guessing correctly triggers the correct result.\n\n" |
|
25 |
|
+ "This program uses prepared statement, and as such is extremely good at preventing SQL injections.\n\n"); |
|
26 |
|
|
|
27 |
|
PreparedStatement ps = conn.prepareStatement("SELECT * FROM SECRETVIP WHERE Name = ?;"); |
|
28 |
|
|
|
29 |
|
while (true) { |
|
30 |
|
System.out.print("\n\nType the name of someone who may be the secret VIP.\n"); |
|
31 |
|
|
|
32 |
|
String entered = key.nextLine(); |
|
33 |
|
|
|
34 |
|
ps.setString(1, entered); |
|
35 |
|
ResultSet rset = ps.executeQuery(); |
|
36 |
|
|
|
37 |
|
if (rset.next()) { |
|
38 |
|
System.out.print("Yes, " + rset.getString(1) + "is our secret VIP!\n"); |
|
39 |
|
} else { |
|
40 |
|
System.out.print("Nope, " + entered + " is not our secret VIP.\n"); |
|
41 |
|
} |
|
42 |
|
} |
|
43 |
|
} catch (SQLException ex) { |
|
44 |
|
ex.printStackTrace(); |
43 |
45 |
} |
} |
44 |
|
} |
|
45 |
|
|
|
46 |
|
} catch (SQLException ex) { |
|
47 |
|
ex.printStackTrace(); |
|
48 |
|
} |
|
49 |
46 |
} |
} |
50 |
47 |
} |
} |