1 There are several shortcomings when using Statement to execute SQL statements containing dynamic information:
1.1 Due to the need to splice dynamic data Into the SQL statement, which results in high program complexity and prone to errors
1.2 If the spliced data contains SQL syntax content, the meaning of the spliced SQL syntax will change and appear SQL injection attack
1.3 When executing SQL in large batches with the same semantics but containing dynamic dataThe efficiency is very poor
2 Reasons why it is not good to use Statement to execute SQL statements
2.1 When executing a SQL statement and sending it to the database, the database first parses the SQL and generates an execution plan (this process will consume resources and performance), if If you execute the same SQL statement multiple times, the database will reuse the execution plan. However, if you execute SQL with the same semantics but containing dynamic data multiple times, the database will generate different execution plans, seriously affecting the database overhead
2.2 For example
Execute SELECT * FROM userifo_fury Generate an execution plan and execute SELECT * FROM userifo_fury again will reuse the above execution plan (becauseThis is a static SQL statement
However, execute INSERT INTO userifo VALUES(1, 'JACK','122314','141234@QQ.COM','FURY',15600) ) Generate an execution plan and then execute itINSERT INTO userifo VALUES(2, 'rose','122314','141234@QQ.COM','FURY',15600)Due to different contents,will generateanother execution plan again. If INSERT in the above situation is executed 1000 times, the database will generate 1000 execution plans, which will seriously affect the efficiency of the database
Therefore, Statement is only suitable forExecute static SQL statements, is not suitable for execute dynamic SQL statements
##
3 Use PreparedStatement instead of StatementEasy to write
No SQL injection problem
Batch execution of SQL statements with the same semantics will reuse the execution plan
1 package cn.xiangxu.entity; 2 3 import java.io.Serializable; 4 5 public class User implements Serializable { 6 7 private static final long serialVersionUID = -5109978284633713580L; 8 9 private Integer id;10 private String name;11 private String pwd;12 public User() {13 super();14 // TODO Auto-generated constructor stub15 }16 public User(Integer id, String name, String pwd) {17 super();18 this.id = id;19 this.name = name;20 this.pwd = pwd;21 }22 @Override23 public int hashCode() {24 final int prime = 31;25 int result = 1;26 result = prime * result + ((id == null) ? 0 : id.hashCode());27 return result;28 }29 @Override30 public boolean equals(Object obj) {31 if (this == obj)32 return true;33 if (obj == null)34 return false;35 if (getClass() != obj.getClass())36 return false;37 User other = (User) obj;38 if (id == null) {39 if (other.id != null)40 return false;41 } else if (!id.equals(other.id))42 return false;43 return true;44 }45 public Integer getId() {46 return id;47 }48 public void setId(Integer id) {49 this.id = id;50 }51 public String getName() {52 return name;53 }54 public void setName(String name) {55 this.name = name;56 }57 public String getPwd() {58 return pwd;59 }60 public void setPwd(String pwd) {61 this.pwd = pwd;62 }63 @Override64 public String toString() {65 return "User [id=" + id + ", name=" + name + ", pwd=" + pwd + "]";66 }67 68 69 70 }Entity class corresponding to the user table
1 package testJDBC; 2 3 import java.sql.Connection; 4 import java.sql.DriverManager; 5 import java.sql.PreparedStatement; 6 import java.sql.ResultSet; 7 import java.sql.SQLException; 8 import java.util.ArrayList; 9 import java.util.List;10 11 import org.junit.Test;12 13 import cn.xiangxu.entity.User;14 15 public class TestCase {16 @Test17 public void test01() {18 Connection conn = null;19 PreparedStatement ps = null;20 ResultSet rs = null;21 try {22 Class.forName("com.mysql.jdbc.Driver"); // 加载数据库驱动23 24 conn = DriverManager.getConnection( // 初始化连接对象25 "jdbc:mysql://localhost:3306/test", "root", "182838");26 27 28 String sql = "SELECT * FROM user WHERE pwd = ? "; // 拼接SQL语句,位置参数用?代替29 30 ps = conn.prepareStatement(sql); // 初始化预编译执行对象31 32 ps.setString(1, "182838"); // 设置SQL语句中的位置位置参数(注意:是从1开始数不是从0开始数)33 34 rs = ps.executeQuery(); // 执行SQL语句35 36 List<user> users = new ArrayList<user>(); // 创建一个集合来存放记录对象37 while(rs.next()) { // 遍历结果集38 // System.out.println("====================");39 // System.out.println(rs.getInt("id"));40 // System.out.println(rs.getString("name"));41 // System.out.println(rs.getString("pwd"));42 User user = new User();43 user.setId(rs.getInt("id"));44 user.setName(rs.getString("name"));45 user.setPwd(rs.getString("pwd"));46 users.add(user); // 向集合中添加元素47 }48 49 System.out.println(users); // 打印输出集合50 for(User user : users) {51 System.out.println(user);52 }53 54 // 释放资源55 rs.close();56 ps.close(); 57 conn.close();58 59 } catch (Exception e) {60 // TODO Auto-generated catch block61 e.printStackTrace();62 } finally {63 if(rs != null) {64 try {65 rs.close();66 } catch (SQLException e) {67 // TODO Auto-generated catch block68 e.printStackTrace();69 }70 }71 if(ps != null) {72 try {73 ps.close();74 } catch (SQLException e) {75 // TODO Auto-generated catch block76 e.printStackTrace();77 }78 }79 if(conn != null) {80 try {81 conn.close();82 } catch (SQLException e) {83 // TODO Auto-generated catch block84 e.printStackTrace();85 }86 }87 }88 89 }90 91 }</user></user>Instance of using precompiled Statement
4 利用Properties对象读取properties配置文件中的信息
4.1 Properties继承了Hashtable类,Properties对象也是使用键值对的方式来保存数据,但是Properties对象的键和值都是字符串类型
class Properties extends Hashtable
4.2 Properties 类中的主要方法
4.2.1 public synchronized void load(InputStream inStream) throws IOException
将properties属性文件的文件输入流加载到Properties对象
4.2.2 public void store(OutputStream out, String comments) throws IOException
将Properties对象中的属性列表保存到输出流文件中
注意:第二个参数表示注释信息(注意:properties文件中不能用中文),在注释信息后面会自动添加一个时间信息
注意:新创建的文件在项目的根目录下面(问题:为什么在eclipse中没有,但是到文件夹中却能找到???)
4.2.3 public String getProperty(String key)
获取属性值,参数是属性的键
4.2.4 public synchronized Object setProperty(String key, String value)
修改属性值,参数1是属性的键,参数2是属性的新值
4.3 案例
要求:读取properties配置文件总的属性值,将读取到的属性值进行修改后保存到另外一个properties配置文件中


1 package cn.xiangxu.entity; 2 3 import java.io.FileInputStream; 4 import java.io.FileOutputStream; 5 import java.io.InputStream; 6 import java.util.Iterator; 7 import java.util.Properties; 8 9 public class Test {10 public static void main(String[] args) {11 try {12 Properties prop = new Properties(); // 创建Properties对象13 14 // prop.load(new FileInputStream("config.properties")); // 使用这种方式时,配置文件必须放在项目的根目录下15 InputStream is = Test.class.getClassLoader().getResourceAsStream("config/config.properties"); // 读取属性文件16 17 prop.load(is); // 加载属性列表18 19 Iterator<string> it=prop.stringPropertyNames().iterator(); // 将配置文件中的所有key放到一个可迭代对象中20 while(it.hasNext()){ // 利用迭代器模式进行迭代21 String key=it.next(); // 读取下一个迭代对象的下一个元素22 System.out.println(key+":"+prop.getProperty(key)); // 根据key值获取value值(获取属性信息)23 }24 25 is.close(); // 关闭输入流,释放资源26 27 FileOutputStream oFile = new FileOutputStream("b.properties", true);//创建一个输出流文件,true表示追加打开28 prop.setProperty("maxactive", "33"); // 修改属性信息29 prop.store(oFile, "zhe shi yi ge xin de shu xing pei zhi wen jian."); // 将Properties对象中的内容放到刚刚创建的文件中去30 oFile.close(); // 关闭输出流,释放资源31 32 } catch (Exception e) {33 // TODO Auto-generated catch block34 e.printStackTrace();35 } 36 }37 }</string>
等待读取的properties配置文件的位置如下图所示
5 数据库连接池
5.1 什么是数据库连接池
程序启动时就创建足够多的数据库连接,并将这些连接组成一个连接池,由程序自动地对池中的连接进行申请、使用、释放
5.2 数据库连接池的运行机制
》程序初始化时创建连接池
》需要操作数据库时向数据库连接池申请一个可用的数据库连接
》使用完毕后就将数据库连接还给数据库连接池(注意:不是关闭连接,而是交给连接池)
》整个程序退出时,断开所有连接,释放资源(即:管理数据库连接池的那个线程被杀死后才关闭所有的连接)
5.3 数据库连接池的编程步骤
5.3.1 导包
5.3.2 声明ThreadLocal、BasicDataSource成员变量(注意:这两个成员变量是静态的)
5.3.3 在静态代码块中实例化那两个成员变量,并通过Properties对象读取配置文件信息,利用这些配置文件信息给BasicDataSource对象进行初始化处理
5.3.4 编写创建连接静态方法
利用BasicDataSource对象实例化一个连接对象
将这个连接对象放到ThreadLocal对象中
5.3.5 编写释放连接静态方法
从ThreadLocal对象中获取连接对象
清空ThreadLocal对象
判断连接对象是否释放
6 利用数据库连接池操作数据库
项目结构图
2 # deng hao liang bian mei you kong ge, mo wei mei you fen hao3 # hou mian bu neng you kong ge4 driverClassName=com.mysql.jdbc.Driver5 url=jdbc:mysql://localhost:3306/test6 username=root7 password=1828388 maxActive=1009 maxWait=3000
1 <project> 2 <modelversion>4.0.0</modelversion> 3 <groupid>cn.xiangxu</groupid> 4 <artifactid>testJDBC</artifactid> 5 <version>0.0.1-SNAPSHOT</version> 6 <dependencies> 7 <dependency> 8 <groupid>mysql</groupid> 9 <artifactid>mysql-connector-java</artifactid>10 <version>5.1.37</version>11 </dependency>12 <dependency>13 <groupid>junit</groupid>14 <artifactid>junit</artifactid>15 <version>4.12</version>16 </dependency>17 <dependency>18 <groupid>commons-dbcp</groupid>19 <artifactid>commons-dbcp</artifactid>20 <version>1.4</version>21 </dependency>22 </dependencies>23 </project>
1 package cn.xiangxu.tools; 2 3 import java.io.IOException; 4 import java.io.InputStream; 5 import java.sql.Connection; 6 import java.sql.SQLException; 7 import java.util.Properties; 8 9 import org.apache.commons.dbcp.BasicDataSource;10 11 public class DBUtil {12 /*13 * ThreadLocal用于线程跨方法共享数据使用14 * ThreadLocal内部有一个Map, key为需要共享数据的线程本身,value就是其需要共享的数据15 */16 private static ThreadLocal<connection> tl; // 声明一个类似于仓库的东西17 private static BasicDataSource dataSource; // 声明一个数据库连接池对象18 19 // 静态代码块,在类加载的时候执行,而且只执行一次20 static {21 tl = new ThreadLocal<connection>(); // 实例化仓库对象22 dataSource = new BasicDataSource(); // 实例数据库连接池对象23 24 Properties prop = new Properties(); // 创建一个Properties对象用(该对象可以用来加载配置文件中的属性列表)25 InputStream is = DBUtil.class.getClassLoader().getResourceAsStream("config/mysql.properties"); // 读取配置文件信息26 try {27 prop.load(is); // 加载配置文件中的属性列表28 29 String driverClassName = prop.getProperty("driverClassName"); // 获取属性信息30 String url = prop.getProperty("url");31 String username = prop.getProperty("username");32 String password = prop.getProperty("password");33 Integer maxActive = Integer.parseInt(prop.getProperty("maxActive"));34 Integer maxWait = Integer.parseInt(prop.getProperty("maxWait"));35 36 dataSource.setDriverClassName(driverClassName); // 初始化数据库连接池(即:配置数据库连接池的先关参数)37 dataSource.setUrl(url);38 dataSource.setUsername(username);39 dataSource.setPassword(password);40 dataSource.setMaxActive(maxActive);41 dataSource.setMaxWait(maxWait);42 43 is.close(); // 关闭输入流,释放资源44 } catch (IOException e) {45 // TODO Auto-generated catch block46 e.printStackTrace();47 } 48 49 }50 51 /**52 * 创建连接对象(注意:静态方法可以直接通过类名来调用)53 * @return 连接对象54 * @throws Exception55 */56 public static Connection getConnection() throws Exception { 57 try {58 Connection conn = dataSource.getConnection(); // 创建连接对象(利用数据库连接池进行创建)59 tl.set(conn); // 将连接对象放到仓库中60 return conn; 61 } catch (Exception e) {62 // TODO Auto-generated catch block63 e.printStackTrace();64 throw e;65 }66 }67 68 /**69 * 关闭连接对象(注意:静态方法可以通过类名直接调用)70 * @throws Exception71 */72 public static void closeConnection() throws Exception {73 Connection conn = tl.get(); // 从仓库中取出连接对象74 tl.remove(); // 清空仓库75 if(conn != null) { // 判断连接对象是否释放资源76 try {77 conn.close();78 } catch (Exception e) {79 // TODO Auto-generated catch block80 e.printStackTrace();81 throw e;82 }83 }84 }85 86 }</connection></connection>
1 package testJDBC; 2 3 import java.sql.Connection; 4 import java.sql.PreparedStatement; 5 import java.sql.ResultSet; 6 7 import org.junit.Test; 8 9 import cn.xiangxu.tools.DBUtil;10 11 public class TestDBUtil {12 @Test13 public void test01() {14 try {15 Connection conn = DBUtil.getConnection(); // 创建连接对象16 String sql = "SELECT * FROM user "; // 拼接SQL语句17 PreparedStatement ps = conn.prepareStatement(sql); // 创建执行对象18 ResultSet rs = ps.executeQuery(sql); // 执行SQL语句19 while(rs.next()) { // 遍历结果集20 System.out.println(rs.getString("name"));21 }22 } catch (Exception e) {23 e.printStackTrace();24 } finally { // 关闭连接,释放资源25 try {26 DBUtil.closeConnection();27 } catch (Exception e) {28 e.printStackTrace();29 }30 }31 }32 }
The above is the detailed content of JDBC connection database example explanation. For more information, please follow other related articles on the PHP Chinese website!

The article discusses using Maven and Gradle for Java project management, build automation, and dependency resolution, comparing their approaches and optimization strategies.

The article discusses creating and using custom Java libraries (JAR files) with proper versioning and dependency management, using tools like Maven and Gradle.

The article discusses implementing multi-level caching in Java using Caffeine and Guava Cache to enhance application performance. It covers setup, integration, and performance benefits, along with configuration and eviction policy management best pra

The article discusses using JPA for object-relational mapping with advanced features like caching and lazy loading. It covers setup, entity mapping, and best practices for optimizing performance while highlighting potential pitfalls.[159 characters]

Java's classloading involves loading, linking, and initializing classes using a hierarchical system with Bootstrap, Extension, and Application classloaders. The parent delegation model ensures core classes are loaded first, affecting custom class loa


Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

AI Hentai Generator
Generate AI Hentai for free.

Hot Article

Hot Tools

SublimeText3 English version
Recommended: Win version, supports code prompts!

mPDF
mPDF is a PHP library that can generate PDF files from UTF-8 encoded HTML. The original author, Ian Back, wrote mPDF to output PDF files "on the fly" from his website and handle different languages. It is slower than original scripts like HTML2FPDF and produces larger files when using Unicode fonts, but supports CSS styles etc. and has a lot of enhancements. Supports almost all languages, including RTL (Arabic and Hebrew) and CJK (Chinese, Japanese and Korean). Supports nested block-level elements (such as P, DIV),

MinGW - Minimalist GNU for Windows
This project is in the process of being migrated to osdn.net/projects/mingw, you can continue to follow us there. MinGW: A native Windows port of the GNU Compiler Collection (GCC), freely distributable import libraries and header files for building native Windows applications; includes extensions to the MSVC runtime to support C99 functionality. All MinGW software can run on 64-bit Windows platforms.

SublimeText3 Chinese version
Chinese version, very easy to use

SublimeText3 Mac version
God-level code editing software (SublimeText3)