当前位置: 首页 > news >正文

珠海品牌机械网站建设php网站怎么搭建环境配置

珠海品牌机械网站建设,php网站怎么搭建环境配置,网站的横幅怎么做,网站建设用途课程目录 一、JDBC概述 二、JDBC基本操作 三、使用PreparedStatement处理CRUD 四、数据库连接池 五、Apache的DBUtils 六、Dao类 一、JDBC概述 1. 为什么需要JDBC 没有JDBC时#xff1a; 有了JDBC后#xff1a; 2. JDBC概述 JDBC#xff1a;Java Database Conn…课程目录 一、JDBC概述 二、JDBC基本操作 三、使用PreparedStatement处理CRUD 四、数据库连接池 五、Apache的DBUtils 六、Dao类 一、JDBC概述 1. 为什么需要JDBC 没有JDBC时 有了JDBC后 2. JDBC概述 JDBCJava Database Connectivity它是代表一组独立于任何数据库管理系统Database Management System, DBMS的API声明在java.sql与javax.sql包中是SUN(现在Oracle)提供的一组接口规范。由各个数据库厂商来提供实现类这些实现类的集合构成了数据库驱动jar。 即JDBC技术包含两个部分 1java.sql包和javax.sql包中的API 因为为了项目代码的可移植性可维护性SUN公司从最初就制定了Java程序连接各种数据库的统一接口规范。这样的话不管是连接哪一种DBMS软件Java代码可以保持一致性。 2各个数据库厂商提供的jar 因为各个数据库厂商的DBMS软件各有不同那么内部如何通过sql实现增、删、改、查等管理数据只有这个数据库厂商自己更清楚因此把接口规范的实现交给各个数据库厂商自己实现。 3. JDBC使用步骤 3.1. 新建MySQL数据库和表完成建表 create database jdbc_test;use jdbc_test;create table user(id int primary key auto_increment,username varchar(20),password varchar(20),nickname varchar(20) );INSERT INTO USER VALUES(null,zs,123456,老张); INSERT INTO USER VALUES(null,ls,123456,老李); INSERT INTO USER VALUES(null,wangwu,123,老王);3.2. 注册驱动 1将DBMS数据库管理软件的驱动jar拷贝到项目的lib目录中       根据不同的数据库版本进行驱动的选择 例如mysql-connector-java-5.1.36-bin.jar 2把驱动jar添加到项目的build path中即将jar包放入在src目录下新建的lib目录下然后右键lib目录选择add as library 3将驱动类加载到内存中 Class.forName(com.mysql.jdbc.Driver);如果是8版本则将驱动改为 Class.forName(com.mysql.cj.jdbc.Driver);3.3. 获取Connection连接对象 1Connection conn DriverManager.getConnection(url,username,password); 2mysql的urljdbc:mysql://localhost:3306/数据库名?参数名参数值 String url jdbc:mysql://localhost:3306/数据库名参数名参数值useSSLfalseserverTimezoneUTCallowPublicKeyRetrievaltrue; 如果用户使用了 sha256_password 认证密码在传输过程中必须使用 TLS 协议保护但是如果 RSA 公钥不可用可以使用服务器提供的公钥可以在连接中通过 ServerRSAPublicKeyFile 指定服务器的 RSA 公钥或者AllowPublicKeyRetrievalTrue参数以允许客户端从服务器获取公钥但是需要注意的是 AllowPublicKeyRetrievalTrue可能会导致恶意的代理通过中间人攻击(MITM)获取到明文密码所以默认是关闭的必须显式开启 修改Timezone使MySQL的timezone和idea的一致后可以不写serverTimezoneUTCallowPublicKeyRetrievaltrue3jdbc:mysql://localhost:3306/testdb?useUnicodetruecharacterEncodingutf8如果JDBC程序与服务器端的字符集不一致会导致乱码那么可以通过参数指定服务器端的字符集) String url jdbc:mysql://localhost:3306/jdbc_testuseUnicodetruecharacterEncodingutf8; String user root; String password root; //获得连接 Connection connection DriverManager.getConnection(url, user, password);3.4. 执行sql并处理结果 编写sql String sql select *from user;创建Statement对象 Statement statement connection.createStatement();使用Statement对象执行sql 1增删改调用executeUpate方法 2查询调用executeQuery方法 ResultSet resultSet statement.executeQuery(sql);处理结果 1增删改返回的是整数值,表示受到影响的数据条数 2查询返回ResultSet结果 boolean next()判断是否还有下一行getString(字段名或序号),getInt(字段名或序号),getObject(字段名或序号) while (resultSet.next()) {//获取每一列的数据System.out.println(resultSet.getObject(1));System.out.println(resultSet.getObject(2));System.out.println(resultSet.getObject(3));System.out.println(resultSet.getObject(4)); }3.5. 释放资源 原则是后创建的资源先关闭我们会依次关闭ResultSet、Statement、Connection对象 //关闭资源 if(resultSet ! null){resultSet.close();} if(statement ! null){statement .close(); } if(connection ! null){connection.close(); }3.6. JDBC使用小结 二、JDBC基本操作 1. 执行添加的SQL语句 IDEA/数据库连接 Test public void insert() throws Exception {//增加 insert into user values(null,tq,77777,田七);//1.注册驱动// Class.forName(com.mysql.jdbc.Driver);Class.forName(com.mysql.cj.jdbc.Driver);//2.获得连接String url jdbc:mysql://localhost:3306/jdbc_test?useUnicodetruecharacterEncodingutf8;String user root;String password root;Connection connection DriverManager.getConnection(url, user, password);//3.创建执行sql语句对象Statement statement connection.createStatement();//4.执行sql语句String sql insert into user values(null,tq,77777,田七);int rows statement.executeUpdate(sql);System.out.println(几行收影响 rows);//5.释放资源if (statement ! null) {statement.close();}if (connection ! null) {connection.close();}}2. 执行删除的SQL语句 Test //删除id为5的用户 public void delete() throws Exception {//1.注册驱动// Class.forName(com.mysql.jdbc.Driver);Class.forName(com.mysql.cj.jdbc.Driver);//2.获得连接String url jdbc:mysql://localhost:3306/jdbc_test?useUnicodetruecharacterEncodingutf8;String user root;String password root;Connection connection DriverManager.getConnection(url, user, password);//3.创建执行sql语句对象Statement statement connection.createStatement();//4.执行sql语句String sql delete from user where id 5;statement.executeUpdate(sql);//5.释放资源if (statement ! null) {statement.close();}if (connection ! null) {connection.close();} }3. 执行修改的SQL语句 Test //更新 把id为4的用户的密码改成88888888 public void update() throws Exception {//1.注册驱动//Class.forName(com.mysql.jdbc.Driver);Class.forName(com.mysql.cj.jdbc.Driver);//2.获得连接String url jdbc:mysql://localhost:3306/jdbc_test?useUnicodetruecharacterEncodingutf8;String user root;String password root;Connection connection DriverManager.getConnection(url, user, password);//3.创建执行sql语句对象Statement statement connection.createStatement();//4.执行sql语句String sql update user set password 88888888 where id 4;statement.executeUpdate(sql);//5.释放资源if (statement ! null) {statement.close();}if (connection ! null) {connection.close();}}4. 执行查询单行数据的SQL语句 要求: 将查询到的结果封装到User对象中 User类 public class User {private int id;private String username;private String password;private String nickname;//提供get/set方法 AltInsertpublic User() {}public User(int id, String username, String password, String nickname) {this.id id;this.username username;this.password password;this.nickname nickname;}public int getId() {return id;}public void setId(int id) {this.id id;}public String getUsername() {return username;}public void setUsername(String username) {this.username username;}public String getPassword() {return password;}public void setPassword(String password) {this.password password;}public String getNickname() {return nickname;}public void setNickname(String nickname) {this.nickname nickname;}Overridepublic String toString() {return User{ id id , username username \ , password password \ , nickname nickname \ };} }JDBC 代码 Test public void query() throws Exception {//查询id为1的用户//1.注册驱动//Class.forName(com.mysql.jdbc.Driver);Class.forName(com.mysql.cj.jdbc.Driver);//2.获得连接String url jdbc:mysql://localhost:3306/jdbc_test?useUnicodetruecharacterEncodingutf8;String username root;String password root;Connection connection DriverManager.getConnection(url, username, password);//3.创建执行sql语句对象Statement statement connection.createStatement();//4.执行sql语句String sql select * from user where id 1;ResultSet resultSet statement.executeQuery(sql);User user null;while (resultSet.next()) {//每遍历一次,就是一条数据.就是一个User对象(有数据才有user)user new User(resultSet.getInt(id),resultSet.getString(username),resultSet.getString(password),resultSet.getString(nickname));}//获得用户名System.out.println(用户名user.getUsername());//5.释放资源if (resultSet ! null) {resultSet.close();}if (statement ! null) {statement.close();}if (connection ! null) {connection.close();} }5. 执行查询多行数据的SQL语句 要求: 将查询到的多行数据封装到ListUser中 Test //查询所有用户 public void queryAll() throws Exception {//1.注册驱动//DriverManager.registerDriver(new Driver());//类全限定名(带包名), 加载Driver类, 静态代码块就会执行, 驱动就注册了//Class.forName(com.mysql.jdbc.Driver);Class.forName(com.mysql.cj.jdbc.Driver);//2.获得连接(连接数据库)//连接数据库路径String urljdbc:mysql://localhost:3306/jdbc_test?useUnicodetruecharacterEncodingutf8;String username root;String password root;Connection connection DriverManager.getConnection(url, username, password);//3.创建执行sql语句的对象Statement statement connection.createStatement();//4.执行sql语句, 处理结果String sql select * from user;ResultSet resultSet statement.executeQuery(sql);ListUser list new ArrayListUser();while (resultSet.next()){//每遍历一次就是一条数据, 就封装成一个User对象. 把封装的每一个User添加到list集合里面User user new User(resultSet.getInt(id),resultSet.getString(username),resultSet.getString(password),resultSet.getString(nickname));list.add(user);}//获得第二个用户的用户名System.out.println(list.get(1));//5.释放资源(先创建的后关闭)if(resultSet ! null){resultSet.close();}if(statement ! null){statement.close();}if(connection ! null){connection.close();}}三、使用PreparedStatement处理CRUD 1. Statement存在的问题 每次执行一个SQL语句都需要先编译 String sql1 insert into user values(null,tq,77777,田七); String sql2 insert into user values(null,zl,666666,赵六); String sql3 insert into user values(null,zs,333333,张三); //如果使用Statement执行上述SQL语句需要编译三次sql注入漏洞 String username hahahahha or 11 String sql SELECT * FROM user where username username ; //结果会把所有数据都查询出来 Statement st conn.createStatement(); ResultSet rs st.executeQuery(sql);2. PreparedStatement解决问题 预编译: PreparedStatement会先对参数化的SQL语句进行预编译执行SQL语句的时候不会再进行编译 String sql insert into user values(null,?,?,?); //预编译 PreparedStatement pstm connection.prepareStatement(sql); //后续设置参数、执行添加多少条数据都不会再重新编译防止SQL注入: PreparedStatement在进行预编译的时候就已经确定好了SQL语句的格式不会再因为后续的操作改变SQL语句的格式 String username hahahahha or 11 String sql SELECT * FROM user where username?; //即使输入张三 or 1 1也没问题 PreparedStatement pst conn.prepareStatement(sql);//中间加入设置的值 pst.setObject(1, username);ResultSet rs pst.executeQuery();3. 获取自增长键值 3.1. 获取自增长键值的应用场景 主要使用在一些复杂的业务中在添加完主键表的一条数据之后要获取到这条数据的主键值然后将该值添加进外键表的外键字段。 3.2. 获取自增长键值的步骤 步骤一在预编译的时候指定要返回自增长的key PreparedStatement pst conn.prepareStatement(sql,Statement.RETURN_GENERATED_KEYS);步骤二在执行完添加数据的SQL语句之后通过PreparedStatement的对象调用getGeneratedKeys()方法来获取自增长键值遍历结果集 ResultSet rs pst.getGeneratedKeys();步骤三遍历获取自增长的键值 if(rs.next()){Object key rs.getObject(1);System.out.println(自增的key值did key); }示例代码 数据库id时auto_increment,自增长 public class TestAutoIncrement {public static void main(String[] args) throws Exception{//1、注册驱动Class.forName(com.mysql.jdbc.Driver);//2、获取连接Connection conn DriverManager.getConnection(jdbc:mysql://localhost:3306/jdbc_test?useUnicodetruecharacterEncodingutf8, root, 123456);//3、执行sqlString sql insert into user values(null,?,?,?);/** 这里在创建PreparedStatement对象时传入第二个参数的作用就是告知服务器端* 当执行完sql后把自增的key值返回来。返回给了pst,通过pst.getGeneratedKeys();* 可以获取自增的key值*/PreparedStatement pst conn.prepareStatement(sql,Statement.RETURN_GENERATED_KEYS);//设置的值pst.setObject(1, aobama);pst.setObject(2, 12345678);pst.setObject(3, 圣枪游侠);//执行sqlint len pst.executeUpdate();//返回影响的记录数if(len0){//从pst中获取到服务器端返回的键值ResultSet rs pst.getGeneratedKeys();//因为这里的key值可能多个因为insert语句可以同时添加多行所以用ResultSet封装//这里因为只添加一条所以用if判断if(rs.next()){Object key rs.getObject(1);System.out.println(自增的key值did key);}}//4、关闭pst.close();conn.close();} }4. 批处理 4.1. 批处理优势和应用场景 批处理相比较单独一条条执行SQL语句来说其效率高很多。批处理一般会使用在批量添加多条数据和批量修改多条数据。 4.2. 批处理的具体操作步骤 步骤一在url中要加一个参数 rewriteBatchedStatementstrue,那么此时url就变成了 jdbc:mysql://localhost:3306/jdbc_test?useUnicodetruecharacterEncodingutf8rewriteBatchedStatementstrue步骤二在完成所有参数设置之后调用PreparedStatement的addBatch()方法添加到批处理中 步骤三最后执行PreparedStatement的executeBatch()方法执行批处理语句 public class TestBatch {public static void main(String[] args) throws Exception{long start System.currentTimeMillis();//例如在部门表t_department中添加1000条模拟数据//1、注册驱动Class.forName(com.mysql.jdbc.Driver);//2、获取连接Connection conn DriverManager.getConnection(jdbc:mysql://localhost:3306/jdbc_test?useUnicodetruecharacterEncodingutf8rewriteBatchedStatementstrue, root, 123456);//3、执行sqlsql语句不能用value只能用valuesString sql insert into user values(null,?,?,?);PreparedStatement pst conn.prepareStatement(sql);//设置的值for (int i 1; i 1000; i) {pst.setObject(1, aobamai);pst.setObject(2, 000000i);pst.setObject(3, 圣枪游侠i);pst.addBatch();//添加到批处理一组操作中攒一块处理}pst.executeBatch();//4、关闭pst.close();conn.close();long end System.currentTimeMillis();System.out.println(耗时 (end - start));//耗时821} }5. 事务 5.1. 事务操作的步骤 1执行逻辑单元之前先开启事务 2逻辑单元执行完毕没有出现异常则提交事务 3逻辑单元执行过程中出现异常则回滚事务 5.2. 事务相关API Connection中与事务有关的方法说明setAutoCommit(boolean autoCommit)参数是true或false 如果设置为false表示关闭自动提交相当于开启事务; 类似sql里面的 start transaction;void commit()提交事务; 类似sql里面的 commit;void rollback()回滚事务; 类似sql里面的 rollback; 5.3. 使用JDBC的事务完成转账案例 事务中最经典的案例就是转账操作如果A向B转了100块在A转出了后系统出错了B没有收到那么A就平白无故少了100块钱了这是非常严重的错误。这时候就需要引入事务对转账操作进行处理。 事务的四大特性如下 原子性一个事务是一个不可分割的工作单位事务中包括的所有操作要么都做要么都不做。 一致性事务必须是使数据库从一个一致性状态变到另一个一致性状态。一致性与原子性是密切相关的。 隔离性一个事务的执行不能被其他事务干扰。即一个事务内部的操作及使用的数据对并发的其他事务是隔离的并发执行的各个事务之间不能互相干扰。 持久性持久性也称永久性指一个事务一旦提交它对数据库中数据的改变就应该是永久性的。接下来的其他操作或故障不应该对其有任何影响。 所以转账是一个事务也就具备了以上的四个特性具备的原子性可以保证A转出100块后B要收到100块这个转账操作才算完成如果B收不到100块那么就将A转出的100块退回给他之所以能够退回是因为这些操作都记录到了数据库中的日志表中当转账失败事务执行回退时也就是撤销该转账操作时日志表中的该条操作就执行一个逆操作增—删加—减等。引入的事务操作主要就是保证原子性其他特性数据库帮我们完成了下面看下具体的代码逻辑。 5.3.1. 准备数据 use jdbc_test; create table account(id int primary key auto_increment,name varchar(20),money double );insert into account values (null,zs,1000); insert into account values (null,ls,1000); insert into account values (null,ww,1000);5.3.2. 代码实现 package com.atguigu.jdbc;import org.junit.Test;import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement;public class TestTransaction {Testpublic void testTransfer() throws Exception {//测试转账//1. 注册驱动Class.forName(com.mysql.jdbc.Driver);//2. 获得连接Connection conn DriverManager.getConnection(jdbc:mysql:///day04?characterEncodingutf8,root,123456);//3. 预编译sql语句String sql update account set moneymoney? where name?;//改变用户的金额PreparedStatement preparedStatement conn.prepareStatement(sql);//开启事务conn.setAutoCommit(false);try {//zs扣款500preparedStatement.setObject(1,-500);preparedStatement.setObject(2,zs);//执行zs扣款的sql语句preparedStatement.executeUpdate();//ls收款500preparedStatement.setObject(1,500);preparedStatement.setObject(2,ls);preparedStatement.executeUpdate();//提交事务conn.commit();} catch (Exception e) {e.printStackTrace();conn.rollback();}finally {//还原connection的AutoCommit为trueconn.setAutoCommit(true);}//关闭资源preparedStatement.close();conn.close();} }保证原子性的关键操作就是使用一个try…catch…将转账操作进行包裹当抛出异常时执行回退逻辑也就是撤销之前事务中执行的全部操作流程。如果没有异常则提交事务将SQL操作所产生的影响进行持久化操作。 四、数据库连接池 1. 连接池概述 什么是连接池 连接池是connection对象的缓冲区它里面会存放一些connection当我们Java程序需要使用connection的时候如果连接池中有则直接从连接池获取不需要去新创建connection了。连接池让Java程序能够复用连接、管理连接。 为什么要使用连接池 1因为每次创建和销毁连接都会带来较大的系统开销 2每次创建和销毁连接都要消耗大概0.05~1s的时间。 3可以防止大量用户并发访问数据库服务器。 2. 连接池的原理 连接池维护着两个容器空闲池和活动池空闲池用于存放未使用的连接活动池用于存放正在使用的连接活动池中的连接使用完之后要归还回空闲池当Java程序需要连接时先判断空闲池中是否有连接如果空闲池中有连接则取出一个连接放置到活动池供Java程序使用Java程序需要连接时如果空闲池中没有连接了则先判断活动池的连接数是否已经达到了最大连接数如果未达到最大连接数则会新创建一个连接放置到活动池供Java程序使用如果空闲池中没有连接了活动池中的连接也已经达到了最大连接数则不能新创建连接了那么此时会判断是否等待超时如果没有等待超时则需要等待活动池中的连接归还回空闲池如果等待超时了则可以采取多种处理方式例如:直接抛出超时异常或者将活动池中使用最久的连接移除掉归还回空闲池以供Java程序使用 3. 连接池的实现 3.1. DataSource接口 JDBC 的数据库连接池使用 javax.sql.DataSource 来表示DataSource 只是一个接口通常被称为数据源所有的Java数据库连接池都需要实现该接口。该接口通常由服务器(Weblogic, WebSphere, Tomcat)提供实现也有一些开源组织提供实现。 3.2. 常见的数据库连接池 DBCP 是Apache提供的数据库连接池速度相对c3p0较快但因自身存在BUGHibernate3已不再提供支持C3P0 是一个开源组织提供的一个数据库连接池速度相对较慢稳定性还可以Proxool 是sourceforge下的一个开源项目数据库连接池有监控连接池状态的功能稳定性较c3p0差一点HikariCP 俗称光连接池,是目前速度最快的连接池Druid 是阿里提供的数据库连接池据说是集DBCP 、C3P0 、Proxool 优点于一身的数据库连接池 3.3. Druid连接池的使用 第一步加入jar包druid-1.1.10.jar 第二步创建druid连接池的配置文件druid.properties文件放置到类路径下 类路径是什么 方式一可以在项目下通过new选择resource bundle就会创建一个resource文件夹这就是类路径了 方式二先创建resource目录然后右键选择Mark directory as — Resources Boot druid.properties内容如下具体的配置作用讲解后面3.4会提到driverClassNamecom.mysql.cj.jdbc.Driver urljdbc:mysql://localhost:3306/test? usernameroot password123456 initialSize5 maxActive10 maxWait1000第三步在项目创建一个工具包utils在里面新建JDBCUtil工具类 package com.drimwai.utils;import com.alibaba.druid.pool.DruidDataSourceFactory;import javax.sql.DataSource; import java.io.InputStream; import java.sql.Connection; import java.sql.SQLException; import java.util.Properties;public class JDBCUtil {private static DataSource dataSource;static {try {//读取配置文件创建连接池//1. 创建一个Properties对象让其去读取druid.properties文件Properties properties new Properties();//2. 使用相对路径来将druid.properties配置文件转成字节输入流,我们可以使用类加载器来读取类路径下文件//JDBCUtil.class.getClassLoader()表示获取ClassLoader对象InputStream inputStream JDBCUtil.class.getClassLoader().getResourceAsStream(druid.properties);//使用properties对象加载流properties.load(inputStream);//使用DruidDataSourceFactory创建连接池dataSource DruidDataSourceFactory.createDataSource(properties);} catch (Exception e) {e.printStackTrace();}}/*** 获取连接池* return*/public static DataSource getDataSource(){return dataSource;}/*** 获取连接* return*/public static Connection getConnection(){try {return dataSource.getConnection();} catch (SQLException e) {e.printStackTrace();throw new RuntimeException(e.getMessage());}}/*** 归还连接的方法* param connection*/public static void releaseConnection(Connection connection){try {connection.close();} catch (SQLException e) {e.printStackTrace();throw new RuntimeException(e.getMessage());}} }3.4. Druid.Properties连接池的配置参数列表 配置缺省说明name配置这个属性的意义在于如果存在多个数据源监控的时候可以通过名字来区分开来。 如果没有配置将会生成一个名字格式是”DataSource-” System.identityHashCode(this)url连接数据库的url不同数据库不一样。例如mysql : jdbc:mysql://10.20.153.104:3306/druid2 oracle : jdbc:oracle:thin:10.20.149.85:1521:ocnautousername连接数据库的用户名password连接数据库的密码。如果你不希望密码直接写在配置文件中可以使用ConfigFilter。详细看这里https://github.com/alibaba/druid/wiki/使用ConfigFilterdriverClassName根据url自动识别 这一项可配可不配如果不配置druid会根据url自动识别dbType然后选择相应的driverClassName(建议配置下)initialSize0初始化时建立物理连接的个数。初始化发生在显示调用init方法或者第一次getConnection时maxActive8最大连接池数量maxIdle8已经不再使用配置了也没效果minIdle最小连接池数量maxWait获取连接时最大等待时间单位毫秒。配置了maxWait之后缺省启用公平锁并发效率会有所下降如果需要可以通过配置useUnfairLock属性为true使用非公平锁。poolPreparedStatementsfalse是否缓存preparedStatement也就是PSCache。PSCache对支持游标的数据库性能提升巨大比如说oracle。在mysql下建议关闭。maxOpenPreparedStatements-1要启用PSCache必须配置大于0当大于0时poolPreparedStatements自动触发修改为true。在Druid中不会存在Oracle下PSCache占用内存过多的问题可以把这个数值配置大一些比如说100validationQuery用来检测连接是否有效的sql要求是一个查询语句。如果validationQuery为nulltestOnBorrow、testOnReturn、testWhileIdle都不会其作用。testOnBorrowtrue申请连接时执行validationQuery检测连接是否有效做了这个配置会降低性能。testOnReturnfalse归还连接时执行validationQuery检测连接是否有效做了这个配置会降低性能testWhileIdlefalse建议配置为true不影响性能并且保证安全性。申请连接的时候检测如果空闲时间大于timeBetweenEvictionRunsMillis执行validationQuery检测连接是否有效。timeBetweenEvictionRunsMillis有两个含义 1)Destroy线程会检测连接的间隔时间2)testWhileIdle的判断依据详细看testWhileIdle属性的说明numTestsPerEvictionRun不再使用一个DruidDataSource只支持一个EvictionRunminEvictableIdleTimeMillisconnectionInitSqls物理连接初始化的时候执行的sqlexceptionSorter根据dbType自动识别 当数据库抛出一些不可恢复的异常时抛弃连接filters属性类型是字符串通过别名的方式配置扩展插件常用的插件有 监控统计用的filter:stat日志用的filter:log4j防御sql注入的filter:wallproxyFilters类型是List如果同时配置了filters和proxyFilters是组合关系并非替换关系 3.6. 连接池使用总结 拷贝加入druid的jar包拷贝druid的配置文件到类路径,并修改拷贝JDBCUtil工具类在需要连接的地方编写Connection conn JDBCUtil.getConnection();此时拿到的连接就是从连接池拿的连接使用完毕之后调用JDBCUtil.releaseConnection(conn);归还连接在需要使用连接池的地方调用JDBCUtil.getDataSource();获取连接池 五、Apache的DBUtils使用 1. DBUtils的概述 本节的DBUtil是由Apache所提供的jar包实现了对数据库增删改查操作而第六节的BaseDao是由我们基于DBUtil自定义的用于实现通用的数据库增删改查操作。上面的JDBCUtils只是实现了数据库连接池的创建和连接的获取、释放等操作并没有实现对数据的操作而DBUtils和BaseDao就是实现对数据的操作的但他们没有实现连接的获取以及连接池的创建等操作所以要使用apache的DBUtil或者BaseDao都要先实现上面的Druid连接池的使用。 Apache的DBUtils的使用 第一步先根据上面的Druid连接池的使用创建JDBCUtils工具包,主要是要用到JDBCUtils里创建的Connection连接 第二步导如以下包 第三步创建一个类,用以下方法便可实现Apache的DBUtils的使用的增删改操作下面有查功能这里不赘述。 //1. 创建QueryRunner,并且传入连接池对象 QueryRunner queryRunner new QueryRunner(JDBCUtil.getDataSource()); //2. 执行SQL语句 String sql delete from user where id?; queryRunner.update(sql,1);commons-dbutils是 Apache 组织提供的一个开源 JDBC工具框架类库它是对JDBC的简单封装学习成本极低并且使用dbutils能极大简化jdbc编码的工作量同时也不会影响程序的性能。 其中QueryRunner类封装了SQL的执行是线程安全的。 1可以实现增、删、改、查、批处理、 2考虑了事务处理需要共用Connection。 3该类最主要的就是简单化了SQL查询它与ResultSetHandler组合在一起使用可以完成大部分的数据库操作能够大大减少编码量。 2. DBUtils执行增删改的SQL语句 2.1 API介绍 QueryRunner() ,创建QueryRunner对象用于执行SQL语句QueryRunner的update(Connection conn, String sql, Object… params)方法用于执行增删改的SQL语句 2.2 代码实现 Test public void testAddUser() throws SQLException {//目标:往user表中添加一行数据//1. 创建QueryRunner需先导入上面提到的jar包QueryRunner queryRunner new QueryRunner();//2. 执行SQL语句String sql insert into user values (null,?,?,?);Connection conn JDBCUtil.getConnection();int i queryRunner.update(conn, sql, aolafu, 123456, 狂战士);//关闭连接JDBCUtil.releaseConnection(conn); }Test public void testAddUserAnother() throws SQLException {//1. 创建QueryRunner,并且传入连接池对象QueryRunner queryRunner new QueryRunner(JDBCUtil.getDataSource());//2. 执行SQL语句String sql insert into user values (null,?,?,?);queryRunner.update(sql,neisesi,123456,狗头);//这种方式的缺点是用不了事务 }Test public void testDeleteUser() throws SQLException {//1. 创建QueryRunner,并且传入连接池对象QueryRunner queryRunner new QueryRunner(JDBCUtil.getDataSource());//2. 执行SQL语句String sql delete from user where id?;queryRunner.update(sql,1); }3. DBUtils执行批处理 3.1 API介绍 public int[] batch(Connection conn,String sql,Object[][] params)throws SQLException 支持批处理INSERT, UPDATE, or DELETE语句public T T insertBatch(Connection conn,String sql,ResultSetHandlerT rsh,Object[][] params) throws SQLException只支持INSERT语句 3.2 代码实现 Test public void testBatch() throws SQLException {//使用DBUtils执行批处理//二维数组:数组内的元素还是数组{{1,2},{3,4},{5,6}}//批量往user表中添加五千条数据//1. 创建QueryRunner对象QueryRunner queryRunner new QueryRunner(JDBCUtil.getDataSource());//2. 编写SQL语句String sql insert into user (username,password,nickname) values (?,?,?);//3. 设置二维数组参数:第一维表示我们需要处理多少条数据第二维表示sql语句有多少个参数Object[][] params new Object[5000][3];for(int i0;i5000;i){//params[i]表示插入的第i条数据//params[i][1]表示插入的第i条数据的第一个问号处的参数params[i][0] usernamei;params[i][1] passwordi;params[i][2] nicknamei;}//执行批处理queryRunner.batch(sql,params); }4. 使用QueryRunner类实现查询 4.1. API介绍 query(String sql, ResultSetHandler rsh, Object… params) 执行查询 selectResultSetHandler结果集处理类 Handler类型说明ArrayHandler将结果集中的第一条记录封装到一个Object[]数组中数组中的每一个元素就是这条记录中的每一个字段的值ArrayListHandler将结果集中的每一条记录都封装到一个Object[]数组中将这些数组在封装到List集合中。BeanHandler将结果集中第一条记录封装到一个指定的javaBean中。BeanListHandler将结果集中每一条记录封装到指定的javaBean中将这些javaBean在封装到List集合中ColumnListHandler将结果集中指定的列的字段值封装到一个List集合中KeyedHandler将结果集中每一条记录封装到MapString,Object,在将这个map集合做为另一个Map的value,另一个Map集合的key是指定的字段的值。MapHandler将结果集中第一条记录封装到了MapString,Object集合中key就是字段名称value就是字段值MapListHandler将结果集中每一条记录封装到了MapString,Object集合中key就是字段名称value就是字段值在将这些Map封装到List集合中。ScalarHandler它是用于单个数据。例如select count(*) from 表。 4.2. 代码实现 Test public void testFindById() throws SQLException {//使用DBUtils执行查询的SQL语句将查询到的一条数据封装到User对象中//1. 创建QueryRunner,并且传入连接池对象QueryRunner queryRunner new QueryRunner(JDBCUtil.getDataSource());//2. 执行SQL语句String sql select * from user where id?;User user queryRunner.query(sql, new BeanHandler(User.class), 2);System.out.println(user); }Test public void testFindAll() throws SQLException {//查询多条数据封装到ListJavaBean//1. 创建QueryRunner,并且传入连接池对象QueryRunner queryRunner new QueryRunner(JDBCUtil.getDataSource());//2. 执行SQL语句String sql select * from user;ListUser userList queryRunner.query(sql, new BeanListHandler(User.class));System.out.println(userList); }Test public void testFindCount() throws SQLException {//查询数据条数//1. 创建QueryRunner,并且传入连接池对象QueryRunner queryRunner new QueryRunner(JDBCUtil.getDataSource());//2. 执行SQL语句String sql select count(id) from user;long count queryRunner.query(sql, new ScalarHandler());System.out.println(count); }六、自定义通用BaseDao Dao是data access Object的缩写中文翻译为数据访问对象我们会将操作持久层的代码编写到对应的Dao类中。 BaseDao类所有Dao类的父类需要先实现上面的Druid连接池的使用注意BaseDao是基于DBUtils自定义实现的所以BaseDao是需要依赖DBUtils的所以也需要引入对应的apache的jar包。 BaseDao实现了通用的数据库增删改查操作。 import com.atguigu.bookstore.utils.JDBCUtil; import org.apache.commons.dbutils.QueryRunner; import org.apache.commons.dbutils.handlers.BeanHandler; import org.apache.commons.dbutils.handlers.BeanListHandler;import java.sql.Connection; import java.sql.SQLException; import java.util.List;public class BaseDaoT {private QueryRunner queryRunner new QueryRunner();/*** 批处理方法* param sql* param paramArr* return*/public int[] batchUpdate(String sql,Object[][] paramArr){Connection conn JDBCUtil.getConnection();try {return queryRunner.batch(conn,sql,paramArr);} catch (SQLException e) {e.printStackTrace();throw new RuntimeException(e.getMessage());} finally {JDBCUtil.releaseConnection(conn);}}/*** 执行增删改的sql语句* param sql* param params* return*/public int update(String sql,Object... params){Connection conn JDBCUtil.getConnection();//执行增删改的sql语句返回受到影响的行数try {return queryRunner.update(conn,sql,params);} catch (SQLException e) {e.printStackTrace();throw new RuntimeException(e.getMessage());} finally {JDBCUtil.releaseConnection(conn);}}/*** 执行查询一行数据的sql语句将结果集封装到JavaBean对象中* param clazz* param sql* param params* return*/public T getBean(ClassT clazz,String sql,Object... params){Connection conn JDBCUtil.getConnection();try {return queryRunner.query(conn,sql,new BeanHandler(clazz),params);} catch (SQLException e) {e.printStackTrace();throw new RuntimeException(e.getMessage());} finally {JDBCUtil.releaseConnection(conn);}}/*** 执行查询多行数据的sql语句并且将结果集封装到ListJavaBean* param clazz* param sql* param params* return*/public ListT getBeanList(ClassT clazz, String sql, Object... params){Connection conn JDBCUtil.getConnection();try {return queryRunner.query(conn,sql,new BeanListHandler(clazz),params);} catch (SQLException e) {e.printStackTrace();throw new RuntimeException(e.getMessage());} finally {JDBCUtil.releaseConnection(conn);}} }测试代码如下: Test public void testUpdate() {BaseDaoObject baseDao new BaseDao();String sql insert into t_user(user_name,user_pwd) values(?,?);int count baseDao.update(sql, 罗志祥, 789456);System.out.println(count count); }Test public void testGetBean() {//这里的User表示数据类型,之前已经创建了一个User类了用来存放用户的 id ,username ,password, nicknameBaseDaoUser baseDao new BaseDao();// user_id userId// user_name userName// user_pwd userPwdString sql select user_id userId,user_name userName,user_pwd userPwd from t_user where user_id?;User user baseDao.getBean(User.class, sql, 2);System.out.println(user user); }Test public void testGetBeanList() {//这里的User表示数据类型,之前已经创建了一个User类了用来存放用户的 id ,username ,password, nicknameBaseDaoUser baseDao new BaseDao();String sql select user_id userId,user_name userName,user_pwd userPwd from t_user;ListUser userList baseDao.getBeanList(User.class, sql);for (User user : userList) {System.out.println(user user);} }
http://www.huolong8.cn/news/29443/

相关文章:

  • 工商银行门户网站是什么意思wordpress分类页打不开
  • 紫金网站制作东莞常平房价2023最新楼盘消息
  • 网站文章编辑器代码甘肃交通工程建设监理公司网站
  • 一个人建设小型网站口碑营销话题
  • 为什么网站建设要将access数据库文件变成asa网站百度地图
  • 顺德网站设计石材做网站
  • 编辑网站教程网络推广技术培训
  • 延庆区加工网站建设推广低代码开发平台公司
  • 建设银行陕西分行网站城市建设理论研究网站
  • 网站的推广方式包括成都互联网公司数量排名
  • html5模板网站福州医社保增减员在什么网站做
  • 企业如何做网站建站商品推广软文800字
  • 做网站的公司济南赛博科技市场泵网站建设
  • 网站建设对比分析网站建设测评报告
  • 淘宝网发布网站建设深圳专业网站开发
  • 网站seo在线诊断wordpress 自动上传插件
  • 广东省东莞市建设培训中心网站深圳网站建设开发需要多少钱
  • 网站建设项目结构分析多推网怎么推广
  • 怎样查别人网站的外链友情链接网站
  • 学校联系我们网站制作做网站找哪家好思南
  • 租网站服务器价格小程序需要租服务器吗
  • 响应式网站建设原则中装建设股票
  • 做3d打印网站wordpress文章设置到导航栏
  • 建设模板网站网站审核备案
  • 做外汇看什么网站网站建设培训 上海
  • 顺德 网站设计如何自定义wordpress登录
  • 如何看网站是用什么程序做的无锡本地做网站
  • 长沙可以做网站的公司wordpress如何做到手机端
  • 基于html做电商网站论文全球装饰公司排名
  • 鞍山网站制作云端无锡网站建设818gx