使用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里,然后再存放到List
- ScalarHandler 将ResultSet的一个列到一个对象中。
使用DbUtils框架对数据库的CRUD
/* * 使用DbUtils框架对数据库的CRUD * 批处理 * * */ public class Test { @org.junit.Test public 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.Test public 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.Test public void delete() throws SQLException { //创建出QueryRunner对象 QueryRunner queryRunner = new QueryRunner(JdbcUtils.getDataSource()); String sql = "DELETE FROM student WHERE id='100'"; queryRunner.update(sql); } @org.junit.Test public 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.Test public 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 rn FROM 表名 WHERE ROWNUM<=(currentPage*lineSize)) temp WHERE temp.rn>(currentPage-1)*lineSize;
Oracle分页原理简单解释:
/* Oracle分页: Oracle的分页依赖于ROWNUM这个伪列,ROWNUM主要作用就是产生行号。 分页原理: 1:子查询查出前n行数据,ROWNUM产生前N行的行号 2:使用子查询产生ROWNUM的行号,通过外部的筛选出想要的数据 例子: 我现在规定每页显示5行数据【lineSize=5】,我要查询第2页的数据【currentPage=2】 注:【对照着语法来看】 实现: 1:子查询查出前10条数据【ROWNUM<=10】 2:外部筛选出后面5条数据【ROWNUM>5】 3:这样我们就取到了后面5条的数据 */
Mysql实现分页
/* Mysql分页语法: @start---偏移量,不设置就是从0开始【也就是(currentPage-1)*lineSize】 @length---长度,取多少行数据 */ SELECT * FROM 表名 LIMIT [START], length; /* 例子: 我现在规定每页显示5行数据,我要查询第2页的数据 分析: 1:第2页的数据其实就是从第6条数据开始,取5条 实现: 1:start为5【偏移量从0开始】 2:length为5 */
总结:
- Mysql从(currentPage-1)*lineSize开始取数据,取lineSize条数据
- Oracle先获取currentPage*lineSize条数据,从(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<Person> list = getPageData2(currentPage, lineSize); for (Person person : list) { System.out.println(person); } } //使用JDBC连接Mysql数据库实现分页 public static List<Person> 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<Person> persons = (List<Person>) queryRunner.query(sql, new BeanListHandler(Person.class), new Object[]{start, lineSize}); return persons; } //使用JDBC连接Oracle数据库实现分页 public static List<Person> 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<Person> persons = (List<Person>) 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; }