高校网站建设目的,用wordpress建站,沈阳做网站最好的公司有哪些,深圳家具定制1.数据库连接池什么是数据库连接池简单来说#xff1a;数据库连接池就是提供连接的。。。为什么我们要使用数据库连接池数据库的连接的建立和关闭是非常消耗资源的频繁地打开、关闭连接造成系统性能低下编写连接池编写连接池需实现java.sql.DataSource接口创建批量的Connectio…1.数据库连接池什么是数据库连接池简单来说数据库连接池就是提供连接的。。。为什么我们要使用数据库连接池数据库的连接的建立和关闭是非常消耗资源的频繁地打开、关闭连接造成系统性能低下编写连接池编写连接池需实现java.sql.DataSource接口创建批量的Connection用LinkedList保存【既然是个池当然用集合保存、、LinkedList底层是链表对增删性能较好】实现getConnetion()让getConnection()每次调用都是在LinkedList中取一个Connection返回给用户调用Connection.close()方法Connction返回给LinkedListprivate static LinkedList list new LinkedList();//获取连接只需要一次就够了所以用static代码块static {//读取文件配置InputStream inputStream Demo1.class.getClassLoader().getResourceAsStream(db.properties);Properties properties new Properties();try {properties.load(inputStream);String url properties.getProperty(url);String username properties.getProperty(username);String driver properties.getProperty(driver);String password properties.getProperty(password);//加载驱动Class.forName(driver);//获取多个连接保存在LinkedList集合中for (int i 0; i 10; i) {Connection connection DriverManager.getConnection(url, username, password);list.add(connection);}} catch (IOException e) {e.printStackTrace();} catch (ClassNotFoundException e) {e.printStackTrace();} catch (SQLException e) {e.printStackTrace();}}//重写Connection方法用户获取连接应该从LinkedList中给他Overridepublic Connection getConnection() throws SQLException {System.out.println(list.size());System.out.println(list);//先判断LinkedList是否存在连接return list.size() 0 ? list.removeFirst() : null;}我们已经完成前三步了现在问题来了。我们调用Conncetion.close()方法是把数据库的物理连接关掉而不是返回给LinkedList的解决思路写一个Connection子类覆盖close()方法写一个Connection包装类增强close()方法用动态代理返回一个代理对象出去拦截close()方法的调用对close()增强分析第一个思路Connection是通过数据库驱动加载的保存了数据的信息。写一个子类Connectionnew出对象子类的Connction无法直接继承父类的数据信息也就是说子类的Connection是无法连接数据库的更别谈覆盖close()方法了。分析第二个思路写一个Connection包装类。写一个类实现与被增强对象的相同接口【Connection接口】定义一个变量指向被增强的对象定义构造方法接收被增强对象覆盖想增强的方法对于不想增强的方法直接调用被增强对象的方法这个思路本身是没什么毛病的就是实现接口时方法太多了所以我们也不使用此方法分析第三个思路代码实现Overridepublic Connection getConnection() throws SQLException {if (list.size() 0) {final Connection connection list.removeFirst();//看看池的大小System.out.println(list.size());//返回一个动态代理对象return (Connection) Proxy.newProxyInstance(Demo1.class.getClassLoader(), connection.getClass().getInterfaces(), new InvocationHandler() {Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {//如果不是调用close方法就按照正常的来调用if (!method.getName().equals(close)) {return method.invoke(connection, args);} else {//进到这里来说明调用的是close方法list.add(connection);//再看看池的大小System.out.println(list.size());}return null;}});}return null;}我们上面已经能够简单编写一个线程池了。下面我们来使用一下开源数据库连接池DBCP使用DBCP数据源的步骤导入两个jar包【Commons-dbcp.jar和Commons-pool.jar】读取配置文件获取BasicDataSourceFactory对象创建DataSource对象private static DataSource dataSource null;static {try {//读取配置文件InputStream inputStream Demo3.class.getClassLoader().getResourceAsStream(dbcpconfig.properties);Properties properties new Properties();properties.load(inputStream);//获取工厂对象BasicDataSourceFactory basicDataSourceFactory new BasicDataSourceFactory();dataSource basicDataSourceFactory.createDataSource(properties);} catch (IOException e) {e.printStackTrace();} catch (Exception e) {e.printStackTrace();}}public static Connection getConnection() throws SQLException {return dataSource.getConnection();}//这里释放资源不是把数据库的物理连接释放了是把连接归还给连接池【连接池的Connection内部自己做好了】public static void release(Connection conn, Statement st, ResultSet rs) {if (rs ! null) {try {rs.close();} catch (Exception e) {e.printStackTrace();}rs null;}if (st ! null) {try {st.close();} catch (Exception e) {e.printStackTrace();}}if (conn ! null) {try {conn.close();} catch (Exception e) {e.printStackTrace();}}}C3P0C3P0数据源的性能更胜一筹并且它可以使用XML配置文件配置信息步骤导入开发包【c3p0-0.9.2-pre1.jar】和【mchange-commons-0.2.jar】导入XML配置文件【可以在程序中自己一个一个配C3P0的doc中的Configuration有XML文件的事例】new出ComboPooledDataSource对象private static ComboPooledDataSource comboPooledDataSource null;static {//如果我什么都不指定就是使用XML默认的配置这里我指定的是oracle的comboPooledDataSource new ComboPooledDataSource(oracle);}public static Connection getConnection() throws SQLException {return comboPooledDataSource.getConnection();}Tomcat数据源Tomcat服务器也给我们提供了连接池内部其实就是DBCP步骤在META-INF目录下配置context.xml文件【文件内容可以在tomcat默认页面的 JNDI Resources下Configure Tomcats Resource Factory找到】导入Mysql或oracle开发包到tomcat的lib目录下初始化JNDI-获取JNDI容器-检索以XXX为名字在JNDI容器存放的连接池context.xml文件的配置authContainertypejavax.sql.DataSourceusernamerootpasswordrootdriverClassNamecom.mysql.jdbc.Driverurljdbc:mysql://localhost:3306/zhongfuchengmaxActive8maxIdle4/try {//初始化JNDI容器Context initCtx new InitialContext();//获取到JNDI容器Context envCtx (Context) initCtx.lookup(java:comp/env);//扫描以jdbc/EmployeeDB名字绑定在JNDI容器下的连接池DataSource ds (DataSource)envCtx.lookup(jdbc/EmployeeDB);Connection conn ds.getConnection();System.out.println(conn);}使用dbutils框架dbutils它是对JDBC的简单封装极大简化jdbc编码的工作量DbUtils类提供了关闭连接装载JDBC驱动回滚提交事务等方法的工具类【比较少使用因为我们学了连接池就应该使用连接池连接数据库】QueryRunner类该类简化了SQL查询配合ResultSetHandler使用可以完成大部分的数据库操作重载了许多的查询更新批处理方法。大大减少了代码量ResultSetHandler接口该接口规范了对ResultSet的操作要对结果集进行什么操作传入ResultSetHandler接口的实现类即可。ArrayHandler把结果集中的第一行数据转成对象数组。ArrayListHandler把结果集中的每一行数据都转成一个数组再存放到List中。BeanHandler将结果集中的第一行数据封装到一个对应的JavaBean实例中。BeanListHandler将结果集中的每一行数据都封装到一个对应的JavaBean实例中存放到List里。ColumnListHandler将结果集中某一列的数据存放到List中。KeyedHandler(name)将结果集中的每一行数据都封装到一个Map里再把这些map再存到一个map里其key为指定的key。MapHandler将结果集中的第一行数据封装到一个Map里key是列名value就是对应的值。MapListHandler将结果集中的每一行数据都封装到一个Map里然后再存放到ListScalarHandler 将ResultSet的一个列到一个对象中。使用DbUtils框架对数据库的CRUD/** 使用DbUtils框架对数据库的CRUD* 批处理** */public class Test {org.junit.Testpublic void add() throws SQLException {//创建出QueryRunner对象QueryRunner queryRunner new QueryRunner(JdbcUtils.getDataSource());String sql INSERT INTO student (id,name) VALUES(?,?);//我们发现query()方法有的需要传入Connection对象有的不需要传入//区别你传入Connection对象是需要你来销毁该Connection你不传入由程序帮你把Connection放回到连接池中queryRunner.update(sql, new Object[]{100, zhongfucheng});}org.junit.Testpublic void query()throws SQLException {//创建出QueryRunner对象QueryRunner queryRunner new QueryRunner(JdbcUtils.getDataSource());String sql SELECT * FROM student;List list (List) queryRunner.query(sql, new BeanListHandler(Student.class));System.out.println(list.size());}org.junit.Testpublic void delete() throws SQLException {//创建出QueryRunner对象QueryRunner queryRunner new QueryRunner(JdbcUtils.getDataSource());String sql DELETE FROM student WHERE id100;queryRunner.update(sql);}org.junit.Testpublic void update() throws SQLException {//创建出QueryRunner对象QueryRunner queryRunner new QueryRunner(JdbcUtils.getDataSource());String sql UPDATE student SET name? WHERE id?;queryRunner.update(sql, new Object[]{zhongfuchengaaa, 1});}org.junit.Testpublic void batch() throws SQLException {//创建出QueryRunner对象QueryRunner queryRunner new QueryRunner(JdbcUtils.getDataSource());String sql INSERT INTO student (name,id) VALUES(?,?);Object[][] objects new Object[10][];for (int i 0; i 10; i) {objects[i] new Object[]{aaa, i 300};}queryRunner.batch(sql, objects);}}分页分页技术是非常常见的在搜索引擎下搜索页面不可能把全部数据都显示在一个页面里边。所以我们用到了分页技术。Oracle实现分页/*Oracle分页语法lineSize---每页显示数据行数currentPage----当前所在页*/SELECT *FROM (SELECT 列名,列名,ROWNUM rnFROM 表名WHERE ROWNUM(currentPage*lineSize)) tempWHERE temp.rn(currentPage-1)*lineSize;Oracle分页原理简单解释/*Oracle分页Oracle的分页依赖于ROWNUM这个伪列ROWNUM主要作用就是产生行号。分页原理1子查询查出前n行数据ROWNUM产生前N行的行号2使用子查询产生ROWNUM的行号通过外部的筛选出想要的数据例子我现在规定每页显示5行数据【lineSize5】我要查询第2页的数据【currentPage2】注【对照着语法来看】实现1子查询查出前10条数据【ROWNUM10】2外部筛选出后面5条数据【ROWNUM5】3这样我们就取到了后面5条的数据*/Mysql实现分页/*Mysql分页语法start---偏移量不设置就是从0开始【也就是(currentPage-1)*lineSize】length---长度取多少行数据*/SELECT *FROM 表名LIMIT [START], length;/*例子我现在规定每页显示5行数据我要查询第2页的数据分析1第2页的数据其实就是从第6条数据开始取5条实现1start为5【偏移量从0开始】2length为5*/总结Mysql从(currentPage-1)*lineSize开始取数据取lineSize条数据Oracle先获取currentPagelineSize条数据从(currentPage-1)lineSize开始取数据使用JDBC连接数据库实现分页下面是常见的分页图片配合图片看下我们的需求是什么算出有多少页的数据显示在页面上根据页码从数据库显示相对应的数据。分析算出有多少页数据这是非常简单的【在数据库中查询有多少条记录你每页显示多少条记录就可以算出有多少页数据了】使用Mysql或Oracle的分页语法即可通过上面分析我们会发现需要用到4个变量currentPage--当前页【由用户决定的】totalRecord--总数据数【查询表可知】lineSize--每页显示数据的数量【由我们开发人员决定】pageCount--页数【totalRecord和lineSize决定】//每页显示3条数据int lineSize 3;//总记录数int totalRecord getTotalRecord();//假设用户指定的是第2页int currentPage 2;//一共有多少页int pageCount getPageCount(totalRecord, lineSize);//使用什么数据库进行分页记得要在JdbcUtils中改配置List list getPageData2(currentPage, lineSize);for (Person person : list) {System.out.println(person);}}//使用JDBC连接Mysql数据库实现分页public static List getPageData(int currentPage, int lineSize) throws SQLException {//从哪个位置开始取数据int start (currentPage - 1) * lineSize;QueryRunner queryRunner new QueryRunner(JdbcUtils.getDataSource());String sql SELECT name,address FROM person LIMIT ?,?;List persons (List) queryRunner.query(sql, new BeanListHandler(Person.class), new Object[]{start, lineSize});return persons;}//使用JDBC连接Oracle数据库实现分页public static List getPageData2(int currentPage, int lineSize) throws SQLException {//从哪个位置开始取数据int start (currentPage - 1) * lineSize;//读取前N条数据int end currentPage * lineSize;QueryRunner queryRunner new QueryRunner(JdbcUtils.getDataSource());String sql SELECT name, address FROM ( SELECT name, address , ROWNUM rn FROM person WHERE ROWNUM ? )temp WHERE temp.rn?;List persons (List) queryRunner.query(sql, new BeanListHandler(Person.class), new Object[]{end, start});return persons;}public static int getPageCount(int totalRecord, int lineSize) {//简单算法//return (totalRecord - 1) / lineSize 1;//此算法比较好理解把数据代代进去就知道了。return totalRecord % lineSize 0 ? (totalRecord / lineSize) : (totalRecord / lineSize) 1;}public static int getTotalRecord() throws SQLException {//使用DbUtils框架查询数据库表中有多少条数据QueryRunner queryRunner new QueryRunner(JdbcUtils.getDataSource());String sql SELECT COUNT(*) FROM person;Object o queryRunner.query(sql, new ScalarHandler());String ss o.toString();int s Integer.parseInt(ss);return s;}如果文章有错的地方欢迎指正大家互相交流。习惯在微信看技术文章的同学可以关注微信公众号:Java3y。