DBUtils是Java编程中的数据库操作实用工具,小巧简单实用。DBUtils封装了对JDBC的操作,简化了JDBC操作,可以减少60%以上的代码。
DBUtils三个核心功能介绍
第一步:Dept.java:Dept源代码
第二步:新建项目,加入Maven依赖:
<dependency>
<groupId>commons-dbutilsgroupId>
<artifactId>commons-dbutilsartifactId>
<version>1.7version>
dependency>
<dependency>
<groupId>com.alibabagroupId>
<artifactId>druidartifactId>
<version>1.1.17version>
dependency>
第二步:在resources目录下创建mysql.properties,代码如下:
driverClassName=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/test?useSSL=false&serverTimezone=UTC&user=root&password=&useUnicode=true&characterEncoding=UTF8&autoReconnect=true&failOverReadOnly=false
username=root
password=root
filters=stat
initialSize=2
maxActive=300
maxWait=60000
timeBetweenEvictionRunsMillis=60000
minEvictableIdleTimeMillis=300000
validationQuery=SELECT 1
testWhileIdle=true
testOnBorrow=false
testOnReturn=false
poolPreparedStatements=false
maxPoolPreparedStatementPerConnectionSize=200
第三步:创建数据库连接工具类:
public class DBUtil {
private static final ThreadLocal<Connection> threadLocal = new ThreadLocal<>();
private static DataSource dataSource = null;
private DBUtil() {
}
static { //配置文件加载,只执行一次
try (InputStream is = DBUtil.class.getResourceAsStream("/mysql.properties");) {
Properties properties = new Properties();
properties.load(is);
dataSource = DruidDataSourceFactory.createDataSource(properties);
} catch (Exception e1) {
throw new RuntimeException("读取配置文件异常", e1);
}
}
public static Connection getConnection() { //获取连接
Connection conn = null;
try {
conn = threadLocal.get(); //从当前线程获得 conn
if (conn == null || conn.isClosed()) {
conn = dataSource.getConnection();
threadLocal.set(conn);
}
} catch (Exception e) {
throw new RuntimeException("连接数据库异常", e);
}
return conn;
}
public static QueryRunner getQueryRunner() {
return new QueryRunner(dataSource);
}
public static void release(Connection conn) {
try { // 建议采用这种形式来释放资源,因为finally里面的一定会被释放
if (conn != null) {
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
第四步:测试事务
public static void main(String[] args) {
Connection conn = getConnection();
try {
conn.setAutoCommit(false); // 设置事务提交为手动
String sql = "insert into tb_dept (dname,loc) values(?,?)";
QueryRunner queryRunner = getQueryRunner();
queryRunner.update(conn, sql, "aa", "aaaaa");
System.out.println(3 / 0);
queryRunner.update(sql, "bb", "bbbbbbbbbb");
conn.commit();
} catch (SQLException e) {
e.printStackTrace();
try {
conn.rollback();
} catch (SQLException ex) {
ex.printStackTrace();
}
} finally {
release(conn);
}
}
第五步:DeptDaoImpl.java
public class DeptDaoImpl {
private QueryRunner queryRunner = DBUtil.getQueryRunner();
public int insertDept(Dept dept) throws SQLException {
String sql = "insert into tb_dept (deptno, dname, loc) values (?, ?, ?)";
return queryRunner.update(sql, dept.getDeptno(), dept.getDname(), dept.getLoc());
}
public int batchInsertDept(List<Dept> deptList) throws SQLException {
Object[][] params = new Object[deptList.size()][3];
for (int i = 0; i < params.length; i++) {
Dept dept = deptList.get(i);
params[i][0] = dept.getDeptno();
params[i][1] = dept.getDname();
params[i][2] = dept.getLoc();
}
StringBuilder wenHao = new StringBuilder();
for (int i = 0; i < params[0].length; i++) {
wenHao.append("?,");
}
String sql = "insert into tb_dept values(" + wenHao.deleteCharAt(wenHao.length() - 1) + ")";
queryRunner.batch(sql, params);
return 1; // 如果不抛出异常,就返回1,表示删除成功
}
public int deleteDeptByDeptno(Byte deptno) throws SQLException {
String sql = "delete from tb_dept where deptno = ?";
return queryRunner.update(sql, deptno);
}
public int deleteDeptByCondition(Dept dept) throws SQLException {
List<Object> paramValueList = new ArrayList<>();
StringBuffer paramBuf = new StringBuffer("1=1 ");
if (dept.getDeptno() != null) {
paramBuf.append("and deptno= ? ");
paramValueList.add(dept.getDeptno());
}
if (dept.getDname() != null) {
paramBuf.append("and dname= ? ");
paramValueList.add(dept.getDname());
}
if (dept.getLoc() != null) {
paramBuf.append("and loc= ? ");
paramValueList.add(dept.getLoc());
}
String sql = "delete from tb_dept where " + paramBuf.substring(0, paramBuf.length() - 3);
return queryRunner.update(sql, paramValueList.toArray());
}
public int batchDeleteDeptByDeptnos(String deptnos) throws SQLException {
String[] split = deptnos.split(",");
Object[][] params = new Object[1][];
StringBuilder wenHao = new StringBuilder();
for (int i = 0; i < split.length; i++) {
wenHao.append("?,");
}
params[0] = split;
String sql = "delete from tb_dept where deptno in (" + wenHao.deleteCharAt(wenHao.length() - 1) + ")";
queryRunner.batch(sql, params);
return 1; // 如果不抛出异常,就返回1,表示删除成功
}
public int updateDept(Dept dept) throws SQLException {
String sql = "update tb_dept set dname= ? ,loc= ? where deptno = ?";
return queryRunner.update(sql, dept.getDname(), dept.getLoc(), dept.getDeptno());
}
public long selectCount() throws SQLException {
String sql = "select count(*) from tb_dept";
// ScalarHandler:将查询的结果的第一行的某一列放到一个对象中;精确定位到某个值
Long query = queryRunner.query(sql, new ScalarHandler<Long>());
return query.intValue();
}
public long selectCountByCondition(Dept dept) throws SQLException {
List<Object> paramValueList = new ArrayList<>();
StringBuffer paramBuf = new StringBuffer("1=1 ");
if (dept.getDeptno() != null) {
paramBuf.append("and deptno= ? ");
paramValueList.add(dept.getDeptno());
}
if (dept.getDname() != null) {
paramBuf.append("and dname= ? ");
paramValueList.add(dept.getDname());
}
if (dept.getLoc() != null) {
paramBuf.append("and loc= ? ");
paramValueList.add(dept.getLoc());
}
String sql = "select count(*) from tb_dept where " + paramBuf.substring(0, paramBuf.length() - 3);
Long query = queryRunner.query(sql, new ScalarHandler<Long>(), paramValueList.toArray());
return query.intValue();
}
public Dept selectDeptByDeptno(Byte deptno) throws SQLException {
String sql = "select deptno as deptno, dname as dname, loc as loc from tb_dept where deptno = ?";
return queryRunner.query(sql, new BeanHandler<>(Dept.class), deptno);
}
public List<Dept> selectAllDept() throws SQLException {
String sql = "select deptno as deptno, dname as dname, loc as loc from tb_dept";
return queryRunner.query(sql, new BeanListHandler<>(Dept.class));
}
public List<Dept> selectDeptByCondition(Dept dept) throws SQLException {
List<Object> paramValueList = new ArrayList<>();
StringBuffer paramBuf = new StringBuffer("1=1 ");
if (dept.getDeptno() != null) {
paramBuf.append("and deptno= ? ");
paramValueList.add(dept.getDeptno());
}
if (dept.getDname() != null) {
paramBuf.append("and dname= ? ");
paramValueList.add(dept.getDname());
}
if (dept.getLoc() != null) {
paramBuf.append("and loc= ? ");
paramValueList.add(dept.getLoc());
}
String sql = "select deptno as deptno, dname as dname, loc as loc from tb_dept where " + paramBuf.substring(0, paramBuf.length() - 3);
return queryRunner.query(sql, new BeanListHandler<>(Dept.class), paramValueList.toArray());
}
public List<Dept> selectDeptWithPagination(int page, int rows) throws SQLException {
String sql = "select deptno as deptno, dname as dname, loc as loc from tb_dept limit ?, ?";
return queryRunner.query(sql, new BeanListHandler<>(Dept.class), (page - 1) * rows, rows);
}
public List<Dept> selectDeptWithPaginationByCondition(int page, int rows, Dept dept) throws SQLException {
List<Object> paramValueList = new ArrayList<>();
StringBuffer paramBuf = new StringBuffer("1=1 ");
if (dept.getDeptno() != null) {
paramBuf.append("and deptno= ? ");
paramValueList.add(dept.getDeptno());
}
if (dept.getDname() != null) {
paramBuf.append("and dname= ? ");
paramValueList.add(dept.getDname());
}
if (dept.getLoc() != null) {
paramBuf.append("and loc= ? ");
paramValueList.add(dept.getLoc());
}
String sql = "select deptno as deptno, dname as dname, loc as loc from tb_dept where " + paramBuf.substring(0, paramBuf.length() - 3) + " limit ?, ?";
paramValueList.add((page - 1) * rows);
paramValueList.add(rows);
return queryRunner.query(sql, new BeanListHandler<>(Dept.class), paramValueList.toArray());
}
}
SQL 语句从编译和运行的角度可以分为静态 SQL和 动态 SQL,所谓SQL的动态和静态,是指SQL语句在何时被编译和执行。
这两种 SQL 在使用方式、运行机制和性能表现等方面各有特点 :
静态sql的存取路径是在运行前就确定好的,而动态sql的存取路径是在运行时动态生成的。
注意:在SQL中如果某些参数没有确定,如"select * from t1 where c1>? and c2",这种语句是静态SQL,不是动态SQL,虽然个别参数的值不知道,但整个SQL的结构已经确定,数据库是可以将它编译的,在执行阶段只需将个别参数的值补充进来即可。