{"id":31743,"date":"2023-03-17T13:01:00","date_gmt":"2023-03-17T20:01:00","guid":{"rendered":"https:\/\/coderpad.io\/?p=31743"},"modified":"2023-06-05T13:37:11","modified_gmt":"2023-06-05T20:37:11","slug":"using-preparedstatement-in-jdbc-with-examples","status":"publish","type":"post","link":"https:\/\/coderpad.io\/blog\/development\/using-preparedstatement-in-jdbc-with-examples\/","title":{"rendered":"Using PreparedStatement in JDBC With Examples"},"content":{"rendered":"\n<p>The<a href=\"https:\/\/docs.oracle.com\/javase\/tutorial\/jdbc\/basics\/index.html\" target=\"_blank\" rel=\"noopener\"> JD\u00aeBC<\/a> (Java database connectivity) API defines a standard interface for Java applications to connect to different relational database (RDBMS) implementations. Most popular relational <a href=\"https:\/\/coderpad.io\/resources\/docs\/interview\/databases\/\">database<\/a> vendors provide JDBC-compliant drivers for their databases.<\/p>\n\n\n\n<p>The JDBC API provides the <a href=\"https:\/\/docs.oracle.com\/en\/java\/javase\/11\/docs\/api\/java.sql\/java\/sql\/Statement.html\" target=\"_blank\" rel=\"noopener\"><code>Statement<\/code><\/a> object to execute queries, updates, and DDL statements on data in a database. The <a href=\"https:\/\/docs.oracle.com\/en\/java\/javase\/11\/docs\/api\/java.sql\/java\/sql\/PreparedStatement.html\" target=\"_blank\" rel=\"noopener\"><code>PreparedStatement<\/code><\/a> is a subclass of` <code>Statement<\/code> that provides better security, portability across vendors, and performance.<\/p>\n\n\n\n<p>The <em>prepared<\/em> in the name comes from the fact that it&#8217;s prepared\/compiled initially and then reused rather than having to be compiled for each execution.<\/p>\n\n\n\n<p>This post will explain why and how to work with <code>PreparedStatements<\/code>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Usage<\/strong><\/h2>\n\n\n\n<p>Since a <code>PreparedStatement<\/code> is a subclass of <code>Statement<\/code>, it can do what a <code>Statement<\/code> can do, plus more.<\/p>\n\n\n\n<p>The fact that the <code>PreparedStatement<\/code> is pre-compiled is transparent to its users. Where it differs in usage is in its ability to specify parameters.<\/p>\n\n\n\n<p>The JDBC driver handles these parameters and thus, the handling is naturally compatible with the database we&#8217;re using. This leads to some benefits, as we will see later.<\/p>\n\n\n\n<p>Below is an example of using the <code>PreparedStatement<\/code> with two parameters:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java shcb-wrap-lines\">PreparedStatement insStm = conn.prepareStatement(<span class=\"hljs-string\">\"insert into emp values(?,?)\"<\/span>);\n\ninsStm.setInt(<span class=\"hljs-number\">1<\/span>, <span class=\"hljs-number\">1<\/span>);\n\ninsStm.setString(<span class=\"hljs-number\">2<\/span>, <span class=\"hljs-string\">\"Harry Potter\"<\/span>);\n\ninsStm.execute();<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>As shown above, we&#8217;re inserting records into the <code>emp<\/code> table. In the SQL command string, we denote the places where a parameter should be with a question mark. When specifying parameter values, we identify a parameter by its position in the SQL command.<\/p>\n\n\n\n<p>The starting position is 1 instead of the usual 0. If we use the same parameter value in multiple positions, we&#8217;ll have to set it for each position.<\/p>\n\n\n\n<p>The first parameter is an integer, so we use the <code>setInt<\/code> method. The second is a string, so we use <code>setString<\/code>. Using the strongly typed methods ensures that we won&#8217;t pass the wrong type of parameter by mistake.<\/p>\n\n\n\n<p>But if we were getting the parameters dynamically, say, from an array or collection, it would be cumbersome to check the type of each parameter and then use the corresponding set method. The <code>setObject<\/code> method is helpful here. Using it, we can set a parameter of any<a href=\"https:\/\/docs.oracle.com\/cd\/E19830-01\/819-4721\/beajw\/index.html\" target=\"_blank\" rel=\"noopener\"> supported type<\/a>.<\/p>\n\n\n\n<p>A PreparedStatement object is not <code>thread-safe;<\/code> we should not use the same instance concurrently from multiple threads.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Improper usage<\/strong><\/h3>\n\n\n\n<p>We can only use parameters where we would use values. If we try to use parameters to build other parts of the SQL command, it won&#8217;t work. For example, what we see here would fail with an <code>SQLSyntaxErrorException<\/code>:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java shcb-wrap-lines\">PreparedStatement pStm = conn.prepareStatement(<span class=\"hljs-string\">\"select * from ?\"<\/span>);\n\npStm.setString(<span class=\"hljs-number\">1<\/span>, <span class=\"hljs-string\">\"emp\"<\/span>);\n\npStm.execute();<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Here, we&#8217;re trying to provide the table name as a parameter. However, this isn&#8217;t allowed, nor would any other syntax part be, like column names, <code><a href=\"https:\/\/coderpad.io\/blog\/development\/sql-functions-and-techniques-every-data-person-should-know\/\">where clause, group by, order<\/a><\/code> by, etc.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Security<\/strong><\/h2>\n\n\n\n<p>A <code>PreparedStatement<\/code> provides better security against certain hacking attacks compared with its parent, the Statement. The <code>Statement<\/code> object executes a string command. If it needs to use some parameters, we must concatenate them as strings with the SQL command. This creates a risk of the command being changed to something else using the parameters.<\/p>\n\n\n\n<p>Consider the query below using string concatenation to validate a user&#8217;s login:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"SQL (Structured Query Language)\" data-shcb-language-slug=\"sql\"><span><code class=\"hljs language-sql shcb-wrap-lines\">\"<span class=\"hljs-keyword\">select<\/span> * <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-keyword\">user<\/span> <span class=\"hljs-keyword\">where<\/span> user_name = <span class=\"hljs-string\">'\" + usrName + \"'<\/span><span class=\"hljs-string\">\"<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">SQL (Structured Query Language)<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">sql<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Here, <code>usrName<\/code> is a string that the application&#8217;s user has provided. If a malicious user were to enter usrName as <code>' or '1'='1<\/code> (note the single quotes used), the query string now becomes<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"SQL (Structured Query Language)\" data-shcb-language-slug=\"sql\"><span><code class=\"hljs language-sql shcb-wrap-lines\"><span class=\"hljs-keyword\">select<\/span> * <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-keyword\">user<\/span> <span class=\"hljs-keyword\">where<\/span> user_name = <span class=\"hljs-string\">''<\/span> <span class=\"hljs-keyword\">or<\/span> <span class=\"hljs-string\">'1'<\/span>=<span class=\"hljs-string\">'1'<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">SQL (Structured Query Language)<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">sql<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>This SQL command now circumvents the check for <code>user_name<\/code>, since the added OR condition is always true. If the database allows us to run multiple commands in a go (separated by a semicolon, for example), then a hacker could append a destructive command like delete or drop as well. This type of hacking attack using injected parameters to alter the SQL command is called an <strong>SQL injection <\/strong>attack.<\/p>\n\n\n\n<p>Now, let&#8217;s try using a <code>PreparedStatement<\/code> instead. Using <code>PreparedStatement<\/code>, the above code would become<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java shcb-wrap-lines\">PreparedStatement loginStm = conn.prepareStatement(<span class=\"hljs-string\">\"select * from user where user_name = ?\"<\/span>);\n\nloginStm.setInt(<span class=\"hljs-number\">1<\/span>, usrName);\n\nloginStm.execute();<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>What&#8217;s different here? The JDBC driver is handling the parameters. It&#8217;ll send the parameters to the database as variables bound to the pre-compiled SQL command. The database will escape the special character within them if needed. For example, it usually escapes a single quote with an additional single quote. Thus, the malicious value remains a value, and it cannot change the SQL command.<\/p>\n\n\n\n<p>Note that we can use a <code>Statement<\/code> and escape the values ourselves before concatenating, but the escaping syntax can differ from database to database and hence, it&#8217;s best to let the JDBC driver handle it.<\/p>\n\n\n\n<p>Also, there are still other advantages to using a <code>PreparedStatement<\/code>. Read on.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Portability and ease of use<\/strong><\/h2>\n\n\n\n<p>When we use string concatenation to inject parameters into the SQL command, we have to format and escape the values too. Also, this part could be database specific, making our code less portable across different database implementations.<\/p>\n\n\n\n<p>We&#8217;ve seen an example of this in the <strong>SQL injection<\/strong> section above. Parameters in PreparedStatement make our life easier and keep the code portable since the JDBC driver handles them.<\/p>\n\n\n\n<p>Let&#8217;s see another example using dates. Let&#8217;s assume the user has entered a date and wants to filter records by that date. If we were building the query as a string, then we would need to convert the date into a string:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-6\" data-shcb-language-name=\"SQL (Structured Query Language)\" data-shcb-language-slug=\"sql\"><span><code class=\"hljs language-sql shcb-wrap-lines\">\"<span class=\"hljs-keyword\">select<\/span> * <span class=\"hljs-keyword\">from<\/span> sales <span class=\"hljs-keyword\">where<\/span> sale_date &gt; <span class=\"hljs-string\">'\" + user_date_string + \"'<\/span><span class=\"hljs-string\">\"<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-6\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">SQL (Structured Query Language)<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">sql<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>What should be the format of the date string? For example, should it be <code>dd-MM-YY<\/code> or <code>MM-dd-YY<\/code>, etc.?<\/p>\n\n\n\n<p>This would work only if the format of <code>user_date_string<\/code> matches the default date format for the database. The default date format can vary from one database instance to another, so we cannot be sure about it.<\/p>\n\n\n\n<p>We could use some database function like <code>TO_DATE<\/code> that will parse the <code>user_date_string<\/code> with the given format and convert it back into the date.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-7\" data-shcb-language-name=\"SQL (Structured Query Language)\" data-shcb-language-slug=\"sql\"><span><code class=\"hljs language-sql shcb-wrap-lines\">\"<span class=\"hljs-keyword\">select<\/span> * <span class=\"hljs-keyword\">from<\/span> sales <span class=\"hljs-keyword\">where<\/span> sale_date &gt; <span class=\"hljs-keyword\">TO_DATE<\/span>( <span class=\"hljs-string\">'DD-MM-YYYY'<\/span>, <span class=\"hljs-string\">'\" + user_date_string + \"'<\/span>)<span class=\"hljs-string\">\"<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-7\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">SQL (Structured Query Language)<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">sql<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>However, the syntax of functions like <code>TO_DATE<\/code> is specific to a database vendor; others might not have the same name or parameters. Some<a href=\"https:\/\/docs.oracle.com\/javadb\/10.8.3.0\/ref\/rrefjdbc88908.html\" target=\"_blank\" rel=\"noopener\"> functions are supported by the JDBC<\/a> spec using the <code>fn<\/code> keyword, but many JDBC drivers don&#8217;t have implementations for these.<\/p>\n\n\n\n<p>So, it&#8217;s <code>PreparedStatement<\/code> to the rescue:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-8\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java shcb-wrap-lines\">PreparedStatement dateFilterStm = conn.prepareStatement(<span class=\"hljs-string\">\"select * from sales where sale_date &gt; ?)\"<\/span>;\n\ndateFilterStm.setDate( <span class=\"hljs-number\">1<\/span>, usrDate);<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-8\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>All we need to do is pass the date as <code>java.util.Date<\/code> or <code>java.sql.Date<\/code> to the <code>PreparedStatement<\/code>. There&#8217;s no worrying about escaping or formatting or portability.<\/p>\n\n\n\n<p>PreparedStatement rocks!<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Performance<\/strong><\/h2>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Pre-compilation<\/strong><\/h3>\n\n\n\n<p>We mentioned at the start that the SQL command used in a PreparedStatement is pre-compiled or prepared initially and then reused.<\/p>\n\n\n\n<p>What does pre-compile mean, and who does it? When we run an SQL command on the database, the database will first validate, parse, and build an execution plan to run it. These steps come under pre-compiling.<\/p>\n\n\n\n<p>When the JDBC driver creates a prepared statement, it will ask the database to pre-compile that SQL command. Then, the database will store the pre-compiled command in a cache for the current database connection. If the same SQL command is to be run multiple times, using the pre-compiled version is better for performance since the compilation part has to be done only once.<\/p>\n\n\n\n<p>The database has a limited cache for pre-compiled SQL commands and hence, we cannot have too many of them. Defining parameters helps make the command reusable and therefore reduces the number of distinct commands.<\/p>\n\n\n\n<p>If the parameters weren&#8217;t separate, the same command with different parameters would each become a separate command.<\/p>\n\n\n\n<p>For example:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-9\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java shcb-wrap-lines\">select * from emp where name = <span class=\"hljs-string\">'Goldstein'<\/span>;\n\nselect * from emp where name = <span class=\"hljs-string\">'Mukherjee'<\/span>;\n\nselect * from emp where name = ?;<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-9\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>In the above examples, the first two SQL commands are distinct since we didn&#8217;t define the parameters separately. Whereas, if we had used a PreparedStatement as in the third, then they could have used the same SQL command.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Reusing<\/strong><\/h3>\n\n\n\n<p>Using the same <code>PreparedStatement<\/code> multiple times in the same database session\/connection will be better for performance. Each time, we need to set the parameters and execute the <code>PreparedStatement<\/code>. For example, we could use it to repeatedly insert data into a table<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-10\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java shcb-wrap-lines\">PreparedStatement insStm = conn.prepareStatement(<span class=\"hljs-string\">\"insert into emp values(?,?)\"<\/span>);\n\ninsStm.setInt(<span class=\"hljs-number\">1<\/span>, <span class=\"hljs-number\">1<\/span>);\n\ninsStm.setString(<span class=\"hljs-number\">2<\/span>, <span class=\"hljs-string\">\"Harry Potter\"<\/span>);\n\ninsStm.execute();\n\ninsStm.setInt(<span class=\"hljs-number\">1<\/span>, <span class=\"hljs-number\">2<\/span>);\n\ninsStm.setString(<span class=\"hljs-number\">2<\/span>, <span class=\"hljs-string\">\"Tom Riddle\"<\/span>);\n\ninsStm.execute();\n\ninsStm.close();<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-10\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>or we could do the set parameters and <code>execute()<\/code> inside a loop. This is still not the best solution since each <code>execute()<\/code> will mean a round trip to the database.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Batching<\/strong><\/h3>\n\n\n\n<p>We can send <strong><em>n<\/em><\/strong> number of statements in a single batch to the database, where <strong><em>n<\/em><\/strong> is up to us to decide. This will reduce the round trips and greatly improve performance. Below is an example using batching.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-11\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java shcb-wrap-lines\">PreparedStatement insStm = conn.prepareStatement(<span class=\"hljs-string\">\"insert into emp values(?,?)\"<\/span>);\n\nList&lt;String&gt; names = List.of( <span class=\"hljs-string\">\"Wareen Buffet\"<\/span>, <span class=\"hljs-string\">\"Steve Jobs\"<\/span>, <span class=\"hljs-string\">\"Bill Gates\"<\/span>);\n\n<span class=\"hljs-keyword\">boolean<\/span> moreRows = <span class=\"hljs-keyword\">false<\/span>;\n\n<span class=\"hljs-keyword\">int<\/span> i=<span class=\"hljs-number\">0<\/span>;\n\n<span class=\"hljs-keyword\">for<\/span>( i=<span class=\"hljs-number\">0<\/span>; i&lt; names.size(); i++) {\n\n  insStm.setInt(<span class=\"hljs-number\">1<\/span>, i+<span class=\"hljs-number\">1<\/span>);\n  \n  insStm.setString(<span class=\"hljs-number\">2<\/span>,names.get(i));\n\n  insStm.addBatch();\n\n  <span class=\"hljs-keyword\">if<\/span>( i % <span class=\"hljs-number\">100<\/span> == <span class=\"hljs-number\">0<\/span>) {\n\n    <span class=\"hljs-comment\">\/\/ execute every 100 rows<\/span>\n\n    <span class=\"hljs-keyword\">int<\/span>&#91;] rowCounts = insStm.executeBatch();\n  }\n\n}\n\n<span class=\"hljs-keyword\">if<\/span>( i % <span class=\"hljs-number\">100<\/span> != <span class=\"hljs-number\">0<\/span>) {\n\n  <span class=\"hljs-comment\">\/\/ lef tover rows<\/span>\n\n  <span class=\"hljs-keyword\">int<\/span>&#91;] rowCounts = insStm.executeBatch();\n\n}\n\ninsStm.close();<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-11\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Here, we call set parameters and <code>addBatch()<\/code> for each row in the loop. The <code>addBatch()<\/code> will store the current parameters for later execution.<\/p>\n\n\n\n<p>When the counter is a multiple of 100, we&#8217;ll execute the batched rows in one go. In our case, that means 100 at a time.<\/p>\n\n\n\n<p><code>executeBatch()<\/code> returns an array of integers corresponding to the number of rows affected by each statement in the batch. The SQL command needs to be sent to the database only once for pre-compilation. The batch needs to send a reference to the pre-compiled command and the parameters for all the rows in the batch.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Conclusion<\/strong><\/h2>\n\n\n\n<p>In this post, we&#8217;ve seen when and why we should use PreparedStatements, along with examples using code.<\/p>\n\n\n\n<p>PreparedStatements are the preferred way to execute SQL commands using the JDBC API since they offer better security, ease of use, portability, and performance.<\/p>\n\n\n\n<p><em>This post was written by Manoj Mokashi. <\/em><a href=\"https:\/\/www.linkedin.com\/in\/manojmokashi\/\" target=\"_blank\" rel=\"noopener\"><em>Manoj<\/em><\/a><em> has more than 25 years of experience as a developer, mostly on java, web technologies, and databases. He\u2019s also worked on PHP, Python, Spark, AI\/ML, and Solr and he really enjoys learning new things.<\/em><\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this post, we&#8217;ll see why and how to work with JDBC and PreparedStatement. We will also learn along with examples using code.<\/p>\n","protected":false},"author":1,"featured_media":31782,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[9],"tags":[],"persona":[29],"blog-programming-language":[51],"keyword-cluster":[],"class_list":["post-31743","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-development"],"acf":[],"_links":{"self":[{"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/posts\/31743","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/comments?post=31743"}],"version-history":[{"count":41,"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/posts\/31743\/revisions"}],"predecessor-version":[{"id":31787,"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/posts\/31743\/revisions\/31787"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/media\/31782"}],"wp:attachment":[{"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/media?parent=31743"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/categories?post=31743"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/tags?post=31743"},{"taxonomy":"persona","embeddable":true,"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/persona?post=31743"},{"taxonomy":"blog-programming-language","embeddable":true,"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/blog-programming-language?post=31743"},{"taxonomy":"keyword-cluster","embeddable":true,"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/keyword-cluster?post=31743"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}