1.JDBC
Java DataBasue Connectivity,java和数据库的连接API;
可以通过载入不同的数据库的“驱动程序”而与不同的数据库进行连接
2.JDBC 操作数据库基本步骤
在开发项目导入对应数据库的驱动类
1)注册驱动 : Class.forName("com.mysql.jdbc.Driver")
2)创建连接: Connection conn = DriverManager.getConnection(url,user,pass);
3)创建sql语句:
使用Statement
Statement st = null; //获取用于向数据库发送sql语句的statement st = conn.createStatement(); //向数据库发sql String sql = "select id,name,password,email,birthday from users"; st.executeQuery(sql);
使用 PrepareStatement: 可以避免sql注入问题
PreperedStatement st = null; String sql = "select * from users where name=? and password=?"; //获取用于向数据库发送sql语句的Preperedstatement st = conn.preparedStatement(sql);//在此次传入,进行预编译 st.setString(1, username); st.setString(2, password); //向数据库发sql st.executeQuery();//在这里不需要传入sql
4)执行语句:Result rs=st.executeQuery();
5)关闭资源:后创建的先关闭
if (pr!=null) { pr.close(); } if (rs!=null) { rs.close(); } if (con!=null) { con.close(); }
3.封装JDBC
导入驱动和数据源
1)配置文件 lib.properties
druid.url=jdbc:mysql://localhost:3306/jdbc_db?useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true druid.username=root druid.password=1234
2)JDBC封装文件 JdbcUtil.java
package com.dxj.util; import java.io.FileInputStream; import java.io.IOException; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.Properties; import com.alibaba.druid.pool.DruidDataSource; /** * 封装JDBC * @author Administrator * */ public class JdbcUtil { //创建数据源对象 private static DruidDataSource ds; //创建连接对象 private static Connection con; //创建PrepareStatement对象 private static PreparedStatement pr; //查询时使用 private static ResultSet rs; static { init(); } /** * 创建数据源对象,读取配置文件 */ public static void init() { //阿里数据源Druid ds=new DruidDataSource(); Properties pro=new Properties(); try { //读取配置文件 pro.load(new FileInputStream("src\com\dxj\resource\lib.properties")); } catch (IOException e) { e.printStackTrace(); } //配置文件 ds.configFromPropety(pro); } /** * 获取Connection()对象 */ public static void connect() { try { con=ds.getConnection(); } catch (SQLException e) { e.printStackTrace(); } } /** * 获取PrepareStatement对象 * @param sql * @param values */ public static void prepareStatement(String sql ,Object ...values) { try { pr=con.prepareStatement(sql); for (int i = 0; i < values.length; i++) { pr.setObject(i+1, values[i]); } } catch (SQLException e) { e.printStackTrace(); } } /** * 执行增、删、改 */ public static void update() { try { pr.executeUpdate(); } catch (SQLException e) { e.printStackTrace(); } } /** * 执行查询操作 * @return */ public static ResultSet query() { try { rs=pr.executeQuery(); } catch (SQLException e) { e.printStackTrace(); } return rs; } /** * 关闭操作 */ public static void close() { try { if (rs!=null) { rs.close(); } if (pr!=null) { pr.close(); } if (con!=null) { con.close(); } } catch (SQLException e) { e.printStackTrace(); } } }
3)测试
package com.dxj.test; import java.util.Random; import com.dxj.util.JdbcUtil; public class JianTest { public static void main(String[] args) { Random ran=new Random(); JdbcUtil.connect(); String jian="delete from test01_tab where u_id>?"; JdbcUtil.prepareStatement(jian,"5210"); JdbcUtil.update(); JdbcUtil.close(); } }
4. 数据库连接池
由于创建连接和释放连接都有很大的开销(尤其是数据库服务器不在本地时,每次建立连接都需要进行 TCP的三次握手,释放连接需要进行 TCP 四次握手,造成的开销是不可忽视的),为了提升系统访问数据库的性能,可以事先创建若干连接置于连接池中,需要时直接从连接池获取,使用结束时归还连接池而不必关闭连接
数据库连接池中的连接在应用服务器启动时被创建并在池中进行管理;
一个连接请求由池中的数据库连接提供;
当连接结束后,请求会被放回池中以供以后重用;
从而避免频繁创建和释放连接所造成的开销,这是典型的用空间换取时间的策略(浪费了空间存储连接,但节省了创建和释放连接的时间)
池化技术在 Java 开发中是很常见的,在使用线程时创建线程池的道理与此相同
基于 Java 的开源数据库连接池主要有:C3P0、Proxool、DBCP、BoneCP、Druid 等。
5.JDBC Statement和Preparement
与 Statement 相比:
1)PreparedStatement 接口代表预编译的语句,它主要的优势在于可以减少 SQL 的编译错误并增加 SQL 的安全性(减少 SQL 注射攻击的可能性);
2)PreparedStatement 中的 SQL 语句是可以带参数的,避免了用字符串连接拼接 SQL 语句的麻烦和不安全;
3)当批量处理 SQL 或频繁执行相同的查询时,PreparedStatement 有明显的性能上的优势,由于数据库可以将编译优化后的 SQL 语句缓存起来,下次执行相同结构的语句时就会很快(不用再次编译和生成执行计划)