1、DBUtils的简介
Commons DbUtils是Apache组织提供的一个对JDBC进行简单封装的开源工具类库,使用它能够简化JDBC应用程序的开发,同时也不会影响程序的性能。
DBUtils包括3个包:
- org.apache.commons.dbutils
- org.apache.commons.dbutils.handlers
- org.apache.commons.dbutils.wrappers
DBUtils封装了对JDBC的操作,简化了JDBC操作,可以少写代码。
2、目前存在的对JDBC封装的框架或者插件(主流常用、我了解的,百度百科上的)
2.1、DBUtils
Commons DbUtils是Apache组织提供的一个对JDBC进行简单封装的开源工具类库,使用它能够简化JDBC应用程序的开发,同时也不会影响程序的性能。
2.2、Spring-JdbcTemplate
- Spring提供的一个操作数据库的技术JdbcTemplate,是对Jdbc的封装。语法风格非常接近DBUtils。
- JdbcTemplate可以直接操作数据库,加快效率,而且学这个JdbcTemplate也是为声明式事务做准备,毕竟要对数据库中的数据进行操纵!
- JdbcTemplate中并没有提供一级缓存,以及类与类之间的关联关系!就像是spring提供的一个DBUtils。
- Spring对数据库的操作使用JdbcTemplate来封装JDBC,结合Spring的注入特性可以很方便的实现对数据库的访问操作。使用JdbcTemplate可以像JDBC一样来编写数据库的操作代码
2.3、ORM框架之Hibernate
Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,它将POJO与数据库表建立映射关系,是一个全自动的orm框架,hibernate可以自动生成SQL语句,自动执行,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库。 Hibernate可以应用在任何使用JDBC的场合,既可以在Java的客户端程序使用,也可以在Servlet/JSP的Web应用中使用,最具革命意义的是,Hibernate可以在应用EJB的JaveEE架构中取代CMP,完成数据持久化的重任。
Hibernate用反射机制实现持久化对象操作,实现与IDE(Integrated Development Environment)的耦合度。Hibernate使用数据库和配置信息为应用程序提供持久化服务。从配置文件中读取数据库相关参数,将持久化类和数据表对应使用。用Hibernate API对象持久化,利用映像信息将持久化操作翻译为SQL语句进行查询。
图解:
2.4、ORM之MyBatis
MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis 。2013年11月迁移到Github。
iBATIS一词来源于“internet”和“abatis”的组合,是一个基于Java的持久层框架。iBATIS提供的持久层框架包括SQL Maps和Data Access Objects(DAOs)
当前,最新版本是MyBatis 3.5.5 ,其发布时间是2020年6月4日。
基本简介:
MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Ordinary Java Object,普通的 Java对象)映射成数据库中的记录。
2.5、额外了解信息(JPA和OPenJPA)
2.5.1、JPA
JPA是Java Persistence API的简称,中文名Java持久层API,是JDK 5.0注解或XML描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中。
Sun引入新的JPA ORM规范出于两个原因:其一,简化现有Java EE和Java SE应用开发工作;其二,Sun希望整合ORM技术,实现天下归一。
2.5.2、OpenJPA
OpenJPA 是 Apache 组织提供的开源项目,它实现了 EJB 3.0 中的 JPA 标准,为开发者提供功能强大、使用简单的持久化数据管理框架。OpenJPA 封装了和关系型数据库交互的操作,让开发者把注意力集中在编写业务逻辑上。
百度百科之OpenJPA
3、简单使用DBUtils
3.1、使用DBUtils进行CRUD
首先我们先了解其核心的类——QueryRunner,可以进行很多的查询插入或者修改操作。如
- insert
- update
- batch,批量操作
- query
- execute
构造器:
关于传入参数为空参和dataSource的区别:
- 一般情况下,使用CRUD操作使用的是传入参数为dataSource的构造器;
- 如果要添加事务管理的话,则使用的是空参构造器;
3.1.1、增删改操作
/**
* DBUtils的增加数据的操作
* 1、不传入datasource的话,
*/
@Test
public void DBUtils_Add() throws SQLException {
QueryRunner queryRunner = new QueryRunner(JDBCUtils_C3P0.getDatasource());
/*使用可变参数的update*/
queryRunner.update("insert into bank(name,money) values(?,?)","Amy",2000);
}
/**
* DBUtils的删除数据操作
*/
@Test
public void DBUtils_Delete() throws SQLException {
QueryRunner queryRunner = new QueryRunner(JDBCUtils_C3P0.getDatasource());
queryRunner.update("delete from bank where id<10");
}
/**
* DBUtils的修改数据操作
*/
@Test
public void DBUtils_Alter() throws SQLException {
QueryRunner queryRunner = new QueryRunner(JDBCUtils_C3P0.getDatasource());
queryRunner.update("update bank set money=? where id=?",2000,10);
}
批量操作,则使用Batch函数。
3.1.2、查询操作
查询一条数据
/**
* 查询一条数据,需要先将数据进行封装为对象。这里已经封装好的user
*/
@Test
public void DBUtils_Query() throws SQLException {
QueryRunner queryRunner = new QueryRunner(JDBCUtils_C3P0.getDatasource());
/*
* 传入的是一个ResultSetHandler对象,而且泛型参数必须是我们封装的对象。
*/
User user = queryRunner.query("select * from user where username=?", new ResultSetHandler<User>() {
@Override
public User handle(ResultSet resultSet) throws SQLException {
User user1 = new User();
while (resultSet.next()){
user1.setPassword(resultSet.getString("password"));
user1.setUserName(resultSet.getString("username"));
}
return user1;
}
},"dam");
System.out.println(user.toString());
}
查询多条数据
/**
* 查询多条数据,需要先将数据进行封装为对象。这里已经封装好的user。使用一个list或者map来存储
*/
@Test
public void DBUtils_QueryBatch() throws SQLException {
QueryRunner queryRunner = new QueryRunner(JDBCUtils_C3P0.getDatasource());
/*
* 传入的是一个ResultSetHandler对象,而且泛型参数必须是我们封装的对象。
*/
List<User> list = queryRunner.query("select * from user", new ResultSetHandler<List<User>>() {
@Override
public List<User> handle(ResultSet resultSet) throws SQLException {
List<User>list1 = new ArrayList<>();
while (resultSet.next()){
User user = new User();
user.setPassword(resultSet.getString("password"));
user.setUserName(resultSet.getString("username"));
list1.add(user);
}
return list1;
}
});
System.out.println(list.toString());
}
3.2、使用DBUtils的ResultSetHandler
3.2.1、ArrayHandler和ArrayListHandler
/**
* ArrayHandler,将一条记录封装为一个数组_Object[]数组
* ArrayListHandler,将多条记录封装为数组链表,即多个Object[]组成的list
*/
@Test
public void ArrayHandler_Demo() throws SQLException {
QueryRunner queryRunner = new QueryRunner(JDBCUtils_C3P0.getDatasource());
//只查询一条记录。即使查询多条也返回一条
Object[] objects = queryRunner.query("select * from bank where id>15", new ArrayHandler());
System.out.println(Arrays.toString(objects));
}
@Test
public void ArrayListHandler_Demo() throws SQLException {
QueryRunner queryRunner = new QueryRunner(JDBCUtils_C3P0.getDatasource());
List<Object[]> list = queryRunner.query("select * from bank where id>15", new ArrayListHandler());
for (Object[] objects : list) {
System.out.println(Arrays.toString(objects));
}
}
3.2.2、BeanHandler和BeanListHandler
/**
* BeanHandler:将一条记录封装到一个javaBean里面
* BeanListHandler:每条记录时一个javaBean,多条记录封装成一个list。
*/
@Test
public void BeanHandler_Demo() throws SQLException {
QueryRunner queryRunner = new QueryRunner(JDBCUtils_C3P0.getDatasource());
User user = queryRunner.query("select * from user where username=? ", new BeanHandler<User>(User.class), "dam");
System.out.println(user.toString());
}
@Test
public void BeanListHandler_Demo() throws SQLException {
QueryRunner queryRunner = new QueryRunner(JDBCUtils_C3P0.getDatasource());
List<User> list = queryRunner.query("select * from user ", new BeanListHandler<User>(User.class));
for (User u : list) {
System.out.println(u.toString());
}
}
3.2.3、 MapHandler和MapListHandler
/**
* MapHandler:将一条记录封装到一个map
* MapListHandler:将多个记录封装到一个list,每个记录是一个map
*
*/
@Test
public void MapHandler_Demo() throws SQLException {
QueryRunner queryRunner = new QueryRunner(JDBCUtils_C3P0.getDatasource());
// //map的值是Object
Map<String,Object> map = queryRunner.query("select * from user where username=? ", new MapHandler(), "dam");
System.out.println(map);
}
@Test
public void MapListHandler_Demo() throws SQLException {
QueryRunner queryRunner = new QueryRunner(JDBCUtils_C3P0.getDatasource());
//map的值是Object
List<Map<String,Object>> list = queryRunner.query("select * from user ", new MapListHandler());
for (Map u : list) {
System.out.println(u.toString());
}
}
3.2.4、其他的ResultSetHandler
/**
* ColumnListHandler:将数据的某一列封装到list里面
*/
@Test
public void ColumnListHandler_Demo() throws SQLException {
QueryRunner queryRunner = new QueryRunner(JDBCUtils_C3P0.getDatasource());
//map的值是Object
List<String> list = queryRunner.query("select * from user ", new ColumnListHandler<String>("password"));
for (String password : list) {
System.out.println(password.toString());
}
}
/**
* ScalarHandler:看名字旧知道,将单个值进行封装
* 如计算记录条数什么的,count
*/
@Test
public void ScalarHandler_Demo() throws SQLException {
QueryRunner queryRunner = new QueryRunner(JDBCUtils_C3P0.getDatasource());
//map的值是Object
Object count = queryRunner.query("select count(*) from user ", new ScalarHandler<Long>());
System.out.println(count);
}
/**
* KeyedHandler
* 最重要的一个:
* 将查到的一条记录封装为map,多个记录封装为多个map
* 外围建立一个map,其值为上述的map,key则可以指定
*/
@Test
public void KeyedHandler_Demo() throws SQLException {
QueryRunner queryRunner = new QueryRunner(JDBCUtils_C3P0.getDatasource());
//map的值是Object
Map<Object,Map<String,Object>> map = queryRunner.query("select * from user ", new KeyedHandler<>("username"));
for (Object key:map.keySet()
) {
System.out.println(key+" "+map.get(key));
}
}