🚀 Day 4 of My Advanced Java Journey – PreparedStatement in JDBC Today, I learned one of the most important concepts in JDBC — PreparedStatement, which makes database operations more secure and efficient. 🔹 What is PreparedStatement? A PreparedStatement is used to execute SQL queries with dynamic values using placeholders (?). It helps in writing cleaner, reusable, and secure database code. 🔹 Steps to Use PreparedStatement 1️⃣ Load the Driver Load the JDBC driver class. 2️⃣ Establish Connection Connect to the database using URL, username, and password. 3️⃣ Create PreparedStatement Write SQL query with placeholders (?): String query = "INSERT INTO employee (id, name, desig, salary) VALUES (?, ?, ?, ?)"; PreparedStatement pstmt = con.prepareStatement(query); 4️⃣ Set Parameter Values Assign values using setter methods: pstmt.setInt(1, id); pstmt.setString(2, name); pstmt.setString(3, desig); pstmt.setInt(4, salary); 5️⃣ Execute Query int rows = pstmt.executeUpdate(); 🔹 Batch Processing (Multiple Inserts) Used to insert multiple records efficiently in one go. do { pstmt.setInt(1, scan.nextInt()); pstmt.setString(2, scan.next()); pstmt.setString(3, scan.next()); pstmt.setInt(4, scan.nextInt()); pstmt.addBatch(); System.out.println("Add more? (yes/no)"); s = scan.next(); } while(s.equalsIgnoreCase("yes")); int[] result = pstmt.executeBatch(); 🔹 Important Methods setInt(), setString(), setFloat() → Set values executeUpdate() → Insert/Update/Delete addBatch() → Add queries to batch executeBatch() → Execute all at once 🔍 What I explored beyond the session PreparedStatement prevents SQL Injection attacks 🔐 Precompiled queries improve performance Difference between Statement and PreparedStatement Importance of closing resources (Connection, PreparedStatement) Using try-with-resources for better memory management 💡 PreparedStatement is a must-know concept for writing secure and optimized database applications in Java. 🙌 Special thanks to the amazing trainers at TAP Academy: kshitij kenganavar Sharath R MD SADIQUE Bibek Singh Vamsi yadav Hemanth Reddy Harshit T Ravi Magadum Somanna M G Rohit Ravinder TAP Academy 📌 Learning in public. Improving every single day. #Java #AdvancedJava #JDBC #PreparedStatement #BackendDevelopment #LearningInPublic #VamsiLearns
Advanced Java JDBC PreparedStatement Security and Efficiency
More Relevant Posts
-
🚀 Day 3 of My Advanced Java Journey – Mastering CRUD Operations in JDBC Today, I implemented one of the most important concepts in backend development — CRUD operations using JDBC. 🔹 What is CRUD? CRUD stands for: Create → Insert data Read → Fetch data Update → Modify existing data Delete → Remove data 🔹 1. Create (INSERT) Used to add records into the database. ✔️ Key concept: Using PreparedStatement for inserting values safely. String sql = "INSERT INTO employees(name, designation, salary) VALUES (?, ?, ?)"; PreparedStatement ps = conn.prepareStatement(sql); ps.setString(1, "Vamsi"); ps.setString(2, "Software Engineer"); ps.setDouble(3, 60000); ps.executeUpdate(); 🔹 2. Read (SELECT) Used to retrieve and display data. ✔️ Key concept: Using ResultSet to iterate through records. Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery("SELECT * FROM employees"); while(rs.next()){ int id = rs.getInt("id"); String name = rs.getString("name"); String designation = rs.getString("designation"); double salary = rs.getDouble("salary"); } 🔹 3. Update (UPDATE) Used to modify existing records. String sql = "UPDATE employees SET salary = ? WHERE id = ?"; PreparedStatement ps = conn.prepareStatement(sql); ps.setDouble(1, 65000); ps.setInt(2, 1); ps.executeUpdate(); 🔹 4. Delete (DELETE) Used to remove records from the database. String sql = "DELETE FROM employees WHERE id = ?"; PreparedStatement ps = conn.prepareStatement(sql); ps.setInt(1, 1); ps.executeUpdate(); 🔍 What I explored beyond the session Why PreparedStatement is preferred over Statement (prevents SQL Injection 🔐) Difference between executeQuery() and executeUpdate() Importance of handling exceptions (SQLException) Closing resources (Connection, Statement, ResultSet) to avoid memory leaks 💡 CRUD operations form the core of any real-world application, from simple apps to enterprise systems. 🙌 Special thanks to the amazing trainers at TAP Academy: kshitij kenganavar Sharath R MD SADIQUE Bibek Singh Hemanth Reddy Vamsi yadav Harshit T Ravi Magadum Somanna M G Rohit Ravinder TAP Academy 📌 Learning in public. Building consistency every day. #Java #AdvancedJava #JDBC #BackendDevelopment #LearningInPublic #VamsiLearns
To view or add a comment, sign in
-
-
This Java & Spring Data JPA code is a disaster disguised as a login service. Recently, I shared this code without answers, giving an opportunity to challenge yourself. Let's crack this code. This post focused on problems in business logic and authentication logic. Most of them are critical, so let's start with the easiest one. 1. You probably know, in Java, `==` for String is not comparing values, it compares references. If your authentication depends on `u.getLogin() == login`, then login works by luck, not by logic. 2. Registration hashes the password with `md5(password)`, but login compares the stored password with the raw input. In other words, registration and authentication do not even agree on the same format. This login flow is broken by design. 3. MD5 for password storage is a bad idea. Password hashing should be slow and resistant to brute force. MD5 is fast, old, and loved by attackers. Use BCrypt or Argon2 instead. 4. Logging passwords is a free gift for hackers. `log.debug(... password ...)` should be enough to stop the review immediately. I have seen similar things in production code, and they always had to be fixed right away. 5. `findAll().stream()` to authenticate one user is painful to watch. The database can find one user by login, but instead, the code loads all users into memory and filters them in Java. Bad for performance, scalability, and design. 6. Input validation is inconsistent. `register()` trims the login, `login()` does not. There are no checks for null or blank values, or even validation for business logic - username length or complexity of password. Authentication code must be paranoid, because user input is never your friend. 7. `findByLogin(...).isPresent()` and then `save(...)` is not enough to guarantee uniqueness. Two concurrent requests can pass the same check and create duplicate users unless the database has a unique constraint. Business logic bugs also love concurrency. 8. Returning the full `User` entity after registration or login is risky. If it contains the password hash or other internal fields, one careless serialization step can leak data. 9. `loginCount = loginCount + 1` looks innocent, until concurrent logins arrive and you start losing updates. Even counters need proper thinking in multi-user systems. 10. Throwing `IllegalArgumentException` for everything is bad design. Authentication failure, duplicate user, and bad input are different problems, but here they are handled as if they were all the same. In other words, you have to carefully design, develop, and review security features like this, and not only them. Did you find one more problem?
To view or add a comment, sign in
-
-
Day 19 —#100DaysJava today I built my first real Java project. Not a tutorial. Not a copy-paste. A working backend system I built myself. ☕ It is a Login and Registration System using JDBC, DAO pattern, and MySQL. Users can register. Users can login. Data is stored in a real database. That is a real backend application. --- Here is everything I used to build it — and what each piece does: JDBC — the bridge between Java and MySQL. Without this, Java cannot talk to a database at all. PreparedStatement — the safe way to run SQL queries. Prevents SQL Injection attacks. Every real company uses this. Never use plain Statement with user input. DAO Pattern — stands for Data Access Object. This separates your database logic from your business logic. Your main code does not need to know HOW data is saved — just that it is saved. Clean, organized, professional. Transactions — if two database operations need to happen together, transactions make sure either BOTH succeed or NEITHER happens. This is how bank transfers work. Either money leaves account A AND enters account B — or nothing happens at all. Batch Processing — instead of running 100 INSERT queries one by one, batch them and run all 100 in one go. Much faster. This matters in production systems handling real traffic. Connection Pooling — instead of creating a new database connection for every request, reuse existing connections. HikariCP is the industry standard for this. Every Spring Boot application uses it under the hood. --- Project structure I followed: model — User.java (the data object) dao — UserDAO interface + UserDAOImpl (database logic) util — DBConnection (reusable connection) Main — runs the program This is the same structure used in real enterprise Java projects. --- What I learned beyond the code: Storing plain passwords is dangerous. Never do it. BCrypt hashing is the industry standard — that is my next step. Always close your database connection. Use try-with-resources so it closes automatically even if something crashes. 100% coverage does not mean bug-free. Testing edge cases — null email, wrong password, duplicate registration — is what separates good developers from average ones. --- 19 days ago I did not know what a variable was in Java. Today I built a backend system with a real database, real security concepts, and real architecture patterns. The only thing that got me here — showing up every single day. Day 1 .......................... Day 19 To any developer reading this — what was the first real project you built? Drop it below. I would love to know. 🙏 #Java #JDBC #MySQL #DAOPattern #BackendDevelopment #100DaysOfJava #JavaDeveloper #LearningInPublic #100DaysOfCode #Database #CleanCode #SoftwareEngineering #ProjectBuilding
To view or add a comment, sign in
-
🚀 Understanding How Hibernate Interacts with the Database🔄 Today, I spent some time exploring how Hibernate handles different types of queries, and it gave me a much clearer picture of how backend systems actually work behind the scenes. 💡 What I learned: 🔹 HQL (Hibernate Query Language) I worked with queries like FROM Product WHERE price > :price. What I like about HQL is that it works with objects instead of tables, which makes the code feel more natural and readable. 🔹 Native SQL Queries In some cases, I used queries like SELECT * FROM product. This is helpful when we need more control over the database or want to use database-specific features. 🔹 Named Queries I also tried using @NamedQuery, which makes queries reusable and keeps the code cleaner and easier to manage. 🔹 Composite Primary Keys Learned how to handle multiple fields as a primary key using @Embeddable and @EmbeddedId. This was a bit tricky at first, but very useful for real-world scenarios. 🔹 Query Execution Methods Used method executeUpdate() to fetch and modify data efficiently. 📄 What I practiced: I applied all of this on Product-related data — performing filtering, updating, and deleting using both HQL and Native SQL queries. Fayaz S Frontlines EduTech (FLM) #Hibernate #Java #BackendDevelopment #FullStackDevelopment #HQL #LearningJourney #FLM #FrontlinesEdutech
To view or add a comment, sign in
-
🚨 Performance Issues with Hibernate (and how to avoid them) Hibernate is powerful—but if you’re not careful, it can quietly destroy your application's performance. After working on large-scale systems, these are the most common issues I keep seeing: 🔴 1. N+1 Query Problem You fetch a list… and Hibernate fires one query per item. 👉 Example: Loading 100 orders = 101 queries 💥 Impact: Massive latency + database overload ✅ Fix: ▫️ Use JOIN FETCH ▫️ Use @EntityGraph ▫️ Consider DTO projections 🔴 2. LazyInitializationException (and bad fixes) Developers often switch everything to EAGER to "fix" it. 💥 Impact: Over-fetching → memory waste + slow queries ✅ Fix: ▫️ Keep LAZY by default ▫️ Control fetching explicitly in queries 🔴 3. Too Many SELECTs (chatty persistence layer) Multiple small queries instead of one optimized query. 💥 Impact: Network overhead + DB stress ✅ Fix: ▫️ Batch fetching (hibernate.default_batch_fetch_size) ▫️ Use IN queries ▫️ Optimize relationships 🔴 4. Missing Indexes Hibernate won’t save you from bad database design. 💥 Impact: Full table scans on large datasets ✅ Fix: ▫️ Add indexes on foreign keys and filters ▫️ Analyze execution plans 🔴 5. Dirty Checking Overhead Hibernate tracks all managed entities. 💥 Impact: High memory + CPU usage in large transactions ✅ Fix: ▫️ Use @Transactional(readOnly = true) when possible ▫️ Clear persistence context (EntityManager.clear()) 🔴 6. Uncontrolled Flushes Hibernate flushes more often than you expect. 💥 Impact: Extra queries + slower transactions ✅ Fix: ▫️ Use FlushModeType.COMMIT ▫️ Control flush manually in batch operations 🔴 7. Fetching Entire Entities When You Only Need a Few Fields Loading full objects when only 2–3 fields are needed. 💥 Impact: Memory waste + unnecessary joins ✅ Fix: ▫️ Use DTO projections (SELECT new ...) ▫️ Native queries when needed 💡 Final Thought Hibernate doesn’t make your app slow 👉 misusing Hibernate does. If you're building high-performance systems, you must understand what’s happening behind the scenes. 💬 Have you ever debugged a Hibernate performance issue in production? What was the root cause? #Java #Hibernate #Performance #Backend #SpringBoot #CleanCode
To view or add a comment, sign in
-
-
I ran into an illegal character this week at work. Java didn't like it at all but Oracle seemed to be OK with it. So, I had to find the offending character. Looking at the Java code where the error was thrown didn't help much, as the code was referencing multiple objects within the line, and there was no logging to show me the data it was processing at the time - I only had the database to work with. So I went to Google. I knew what I wanted to do, I just needed to refresh myself on regular expressions and the DUMP() function. Then it was just a matter of putting some SQL queries together to build out SQL queries to find characters that Java didn't like... I queries all_tab_columns for a list varchar2 columns in tables I believed were involved. I built SELECT commands to query each column's DUMP() equivalent so I could see if any of the ASCII values were outside the norm. I used REGEXP() as well to find any abnormal characters. Not only was I relying on the functions to find the data, I had to rely on reading some of the data to validate what the functions were looking at and what they were doing. I got very familiar with characters again - something I was masterful at when I was working in the world of DOS and ASCII. Back then I had the table memorized, Alt-205 was a regular in my keystroke arsenal. Regular expressions take that knowledge to a new level now. I never did find that illegal character. It wasn't in the database I was looking at, that's for sure. But then this application is pointed to a few data sources. When I was starting out I had all of commands memorized, their structure was engrained in my mind, and repetition of typing them out reinforced their memory. When I was stuck, I hit F1 and the help available to me could answer my question. That's all been augmented by smarter IDEs that fill out the functions and their structure, auto complete everything I'm typing out. I turn to Google to find Oracle documentation, Java help, and help with anything else I need, supported by professionals like myself who only augment the value of my search. I don't need to remember so much of the language as I do the intent, the logic I need to apply to the situation. I can find the right functions and expressions when I figure that out. But, it was my experience with all_tab_columns, my experience that needed me to write a query to write a query, and my experience with regular expressions that let me remember that I was able to do what I did this week. That experience has been enhanced by my mentors and coworkers along the way who shared their experience with me. On my own I was really good. With them, I was able to become so much better. Software development is a community whether we want to admit it or not - and it always has been - just look at the tools we've developed together through the years because we strive for more efficiency and reliability in our software. It's a group effort. We get better together.
To view or add a comment, sign in
-
🚀 Stop Manual Updates: The Magic of Hibernate Dirty Checking ✔️Ever wondered why your database updates even when you never called .save()? ✔️That’s not a bug; it’s one of Hibernate’s most powerful features. 🎭 The 4 Stages of an Entity’s Life ➡️ Think of Hibernate states as a "VIP Club" for your Java objects. 1️⃣. Transient (The Outsider) ✔️ The object is just a regular Java object. Hibernate doesn't even know it exists. ✔️It has no ID and no connection to the database. ✔️Example: User user = new User("JavaDev"); ✔️Just sitting in your RAM, minding its own business. 2️⃣. Persistent (The VIP Member) ✔️You’ve called .save() or .persist(). The object is now "Managed." ✔️Hibernate is officially "watching" every single change you make to this object. ✔️Example:session.save(user); ✔️Hibernate now tracks this user in its internal cache. 3️⃣. Detached (The Former Member) ✔️The Session is closed. ✔️ The object still has its data and its Database ID, but the "link" is broken. ✔️Hibernate has stopped watching. ✔️Example: session.close(); ✔️ If you change user.setName() now, nothing happens in the database. 4️⃣. Removed (The Evicted) ✔️The object is scheduled to be deleted. ✔️It’s still in your code for a moment, but it’s headed for the exit. ✔️Example: session.delete(user); ✔️ It will be wiped from the DB once the transaction commits. ✨ The "Dirty Checking" Secret ✔️Dirty Checking is the reason you can write cleaner code. ✔️When an object is in the Persistent state, Hibernate takes a "snapshot" of it. ✔️When the transaction is about to finish (Commit), Hibernate performs a quick comparison: 🔹Snapshot:Name: "Rahul" 🔹Current Object: Name: "Rahul Kumar" ✔️Hibernate detects the "Dirt": Aha! The name changed. I’ll handle the SQL update for you! 💡 Why should you care? 1️⃣.Cleaner Code: Your methods aren't cluttered with unnecessary .save() calls. 2️⃣. Performance:Hibernate is smart; if nothing actually changed (no "dirt" found), it won't even fire the SQL update. 3️⃣.Consistency:It ensures your Java memory and Database stay in perfect sync. ✔️What’s your favorite "hidden" Hibernate feature? Let’s discuss in the comments! 👇 #Java #Hibernate #SpringBoot #BackendDevelopment #CodingTips
To view or add a comment, sign in
-
-
Really interesting perspective on the trade-offs between Spring Data JPA and JDBC. In my experience working with backend systems, this balance between abstraction and control is always a challenge. While ORMs like JPA make development faster, they can sometimes hide what’s really happening at the SQL level, especially when dealing with performance issues. Tools like jOOQ are interesting because they give you more control over queries while still keeping the benefits of type safety and integration with Java. I think the key is choosing the right tool based on the problem—especially when performance and complex queries are involved. Curious to hear—have you used jOOQ in production, and how was your experience?
💡 Java Object-Oriented Querying. 👉 In terms of database access, the Java community is clearly divided into two camps: some like Spring Data JPA for its simplicity and low entry threshold. In contrast, others prefer Spring JDBC for its accuracy and query-tuning capabilities. 👉 Both Spring Data JPA and Spring Data JDBC, with their obvious advantages, have disadvantages that make development on them not very suitable for production. These solutions are two extremes, and we need a golden mean. 🔥 You may ask: What are the alternatives? And I will answer: Java Object-Oriented Querying. ⚠️ jOOQ (Java Object-Oriented Querying) is a Java library that allows you to write SQL queries directly in your code using a typed DSL (Domain-Specific Language) generated based on the database schema. When used with Spring Boot, jOOQ provides strong typing, query safety, and convenient database operations, making it an excellent alternative to ORMs like Hibernate for complex queries. 🔥 Unlike Spring Data JPA, jOOQ has no side effects. There is no N+1 problem (unless, of course, you create one yourself with suboptimal queries). All queries will be executed exactly as you define them and in exactly the number you specify. ➕ Benefits: ▪️ Code generation: jOOQ scans your database and generates Java classes corresponding to the tables and views. ▪️ Type safety: If you change a column name in the database, the project will not compile until you update the queries, which prevents runtime errors. ▪️ SQL-oriented: Unlike Hibernate (which hides SQL), jOOQ allows you to write full-fledged, complex SQL queries (JOINs, subqueries, window functions) in Java, while retaining control over what happens. ▪️ Integration with Spring: Spring Boot automatically configures jOOQ components, supporting transactions and mapping results to POJOs (Plain Old Java Objects). 🔥 DSL frameworks solve the problem of “translation” between Java and SQL, allowing you to write a database query in a Java-based architecture in such a way that it exactly matches the expected SQL query. ‼️ Examples: Result<Record> result = create..select() .from(AUTHOR) .where(AUTHOR..ID..gt(5)) .orderBy(AUTHOR..FIRST_NAME..asc()) .fetch(); for (Record r: result) { Integer id = r.getValue(AUTHOR..ID); String firstName = r.getValue(AUTHOR.FIRST_NAME); logger.log(Level..INFO, "ID: {}, Name: {}", id, firstName); } 📌 jOOQ is the perfect choice if you need full control over SQL but want to avoid manual JDBC data mapping and typos in SQL queries. #programmingtips #softwaredevelopment #data #spring
To view or add a comment, sign in
-
-
Running native queries in Spring? Hibernate's L2 cache doesn't know about native queries. When you bypass JPQL and fire raw SQL directly, Hibernate has no way to track the changes made. The stale data quietly stays in the cache. The fix: clearAutomatically = true on @Modifying @Query( value = "UPDATE products SET price = :price WHERE id = :id", nativeQuery = true ) @Modifying(clearAutomatically = true) @Transactional int updatePrice(@Param("price") BigDecimal price, @Param("id") Long id); This evicts the entire persistence context (L1 cache) after the bulk update. So the next read goes back to the DB. Real-world scenarios where this matters: 1) Bulk price updates in e-commerce (without clear, the old price is returned) 2) Soft deletes via native UPDATE (cached entity still shows as "active") 3) Batch status/audit flag changes (stale flags break downstream logic silently) 4) In-app data migrations running native DML during startup or scheduled jobs Advantages: 1) Prevents stale reads after bulk DML 2) Keeps L1 cache consistent with DB state 3) Zero boilerplate - one annotation flag Disadvantages: 1) Evicts the entire persistence context - not just the affected rows 2) Triggers an implicit flush before eviction (can surface unexpected dirty checks) 3) Hurts performance in large, long-running transactions 4) Does not invalidate L2 cache (Ehcache, Redis) - handle that separately Note: Use clearAutomatically = true whenever native bulk DML touches data already loaded in your persistence context. For L2 cache invalidation, pair it with @CacheEvict or a manual eviction call. #Java #SpringBoot #SpringDataJPA #Hibernate #SoftwareEngineering
To view or add a comment, sign in
-
Day: 3 &4 Java Program Structure Naming Conventions and Data types. Journey with Frontlines EduTech (FLM) and Fayaz S Program Structure:- Package package Name; import Package Name.ClassName; public Class Name { variables like int a = 10; int b = 20; public static void main (String []args){ } methods (public static void sum(){}); } Naming convention: class name:- Test, Test class, TestClassRole12. ClassName is always in Pascal case. Variables Names :- testClass, testRole. Variables name is always in camel case. Method Name:- Same as the variables. It will be started always in camel case. Ex:- connectToDb(){ } Ex:- add(){ } Package Names:- Package Names always in small letters Like :- com, com.test, com.demo Project Name:- Project name is also used Pascal case Same as the ClassName. Dataatypes In Java:- There are two days types 1. Primitive Data types 2. Non-primitive Data types 1. Primitive Data types:- These primitive data types are categorised into four types a. Interger data type b. Float data type c. Character data type d. Boolean data type a. Interger data types:- The integer data types are four types byte - 1 byte (8bits) Short - 2 byte(16bits) int - 4 byte (32bits) long - 8byte(64bits) b. Float data type:- The float are two types float - 4bytes ------> precision of 7digits double - 8bytes ----> precision of 16digits c. Character data types:- The character data types is used only single valued character which represents in single quotes. Ex:- K, A, H, C d Boolean data types:- The data type which is represented in the form of TRUE or FALSE. and its are only in small letters. The Boolean size is only 1 bit. Non-primitive Data types:- Non-primitive Data types are 5types 1. String 2. Class 3. Interface 4. Array 5. Enum. #corejava #namingConventions #Datatypes #java #frontlinemedia
To view or add a comment, sign in
-
Explore content categories
- Career
- Productivity
- Finance
- Soft Skills & Emotional Intelligence
- Project Management
- Education
- Technology
- Leadership
- Ecommerce
- User Experience
- Recruitment & HR
- Customer Experience
- Real Estate
- Marketing
- Sales
- Retail & Merchandising
- Science
- Supply Chain Management
- Future Of Work
- Consulting
- Writing
- Economics
- Artificial Intelligence
- Employee Experience
- Workplace Trends
- Fundraising
- Networking
- Corporate Social Responsibility
- Negotiation
- Communication
- Engineering
- Hospitality & Tourism
- Business Strategy
- Change Management
- Organizational Culture
- Design
- Innovation
- Event Planning
- Training & Development