Java¶

People complain about Java too verbose, too enterprise y, too slow. But here's the truth: it runs on billions of devices, powers enterprise systems, and underlies Android. Working in security means you'll hit Java in web apps, Android apps, enterprise systems, and security tools.
Why Java Matters for Security:
Enterprise Dominance: Most Fortune 500 companies run Java applications. Spring Framework, Hibernate, enterprise Java stacks they're everywhere. When you're testing enterprise environments, you're testing Java applications.
Android Security: Android apps are primarily Java (or Kotlin, which compiles to the JVM). Understanding Java helps you understand Android security, reverse engineer apps, and find vulnerabilities.
Web Application Security: Java web applications have unique security characteristics: - Deserialization vulnerabilities (especially with Java's serialization mechanism) - Enterprise frameworks (Spring, Struts) have their own security patterns - The JVM's security model affects how attacks work
This Cheatsheet's Focus:
Java is big the language and ecosystem are massive. We'll focus on: - Fundamentals (just enough to read and write Java) - Security relevant features (serialization, reflection, class loading) - Common vulnerabilities and how to avoid them - Practical examples for security work
You don't need to become a Java architect, but understanding Java will make you a better security professional.
Table of Contents¶
- 1. Your First Java Program
- 3. Compiling and Running (
javac&java) - 2. Java Language Fundamentals
- 3. Object Oriented Programming (The Heart of Java)
- 5. Building and Managing Projects
Part 1: Your First Java Program¶
1. Setting Up Your Environment-(JDK)¶
Before you can write Java code, you need the Java Development Kit (JDK). Not the JRE (Java Runtime Environment) you need the full JDK which includes the compiler.
What's in the JDK: - javac: The Java compiler (converts .java to .class bytecode) - java: The JVM runtime (executes bytecode) - Standard library: The massive collection of built in classes - Tools: jar, javadoc, debugging tools, etc.
Which JDK to Use:
Recommendation: Use an open source build of the JDK. Eclipse Temurin (formerly AdoptOpenJDK) is popular and well supported. Download the latest LTS (Long-Term Support) version JDK 17 or JDK 21 are good choices.
Why Not Oracle JDK? Oracle JDK has licensing restrictions for commercial use. For learning and security work, open source distributions are fine.
Installation Options: - Linux/macOS: Use SDKMAN! (curl -s "https://get.sdkman.io" | bash) to easily install and switch between Java versions - Windows: Download the installer from Eclipse Temurin or use Chocolatey (choco install temurin17) - Package Managers: Most Linux distributions include OpenJDK in their repositories
Verify Installation:
java -version # Should show version info
javac -version # Should show compiler version
If both commands work, you're ready to go.
2. Hello, World!: The Classic Entry Point¶
In Java, all code must reside inside a class. The entry point for any Java application is a main method with a specific signature.
HelloWorld.java
// A class is a blueprint for creating objects.
// Every Java application has at least one class.
public class HelloWorld {
// This is the main method. The JVM looks for this exact signature to start the program.
// `public`: It can be called from anywhere.
// `static`: It belongs to the class, not an instance of the class.
// `void`: It doesn't return any value.
// `main`: The name of the method.
// `String[] args`: An array of strings for command line arguments.
public static void main(String[] args) {
// `System.out.println()` prints a line of text to the console.
System.out.println("Hello, World!");
}
}
3. Compiling and Running (javac &-java)¶
Java is a compiled language. You first compile your .java source file into .class bytecode, and then the JVM executes the bytecode.
- Save your code in a file named
HelloWorld.java. The filename must match the public class name. - Compile the code using
javac:This will create ajavac HelloWorld.javaHelloWorld.classfile. - Run the compiled code using
java:(Note: You don't include thejava HelloWorld.classextension when running).
Output:
Hello, World!
Part 2: Java Language Fundamentals¶
4. Variables and Primitive Data Types¶
Java has two kinds of types: primitive types and reference types (objects).
Primitive Types: These are the most basic data types.
byte: 8-bit integer.short: 16-bit integer.int: 32-bit integer (most common).long: 64-bit integer.float: 32-bit floating point number.double: 64-bit floating point number (most common for decimals).boolean:trueorfalse.char: A single 16-bit Unicode character.
public class Variables {
public static void main(String[] args) {
// Declaration: type name;
int score;
// Initialization: name = value;
score = 100;
// Declaration and initialization
double price = 19.99;
boolean isAdmin = false;
char initial = 'A';
// Since Java 10, you can use `var` for local variable type inference.
var playerName = "Gopher"; // The compiler infers this is a String
System.out.println("Player: " + playerName);
System.out.println("Score: " + score);
}
}
5. Operators¶
Java has standard operators you'd expect from C-like languages, with some important differences from C/C++ regarding pointers and memory operations (Java doesn't have those that's intentional).
Operator Categories: - Arithmetic: +, -, *, /, % (modulus) Basic math operations - Comparison: ==, !=, >, <, >=, <= Compare values (but be careful with == for objects!) - Logical: && (AND), || (OR), ! (NOT) Boolean logic - Assignment: =, +=, -=, etc. Store values in variables - Bitwise: &, |, ^, ~, <<, >> Manipulate individual bits (less common in Java than C)
6. Control Flow (if, for, while,-switch)¶
public class ControlFlow {
public static void main(String[] args) {
// if else if else
int score = 85;
if (score >= 90) {
System.out.println("Excellent");
} else if (score >= 80) {
System.out.println("Good");
} else {
System.out.println("Keep trying");
}
// for loop
for (int i = 0; i < 5; i++) {
System.out.print(i + " ");
}
System.out.println();
// while loop
int count = 0;
while (count < 5) {
System.out.print(count + " ");
count++;
}
System.out.println();
// switch statement (works with byte, short, char, int, enums, String)
String level = "Admin";
switch (level) {
case "Admin":
System.out.println("Full access");
break;
case "User":
System.out.println("Limited access");
break;
default:
System.out.println("No access");
break;
}
}
}
7. Arrays¶
An array is a fixed size container that holds elements of the same type.
public class ArraysExample {
public static void main(String[] args) {
// Declare and initialize an array of integers
int[] numbers = {10, 20, 30, 40, 50};
// Access an element by its index (0-based)
System.out.println("The first element is: " + numbers[0]);
// Get the length of the array
System.out.println("The array length is: " + numbers.length);
// Iterate over an array using an enhanced for loop
for (int number : numbers) {
System.out.print(number + " ");
}
System.out.println();
}
}
Part 3: Object Oriented Programming (The Heart of-Java)¶
Java is fundamentally object oriented. Everything revolves around classes and objects.
8. Classes and Objects¶
- A Class is a blueprint or template for creating objects.
- An Object is an instance of a class.
// This is the blueprint for a User
public class User {
// Fields (or instance variables) store the state of the object
String username;
boolean isActive;
}
public class App {
public static void main(String[] args) {
// Create an object (an instance of the User class)
User user1 = new User();
user1.username = "alice";
user1.isActive = true;
User user2 = new User();
user2.username = "bob";
System.out.println("User 1: " + user1.username);
System.out.println("User 2: " + user2.username);
}
}
9. Constructors¶
A constructor is a special method that is called when an object is created. It's used to initialize the object's state.
public class User {
String username;
String email;
// This is a constructor. It has the same name as the class.
public User(String username, String email) {
// Use the `this` keyword to refer to the current object's fields
this.username = username;
this.email = email;
}
}
// In another file...
// Now we can create a user in one line
User user1 = new User("alice", "alice@example.com");
10. Methods, Fields, and this¶
- Fields are variables inside a class (state).
- Methods are functions inside a class (behavior).
- The
thiskeyword is a reference to the current object.
public class BankAccount {
private double balance; // field
public BankAccount(double initialBalance) {
this.balance = initialBalance;
}
// A method to deposit money
public void deposit(double amount) {
if (amount > 0) {
this.balance += amount;
}
}
// A method to get the current balance
public double getBalance() {
return this.balance;
}
}
11. Access Modifiers (public, private,-etc.)¶
Access modifiers control the visibility of fields, methods, and classes.
public: Accessible from anywhere.private: Only accessible within the same class. This is key for encapsulation—hiding the internal state of an object and exposing it only through public methods.protected: Accessible within the same package and by subclasses.- default (no modifier): Accessible only within the same package.
Best Practice: Make fields private and provide public methods (getters and setters) to access or change them. This gives you control over your object's state.
12. static vs. Instance Members¶
- Instance members (fields and methods) belong to an object. Each object has its own copy.
staticmembers belong to the class itself. There is only one copy, shared by all objects of that class. You don't need to create an object to access them.
public class MathUtil {
public static final double PI = 3.14159; // A static constant
public static int add(int a, int b) { // A static method
return a + b;
}
}
// In another file...
int sum = MathUtil.add(5, 10);
System.out.println("Pi is: " + MathUtil.PI);
13. Inheritance-(extends)¶
Inheritance allows a class (the subclass) to inherit fields and methods from another class (the superclass).
// Superclass
public class Animal {
public void eat() {
System.out.println("This animal eats food.");
}
}
// Subclass
public class Dog extends Animal {
// The Dog class automatically has the eat() method.
// We can also override methods
@Override
public void eat() {
System.out.println("The dog eats kibble.");
}
public void bark() {
System.out.println("Woof!");
}
}
14. Polymorphism and Abstract Classes¶
Polymorphism means "many forms." It allows you to use a superclass reference to refer to a subclass object.
An Abstract Class is a class that cannot be instantiated. It's meant to be subclassed. It can have abstract methods (methods without a body) that subclasses must implement.
abstract class Shape { // Cannot do `new Shape()`
// An abstract method no body
public abstract double getArea();
public void printDescription() {
System.out.println("This is a shape.");
}
}
class Circle extends Shape {
private double radius;
// ... constructor ...
@Override
public double getArea() {
return Math.PI * radius * radius;
}
}
// In main...
Shape myShape = new Circle(10.0); // Polymorphism!
System.out.println("Area: " + myShape.getArea()); // Calls the Circle's getArea() method
myShape.printDescription(); // Calls the Shape's method
15. Interfaces-(implements)¶
An Interface is a completely abstract type. It can only contain method signatures and constants. A class implements an interface, promising to provide an implementation for all of its methods.
A class can extend only one superclass, but it can implements multiple interfaces.
// An interface defining a behavior
interface Loggable {
String getLogMessage();
}
class User implements Loggable {
private String username;
// ...
@Override
public String getLogMessage() {
return "User logged in: " + this.username;
}
}
class SystemEvent implements Loggable {
private String event;
// ...
@Override
public String getLogMessage() {
return "System event: " + this.event;
}
}
// A method that can work with any object that is Loggable
public void writeToLog(Loggable item) {
String message = item.getLogMessage();
// ... write message to a log file ...
}
Part 4: The Java Standard Library¶
16. The String Class¶
Strings in Java are objects, and they are immutable. Once a String object is created, it cannot be changed.
String greeting = "Hello";
String name = "World";
// This does not change the original string. It creates a new one.
String message = greeting + ", " + name + "!"; // "Hello, World!"
System.out.println(message.length()); // 13
System.out.println(message.toUpperCase()); // "HELLO, WORLD!"
System.out.println(message.substring(0, 5)); // "Hello"
17. The Collections Framework (List, Set,-Map)¶
This is Java's equivalent of data structures like Python lists and dictionaries.
List: An ordered collection. Allows duplicates. The most common implementation isArrayList.Set: An unordered collection of unique elements. The most common implementation isHashSet.Map: A collection of key value pairs. Keys must be unique. The most common implementation isHashMap.
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class CollectionsExample {
public static void main(String[] args) {
// List
List<String> names = new ArrayList<>();
names.add("Alice");
names.add("Bob");
names.add("Alice"); // Duplicates are allowed
System.out.println("First name: " + names.get(0));
// Map
Map<String, Integer> scores = new HashMap<>();
scores.put("Alice", 100);
scores.put("Bob", 95);
System.out.println("Bob's score: " + scores.get("Bob"));
// Iterating
for (String name : names) {
System.out.println("Name: " + name);
}
for (Map.Entry<String, Integer> entry : scores.entrySet()) {
System.out.println(entry.getKey() + ": " + entry.getValue());
}
}
}
18. Exception Handling (try catch-finally)¶
Java uses exceptions to handle errors. When an error occurs, an Exception object is "thrown."
- Checked Exceptions: Exceptions that the compiler forces you to handle (e.g.,
IOException). You must either catch them withtry catchor declare that your methodthrowsthem. - Unchecked Exceptions (RuntimeExceptions): Exceptions that you are not required to handle, often indicating a programming error (e.g.,
NullPointerException,ArrayIndexOutOfBoundsException).
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class ExceptionExample {
public static void main(String[] args) {
try {
readFile("non_existent_file.txt");
} catch (FileNotFoundException e) {
System.err.println("Error: File could not be found.");
e.printStackTrace(); // Prints the full error stack trace
}
}
public static void readFile(String fileName) throws FileNotFoundException {
File file = new File(fileName);
Scanner scanner = null;
try {
scanner = new Scanner(file);
while (scanner.hasNextLine()) {
System.out.println(scanner.nextLine());
}
} finally {
// The `finally` block always executes, whether an exception occurred or not.
// It's perfect for cleanup, like closing resources.
if (scanner != null) {
scanner.close();
}
}
}
}
19. File I/O with NIO¶
While older java.io classes exist, the modern way to handle files is with the java.nio.file package (NIO New I/O).
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
public class FileIOExample {
public static void main(String[] args) throws IOException {
Path path = Paths.get("my file.txt");
// Write to a file
String content = "Hello from Java NIO!";
Files.write(path, content.getBytes());
// Read all lines from a file
List<String> lines = Files.readAllLines(path);
System.out.println(lines);
}
}
Part 5: Building and Managing Projects¶
20. Understanding JAR Files¶
A JAR (Java Archive) file is the standard way to package a Java application. It's essentially a ZIP file containing your compiled .class files, resources (like images or config files), and a manifest file.
An executable JAR is one that can be run directly using java -jar myapp.jar. It requires a Main-Class attribute in its manifest file to specify the entry point.
21. Introduction to Maven¶
Maven is a powerful build automation and dependency management tool. It uses a pom.xml file to define the project.
- Dependency Management: Maven automatically downloads the libraries (JARs) your project needs from a central repository.
- Standard Lifecycle: It defines a standard lifecycle for building code:
validate,compile,test,package,install,deploy.
pom.xml example:
<project xmlns="http://maven.apache.org/POM/4.0.0" ...>
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany.app</groupId>
<artifactId>my app</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
</properties>
<dependencies>
<!-- This adds the JUnit 5 testing library to our project -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit jupiter api</artifactId>
<version>5.8.2</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
Common Commands: * mvn compile: Compiles the source code. * mvn test: Runs the tests. * mvn package: Compiles, tests, and packages the code into a JAR file in the target directory.
22. Introduction to Gradle¶
Gradle is a more modern alternative to Maven. It uses a Groovy or Kotlin based DSL for its build scripts (build.gradle), which are often more concise and flexible than Maven's XML.
build.gradle (Groovy DSL) example:
plugins {
id 'java'
}
group 'com.mycompany.app'
version '1.0-SNAPSHOT'
sourceCompatibility = '17'
repositories {
mavenCentral()
}
dependencies {
testImplementation 'org.junit.jupiter:junit jupiter api:5.8.2'
testRuntimeOnly 'org.junit.jupiter:junit jupiter engine:5.8.2'
}
test {
useJUnitPlatform()
}
Common Commands: * ./gradlew build: Compiles, tests, and builds the project. * ./gradlew test: Runs the tests.
Part 6: Java Security¶
Java's enterprise nature means it's often used in high stakes applications, making security paramount. Here are some of the most critical vulnerabilities and how to prevent them.
23. Input Validation¶
Never trust data that comes from outside your application. This includes user form data, API requests, query parameters, etc. Always validate it.
- Allow listing: Only accept known good values (e.g.,
if (currency.equals("USD") || currency.equals("EUR"))). - Format/Type: Ensure the data is in the expected format (e.g., using regex for a UUID) and can be parsed to the correct type.
- Range: Check that numbers fall within an expected range.
24. Preventing SQL Injection with JDBC¶
SQL Injection is a classic attack where an attacker manipulates a database query by injecting malicious SQL. It happens when you build queries by concatenating strings.
WRONG WAY (Vulnerable):
String username = request.getParameter("username"); // Attacker provides: ' OR 1=1 --
String query = "SELECT * FROM users WHERE username = '" + username + "'";
Statement stmt = connection.createStatement();
ResultSet rs = stmt.executeQuery(query); // The query becomes: SELECT * FROM users WHERE username = '' OR 1=1 --
RIGHT WAY (Secure):
Always use PreparedStatement. It separates the query logic from the data, making injection impossible.
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
// ...
String username = request.getParameter("username");
// The `?` is a placeholder for the data.
String query = "SELECT * FROM users WHERE username = ?";
PreparedStatement pstmt = connection.prepareStatement(query);
// Set the parameter value safely. The driver handles escaping.
pstmt.setString(1, username);
ResultSet rs = pstmt.executeQuery();
25. The Dangers of Insecure Deserialization¶
This is one of the most dangerous vulnerability classes in Java. Deserialization is the process of turning a stream of bytes back into an object. If an attacker can control the byte stream, they can potentially instantiate arbitrary classes in your application, leading to Remote Code Execution (RCE).
The Culprit: java.io.ObjectInputStream.
Rule of thumb: Do not deserialize untrusted data with ObjectInputStream.
Safer Alternatives: * Use a data only format like JSON. Libraries like Jackson or Gson are the standard for this. They deserialize data into simple Java objects (POJOs) and don't have the same RCE risks.
// Using Jackson to safely deserialize JSON
import com.fasterxml.jackson.databind.ObjectMapper;
// ...
String jsonData = request.getReader().lines().collect(Collectors.joining());
ObjectMapper mapper = new ObjectMapper();
// This is safe because it only maps data to the fields of the User class.
// It cannot instantiate arbitrary classes or execute code.
User user = mapper.readValue(jsonData, User.class);
26. Preventing XML External Entity-(XXE)¶
If your application parses XML, it may be vulnerable to XXE. An attacker can embed entities in the XML that reference external files or URLs. The XML parser might then access these resources, leading to information disclosure or Server Side Request Forgery (SSRF).
WRONG WAY (Vulnerable):
// A default XML parser is often vulnerable
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(untrustedInputStream); // Attacker's XML is parsed
RIGHT WAY (Secure):
Explicitly disable the features that allow XXE.
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.XMLConstants;
// ...
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
// This is the most important part: disable external entities.
dbf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
dbf.setFeature("http://apache.org/xml/features/disallow doctype decl", true);
dbf.setFeature("http://xml.org/sax/features/external general entities", false);
dbf.setFeature("http://xml.org/sax/features/external parameter entities", false);
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(untrustedInputStream); // Now it's safe
27. Secure Command Execution¶
Executing OS commands based on user input is risky. Avoid it if possible. If you must, use ProcessBuilder and never pass user input directly to a shell.
WRONG WAY (Vulnerable):
// This is vulnerable if `filename` contains special characters like `;` or `&`
Runtime.getRuntime().exec("/bin/sh -c ls " + filename);
RIGHT WAY (Secure):
Pass the command and its arguments as a list. This avoids shell interpretation.
import java.io.IOException;
// ...
String filename = "some;file.txt"; // Example of tricky input
// The filename is passed as a single, safe argument.
// The shell is not involved.
ProcessBuilder pb = new ProcessBuilder("ls", "-la", filename);
try {
Process process = pb.start();
// ... handle process output ...
} catch (IOException e) {
e.printStackTrace();
}
28. Cryptography-(JCA/JCE)¶
Java has a powerful crypto architecture (JCA/JCE). Always use well vetted libraries and standard algorithms.
- Password Hashing: Don't roll your own. Use a library like Spring Security or Bouncy Castle which provide a
BCryptPasswordEncoder. - Random Numbers: For any security purpose (keys, tokens, salts), always use
java.security.SecureRandom.
import java.security.SecureRandom;
// ...
SecureRandom random = new SecureRandom();
byte[] values = new byte[20];
random.nextBytes(values); // Fills the array with cryptographically strong random bytes
Part 7: Cookbook¶
29. Cookbook: Command Line File Hasher¶
This tool calculates the SHA-256 hash of a file provided as a command line argument.
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class FileHasher {
public static void main(String[] args) throws IOException, NoSuchAlgorithmException {
if (args.length != 1) {
System.err.println("Usage: java FileHasher <file path>");
System.exit(1);
}
Path filePath = Paths.get(args[0]);
if (!Files.exists(filePath)) {
System.err.println("Error: File not found at " + filePath);
System.exit(1);
}
MessageDigest sha256 = MessageDigest.getInstance("SHA-256");
try (FileInputStream fis = new FileInputStream(filePath.toFile())) {
byte[] buffer = new byte[8192];
int bytesRead;
while ((bytesRead = fis.read(buffer)) != -1) {
sha256.update(buffer, 0, bytesRead);
}
}
byte[] hashBytes = sha256.digest();
// Convert byte array to hex string
StringBuilder hexString = new StringBuilder();
for (byte b : hashBytes) {
hexString.append(String.format("%02x", b));
}
System.out.println(hexString.toString() + " " + filePath.getFileName());
}
}
30. Cookbook: Basic REST API with Javalin¶
Javalin is a very lightweight and simple web framework for Java. This example shows a minimal API for managing users.
First, add the dependency to your pom.xml (Maven) or build.gradle (Gradle).
Maven pom.xml:
<dependencies>
<dependency>
<groupId>io.javalin</groupId>
<artifactId>javalin</artifactId>
<version>5.3.2</version>
</dependency>
</dependencies>
API Code:
import io.javalin.Javalin;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
public class UserApi {
static class User {
public String name;
public String email;
}
public static void main(String[] args) {
// Use a thread safe map as a simple in memory database
ConcurrentHashMap<Integer, User> users = new ConcurrentHashMap<>();
AtomicInteger lastId = new AtomicInteger();
Javalin app = Javalin.create().start(7070);
// GET /users List all users
app.get("/users", ctx -> {
ctx.json(users);
});
// GET /users/{id} Get a specific user
app.get("/users/{id}", ctx -> {
int id = Integer.parseInt(ctx.pathParam("id"));
User user = users.get(id);
if (user != null) {
ctx.json(user);
} else {
ctx.status(404).result("User not found");
}
});
// POST /users Create a new user
app.post("/users", ctx -> {
User newUser = ctx.bodyAsClass(User.class);
int id = lastId.incrementAndGet();
users.put(id, newUser);
ctx.status(201).result("User created with ID: " + id);
});
}
}
31. Cookbook: Secure Database Client with JDBC¶
This example connects to an in memory H2 database and performs secure CRUD operations.
Maven pom.xml:
<dependencies>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>2.1.214</version>
</dependency>
</dependencies>
JDBC Code:
import java.sql.*;
public class DatabaseClient {
private static final String DB_URL = "jdbc:h2:mem:testdb"; // In memory database
public static void main(String[] args) throws SQLException {
try (Connection conn = DriverManager.getConnection(DB_URL)) {
System.out.println("Connected to H2 database.");
// 1. Create Table
try (Statement stmt = conn.createStatement()) {
stmt.execute("CREATE TABLE employees (id INT PRIMARY KEY, name VARCHAR(255))");
System.out.println("Table created.");
}
// 2. Create (Insert) Data Securely
String insertSql = "INSERT INTO employees (id, name) VALUES (?, ?)";
try (PreparedStatement pstmt = conn.prepareStatement(insertSql)) {
pstmt.setInt(1, 1);
pstmt.setString(2, "Alice");
pstmt.executeUpdate();
pstmt.setInt(1, 2);
pstmt.setString(2, "Bob");
pstmt.executeUpdate();
System.out.println("Inserted 2 records.");
}
// 3. Read (Select) Data Securely
String selectSql = "SELECT id, name FROM employees WHERE id = ?";
try (PreparedStatement pstmt = conn.prepareStatement(selectSql)) {
pstmt.setInt(1, 1);
try (ResultSet rs = pstmt.executeQuery()) {
if (rs.next()) {
System.out.println("Found employee: ID=" + rs.getInt("id") + ", Name=" + rs.getString("name"));
}
}
}
// 4. Update Data Securely
String updateSql = "UPDATE employees SET name = ? WHERE id = ?";
try (PreparedStatement pstmt = conn.prepareStatement(updateSql)) {
pstmt.setString(1, "Robert");
pstmt.setInt(2, 2);
int rowsAffected = pstmt.executeUpdate();
System.out.println("Updated " + rowsAffected + " record(s).");
}
// 5. Delete Data Securely
String deleteSql = "DELETE FROM employees WHERE id = ?";
try (PreparedStatement pstmt = conn.prepareStatement(deleteSql)) {
pstmt.setInt(1, 1);
int rowsAffected = pstmt.executeUpdate();
System.out.println("Deleted " + rowsAffected + " record(s).");
}
}
}
}