1.导包
2.注册驱动
3.获取的连接对象
4.准备sql语句 都是字符串
5.通过数据库的连接获取数据库的执行对象
6.通过执行对象执行sql语句,将sql语句发送给数据库,(DDL语句/DML语句)
7.释放资源
public class JdbcDemo { public static void main(String[] args) throws Exception { // 1)导包 // 如果自己的mysql服务是5.5/5.7 ,导入的驱动jar包 5.1jar包 // 如果自己的mysql服务是8.0,导入的驱动jar包8.0jar包 // 2)注册驱动 Class.forName("com.mysql.jdbc.Driver") ; //mysql驱动jar包5.1的时候用的 // Class.forName("com.mysql.cj.jdbc.Driver") ; //mysql驱动jar包是8.0的使用使用的 // DriverManager.registerDriver(new com.mysql.jdbc.Driver()); // 3)获取的连接对象 /* 驱动管理类 管理jdbc服务的: DriverManager public static Connection getConnection( String url, //统一自定义定位符:连接的是哪个库 String user, //登录mysql的用户名 root String password)//登录mysql的密码 */ Connection conn = DriverManager.getConnection( "jdbc:mysql://localhost:3306/myee_2204_03", //url这个写法是mysql服务端安装的是5.5 //"jdbc:mysql://localhost:3306/myee_2204_03?characterEncoding=utf8&useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true" ,//url这个写法:针对5.7的服务器端以及8.0都可以用 "root", "123456" ); // 4)准备sql语句 都是字符串 String sql = "insert into account(name,balance) values('赵又廷',1000)" ; //5)通过数据库的连接获取数据库的执行对象 //Statement createStatement():创建执行对象,将sql语句发送给数据库 Statement stmt = conn.createStatement(); // 6)通过执行对象执行sql语句,将sql语句发送给数据库,(DDL语句/DML语句) //Statemet:执行对象 ---> int executeUpdate(String sql):执行ddl语句,建表,修改表的字段类型/字段名称,dml语句(insert into/update/delete) int count = stmt.executeUpdate(sql); System.out.println("影响了"+count+"行"); // 7)释放资源 stmt.close(); conn.close(); } }
工具类
jdbc:
public class JdbcUtils { private static String driverClass=null; private static String url=null; private static String user=null; private static String password=null; private JdbcUtils(){} static { Properties pro = new Properties(); InputStream inputStream = JdbcUtils.class.getClassLoader().getResourceAsStream("jdbc.properties"); try { pro.load(inputStream); driverClass = pro.getProperty("driverClass"); url = pro.getProperty("url"); user = pro.getProperty("user"); password = pro.getProperty("password"); } catch (IOException e) { e.printStackTrace(); } } public static Connection getConnection(){ Connection con=null; try { Class.forName(driverClass); con = DriverManager.getConnection(url, user, password); } catch (SQLException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } return con; } public static void close(ResultSet rs,Statement stmt, Connection con){ if ( rs!=null ){ try { rs.close(); } catch (SQLException e) { e.printStackTrace(); } } if ( stmt!=null ){ try { stmt.close(); } catch (SQLException e) { e.printStackTrace(); } } if ( con!=null ){ try { con.close(); } catch (SQLException e) { e.printStackTrace(); } } } public static void close(Statement stmt,Connection con){ close(null,stmt,con); } }
druid:提供连接池只是为了提供初始化的连接对象,并不是连接数据库的
要使用数据源DruidDataSource ---需要创建当前类对象---->它的工厂类创建DruidDataSourceFactory:德鲁伊的数据源工厂
public class DruidUtils { private static DataSource ds; private static ThreadLocal<Connection> t1=new ThreadLocal<>(); private DruidUtils(){} static { try { Properties pro = new Properties(); InputStream is = DruidUtils.class.getClassLoader().getResourceAsStream("druid.properties"); pro.load(is); ds = DruidDataSourceFactory.createDataSource(pro); } catch (IOException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } } //获取数据源 public static DataSource getDataSource(){ return ds; } //获取数据库的连接对象 public static Connection getConnection() throws SQLException { //从当前线程中获取连接对象 Connection con = t1.get(); //判断连接对象是否为空 if ( con==null ){ //为空,从连接池中获取连接对象 con = ds.getConnection(); //将从连接池中获取的连接对象绑定到当前线程上 t1.set(con); } return con; } public static void close(ResultSet rs, Statement stmt, Connection con){ if ( rs!=null ){ try { rs.close(); } catch (SQLException e) { e.printStackTrace(); } } if ( stmt!=null ){ try { stmt.close(); } catch (SQLException e) { e.printStackTrace(); } } if ( con!=null ){ try { con.close();//每一个conn都被线程持有,当conn使用完毕,从线程中解绑出来,归还连接池 t1.remove();//从当前线程中解绑 } catch (SQLException e) { e.printStackTrace(); } } } public static void close(Statement stmt,Connection con){ close(null,stmt,con); } }
定义:数据库连接池负责,管理以及释放数据库连接的,允许应用程序可以重复利用某个连接对象,而不是新建一个对象
优点:节省资源,防止资源消耗,是一个容器,大大提供服务器的性能
1)是否能够提高sql的执行效率:
PreparedStatement只需要预编译一条sql语句,多次利用,大大提高了执行效率,而Statement每次需要单独执行某条sql语句,执行效率低
2)是否会造成sql注入:
前者有效防止sql注入,相对后者来说是安全的
后者,针对动态sql拼接,造成sql注入,相对前者来说不安全
3)共同点:两者都带数据库的执行对象,前者继承自后者
1.导入包
导入核心dbutils的jar包----只是提供jdbc的简易封装
导入mysql驱动jar包
管理连接对象,导入druid.jar
完成单元测试,针对功能测试,导入junit的jar(4.13.1)包以及依赖包2.创建执行对象:QueryRunner----底层本质是PreparedStatement
准备sql语句: String sql="";
针对dml语句:添加/删除/修改----通用方法
update(String sql,Object...params): 参数1:sql语句,参数2:给占位符符号赋值的实际参数列表
针对dql语句: 通用方法 query(String sql, ResultSetHandler handler,Object...params);
参数1:执行的查询的sql语句
参数2:针对查询的结果处理的接口ResultSetHandler很多子实现类参数3:如果查询语句带条件,给占位符号赋值
实现:将查询的多条记录封装到List集合中---子实现类:BeanListHandler<T>
将查询的某条记录封装到实体类中---子实现类:BeanHandler<T>
查询总记录数---使用聚合函数,单行单例的数据---子实现类:ScalarHandler<T>
//1)导入commons-dbutils的jar包 //2)创建执行对象 QueryRunner qr = new QueryRunner(DruidJdbcUtils.getDataSource()) ; //3)准备sql语句 String sql = "select * from product" ; //4)执行sql语句查询的多条记录封装到List集 List<Product> list = qr.query(sql,new BeanListHandler<Product>(Product.class)) //5)返回集合list对象