JDBC
Java Database Connectivity,Java数据库连接
JDBC的本质是Java对所有关系型数据库进行连接操作所制定的一套规则,就是接口。
不同的数据库针对这套规则制定了相对应的实现类,我们需要使用这些已经做好的实现类,来使用Java对数据库进行连接和操作。
实现步骤:
1、导入jar包
在项目的根目录中创建lib文件夹 将mysql-connector-java-5.1.37-bin.jar复制到lib中 数据库驱动的版本一定要和数据的版本是对应的,如果版本差距过大是会报错的。 右键点击该jar包,选择Build Path,点击Add to Build Path
2、注册驱动
Class.forName("com.mysql.jdbc.Driver");
3、获取连接对象
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/库名", "用户名", "密码"); 访问本地数据库路径的简写:jdbc:mysql:///库名
4、编写SQL语句
5、获取执行对象
Statement state = conn.createStatement();
6、执行SQL语句
state.executeUpdate(sql) 实现增删改 state.executeQuery(sql) 实现查询
7、处理执行结果
如果是增删改,判断是否执行成功 executeUpdate方法返回int,用于判断增删改影响的记录数 如果是查询,获取结果集 executeQuery方法返回ResultSet结果集,查询得到的结果被封装在了这个结果集中。 需要遍历集合来获取所有查询的结果 使用方法: 1、next():判断是否有下一个可以获取的查询结果,返回布尔值 2、getXxx(int):在指定的记录中,通过字段的位置获取字段值 3、getXxx(String):在指定的记录中,通过字段名获取字段值 代码: ResultSet set = state.executeQuery(); while(set.next()){ set.getXxx(int/String); }
8、释放资源
if(conn != null){ try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } } if(state !=null){ try { state.close(); } catch (SQLException e) { e.printStackTrace(); } }
package jdbc; /** *增加 */ import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.sql.Statement; public class TeacherShow { public static void main(String[] args) { // 1.准备动作引入jar包 Connection conn = null; Statement state = null; try { // 2.注册驱动 Class.forName("com.mysql.jdbc.Driver"); // 3. 获取连接对象 // 参数1.要访问的数据库 参数2.数据库的用户名 参数3.数据库的密码 conn = DriverManager.getConnection("jdbc:mysql:///company", "root", "root"); // 4.编写SQL语句 String sql = "insert into stu values (null,'ls',21)"; // 5.获取执行对象 state = conn.createStatement(); // 6.执行SQL语句 int row = state.executeUpdate(sql); // 7.处理执行结果 if (row > 0) { System.out.println("添加成功"); } else { System.out.println("添加失败"); } } catch (ClassNotFoundException e) { System.out.println("驱动包加载失败"); } catch (SQLException e) { System.out.println("数据库连接失败"); } finally { // 8.释放资源 if (conn != null) { try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } } if (state != null) { try { state.close(); } catch (SQLException e) { e.printStackTrace(); } } } } }
package day18作业.No1; import java.sql.*; public class HomeworkQuery { public static void main(String[] args) { //写在外面因为finally要用 Connection connection = null; Statement statement = null; ResultSet set = null; try { Class.forName("com.mysql.jdbc.Driver"); connection = DriverManager.getConnection("jdbc:mysql:///dbs", "root", "root"); statement = connection.createStatement(); set = statement.executeQuery("select * from student"); while (set.next()) { System.out.println(set.getInt(1) + " " + set.getString("sname") + " " + set.getInt(3)); } } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } finally { if (set != null) { try { set.close(); } catch (SQLException e) { System.out.println("查找失败"); } } if (statement != null) { try { statement.close(); } catch (SQLException e) { System.out.println("执行失败"); } } if (connection != null) { try { connection.close(); } catch (SQLException e) { System.out.println("连接失败"); } } } } }
额外
- 在Java中资源释放要保持先开后关的原则。就是从里往外关,因为资源之间存在依赖关系。
- 在Java中写sql命令的时候,注意字符不要使用双引号,会和字符串引号冲突。
- 为什么把
Connection conn = null;Statement state = null;
写在try-catch外面?是因为作用域的问题,一旦写在try内部,finally就访问不了释放不了。 - 为什么要把他的值为空?还记得
只有成员变量有默认值,基本是0,引用时null
这句话。所以局部变量是没有默认值的。null相当于完成了初始化,不赋值相当于没有完成初始化。 - 为什么在sql命令拼接的时候使用
"+sql命令+"
?其实这没事吗好奇妙的,也不是语法。你会发现第一个"是上一个字符串的结尾,在Java中+
是作为字符串的拼接,而这中间的sql命令
其实也是字符类型的,总结起来不过是字符串的拼接罢了。不管拼接的是什么类型都会变成字符类型。
二. PreparedStatement
预编译的SQL
作用:防止SQL的注入问题
例如:xxx' or '1'='1,来完成登录功能。
使用步骤:
1、获取对象,并传入要执行的SQL语句
String sql = ""; PreparedStatement state = conn.prepareStatement(sql);
2、向SQL语句的占位符添加数据
state.setXxx(位置,数据); 例如:select * from 表名 where username = ? and password = ? state.setString(1,用户名); state.setString(2,密码);
3、执行SQL,不需要传入SQL语句
state.executeUpdate(); state.executeQuery();
三. 数据库连接池
概念:数据库连接池的本质是一个存储若干个数据库连接对象的容器(集合),用户在访问数据库时,可以直接从该容器中获取连接对象,对数据库进行操作,在使用完毕后将此连接对象归还到池中。
好处:
1、节省资源
2、提高访问效率
DataSource连接池接口
1、getConnection():获取连接
一般这个接口我们不会自己去实现,都用第三方做好的jar包
1、c3p0:Apache组织的
步骤: 1、导入c3p0-0.9.5.2.jar和mchange-commons-java-0.2.12.jar(c3p0要依赖这个包mchange-commons-java.jar) 2、在src下配置c3p0-config.xml文件 在文件中配置: <c3p0-config> <named-config name="mypool"> <property name="drvierClass">com.mysql.jdbc.Driver</property> <property name="jdbcUrl">jdbc:mysql://localhost:3306/库名</property> <property name="user">root</property> <property name="password">root</property> <property name="initialPoolSize">5</property> </named-config> </c3p0-config> 3、获取连接池 DataSource ds = new ComboPooledDataSource("mypool"); 4、获取连接对象 ds.getConntion(); 5、归还连接 ds.close();
2、druid:阿里巴巴的
步骤: 1、导入druid-1.0.9.jar 2、在项目的任意位置配置任意文件名的properties文件 在文件中配置 driverClassName=com.mysql.jdbc.Driver url=jdbc:mysql://localhost:3306/库名 username=root password=root initialSize=5 3、使用连接池工厂创建连接池 // 专门用于读取properties文件的类 Properties pro = new Properties(); // 使用load方法将properties文件载入 pro.load(JdbcUtils.class.getClassLoader().getResourceAsStream("druid.properties")); // 使用DruidDataSourceFactory创建连接池 ds = DruidDataSourceFactory.createDataSource(pro); 4、获取连接对象 ds.getConntion(); 5、归还连接 ds.close();
QueryRunner类的使用
dbutils中提供的一些工具。
- BeanHandler(对象类.class):返回一个对象
- BeanListHandler(对象类.class):返回对象集合
- ScalarHandler(对象类.class):聚合函数查询
这里一定要注意必须用long类型去接,不然int根本接不住啊,总是错,切记切记。