JDBC(二)
1、数据库事务
事务:一组逻辑操作单元,使数据从一种状态变换到另一种状态。
事务操作:当一个事务中执行多个操作时,要么所有操作都提交(commit),要么所有操作都回滚(rollback)到最初状态。
2、考虑事务后的代码实现
private TransferMoneyDao transferMoneyDao = new TransferMoneyDao(); /** * 模拟name2给name1转账 * @param name1 * @param name2 * @param money */ public void testTransfer(String name1, String name2, Double money){ Connection connection = null; try { // 1.获取数据库连接 connection = JdbcUtils.getConnection(); // 2.取消数据的自动提交 connection.setAutoCommit(false); // 3.调用Dao层的转账方法 transferMoneyDao.income("zhangsan",money); transferMoneyDao.outgo("lisi",money); // 4.如果转账正常,手动提交事务 connection.commit(); } catch (Exception e) { e.printStackTrace(); try { // 5.如果转账出现异常,回滚数据 connection.rollback(); } catch (SQLException ex) { ex.printStackTrace(); } } finally { // 6.关闭资源 JdbcUtils.closeResource(connection,null); } }
3、数据库连接池
普通jdbc连接数据库,每一次连接使用完就会断开,当频繁的进行数据库连接时会很占用系统资源。
使用数据库连接池,相当于在一个“缓存池”中放入一定量的连接,需要时从中取出,用完后放回,实现了复用。
连接池技术有C3P0等,这里用的是阿里的Druid
druid的数据库连接池配置:
#驱动加载 driverClassName=com.mysql.jdbc.Driver #注册驱动 url=jdbc:mysql://127.0.0.1:3306/db_name?characterEncoding=utf-8 #连接数据库的用户名 username=root #连接数据库的密码 password=1234 #属性类型的字符串,通过别名的方式配置扩展插件, 监控统计用的stat 日志用log4j 防御sql注入:wall filters=stat #初始化时池中建立的物理连接个数。 initialSize=2 #最大的可活跃的连接池数量 maxActive=300 #获取连接时最大等待时间,单位毫秒,超过连接就会失效。配置了maxWait之后,缺省启用公平锁,并发效率会有所下降, 如果需要可以通过配置useUnfairLock属性为true使用非公平锁。 maxWait=60000 #连接回收器的运行周期时间,时间到了清理池中空闲的连接,testWhileIdle根据这个判断 timeBetweenEvictionRunsMillis=60000 minEvictableIdleTimeMillis=300000 #用来检测连接是否有效的sql,要求是一个查询语句。 validationQuery=SELECT 1 #建议配置为true,不影响性能,并且保证安全性。 申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis, 执行validationQuery检测连接是否有效。 testWhileIdle=true #申请连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。设置为false testOnBorrow=false #归还连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能,设置为flase testOnReturn=false #是否缓存preparedStatement,也就是PSCache。 poolPreparedStatements=false #池中能够缓冲的preparedStatements语句数量 maxPoolPreparedStatementPerConnectionSize=200
优化一下工具类JDBCUtilsByDruid
public class JDBCUtilsByDruid { // 1、导入druid.jar包 // 2、在druid.properties文件中编写好配置 private static DataSource dataSource; // 3、在静态代码块中完成静态数据源的初始化 static { // 创建properties对象,读取配置 Properties properties = new Properties(); try { properties.load(new FileInputStream("src\\druid.properties")); // 创建Druid连接池 dataSource = DruidDataSourceFactory.createDataSource(properties); } catch (Exception e) { e.printStackTrace(); } } /** * 从数据库连接池中获取连接 * @return * @throws SQLException */ public static Connection getConnection() throws SQLException { return dataSource.getConnection(); } /** * close是把connection连接对象放回到连接池中 * @param connection * @param statement * @param resultSet */ public static void closeResource(Connection connection, Statement statement, ResultSet resultSet) { try { if (resultSet != null) { resultSet.close(); } } catch (SQLException e) { e.printStackTrace(); } try { if (statement != null) { statement.close(); } } catch (SQLException e) { e.printStackTrace(); } try { if (connection != null) { connection.close(); } } catch (SQLException e) { e.printStackTrace(); } }}
4、Apache的DbUtils
解决ResultSet结果集不能复用的问题
原理:引入javabean,也叫PoJo或者Domian,一个javabean对象,对应一条表记录,再将这个javabean对象存入到ArrayList集合中。
导入commons-dbutils的jar包
public void testQueryRunner() throws SQLException { Connection connection = JDBCUtilsByDruid.getConnection(); QueryRunner queryRunner = new QueryRunner(); /* 通用查询方法,query(),但比增删改多了结果集处理器ResultSetHandler query方法就是执行一个sql语句,后面的1就是给?赋值,有几个问号就写几个 ResultSetHandler接口,用于处理ResultSet,介绍几种常用的实现类: - 返回单条记录 BeanHandler将结果集中的第一行数据封装到对应的JavaBean实例中 MapHandler将结果集中的第一行数据封装到一个Map中,key是列名,value是对应的值 - 返回多条记录 BeanListHandler将结果集中的每一行数据封装到对应的JavaBean实例中,再存入List MapListHandler将结果集中的每一行数据封装到一个Map中,再存入List - 返回单行单列记录-->Object ScalarHandler一般用于查询特殊值 */ // String sql = "select * from a where id >= ?"; // AjavaBean ajavaBean = queryRunner.query(connection,sql,new BeanHandler<>(AjavaBean.class),1); // List<AjavaBean> list = queryRunner.query(connection,sql,new BeanListHandler<>(AjavaBean.class),1); /* 通用增删改方法,update(),返回的是受影响的行数 */ String sql = "insert a set name = ? where id = ?"; int affectedRow = queryRunner.update(connection,sql,"zhangsan",18); // 关闭资源 JDBCUtilsByDruid.closeResource(connection,null,null); }
本文作者:Ritchie里其
本文链接:https://www.cnblogs.com/wang-zeyu/p/16884325.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 25岁的心里话
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现