实战java中资金计算的要点-BigDecimal

本文详细介绍了在Java中处理财务计算的最佳实践,强调避免使用float和double类型,并推荐使用java.math.BigDecimal来确保高精度的计算结果。同时提供了数据库设计、Hibernate属性定义及常见运算方法的实现。

首先明确的是:Java中的浮点数类型的floatdouble是不能够用来进行资金的运算。

 

在《Effective Java》中也提到这个原则:floatdouble只能用来做科学计算或者是工程计算,在商业计算中我们要用java.math.BigDecimal

 

怎样在实际中应用呢,其实也不难。简单提几点:

1.  数据库表的设计

资金字段的数据类型一般定义为number类型,长度可根据需要而定。

2. hibernatepo的属性的数据类型的定义

       有两种选择,建议用double,float会有精度丢失的问题。hibernate映射工具自动生成的.hbm.xml中,默认也是double类型。

3.程序中资金的运算

       必须使用java.math.BigDecimal,而不能使用float或者double。建议写个工具类,提供些常用的方法供加减等运算使用。

 

有篇不错的文章,大家可以参考:http://www.j-kanban.com/bbs/redirect.php?fid=59&tid=6876&goto=nextoldset

 

实例参考:

 

public class BaseCalculate {
	
	private static final int DEF_DIV_SCALE = 10;

	/**
	 * 提供精确的加法运算 
	 * @param v1 被加数
	 * @param v2 加数
	 * @return 两个参数的和
	 */
	public static double add(double v1, double v2) {
		BigDecimal b1 = new BigDecimal(Double.toString(v1));
		BigDecimal b2 = new BigDecimal(Double.toString(v2));
		return b1.add(b2).doubleValue();
	}
	
	/**
	 * 提供精确的减法运算 
	 * @param v1 被减数
	 * @param v2 减数
	 * @return 两个参数的差
	 */
	public static double substract(double v1, double v2) {
		BigDecimal b1 = new BigDecimal(Double.toString(v1));
		BigDecimal b2 = new BigDecimal(Double.toString(v2));
		return b1.subtract(b2).doubleValue();
	}
	
	/**
	 * 提供精确的乘法运算
	 * @param v1 被乘数
	 * @param v2 乘数
	 * @return 两个参数的积
	 */
	public static double multiply(double v1, double v2) {
		BigDecimal b1 = new BigDecimal(Double.toString(v1));
		BigDecimal b2 = new BigDecimal(Double.toString(v2));
		return b1.multiply(b2).doubleValue();
	}

	/**
	 * 提供(相对)精确的除法运算,当发生除不尽的情况时,
	 * 精确到小数点以后10位,以后的数字四舍五入.
	 * @param v1 被除数
	 * @param v2 除数
	 * @return 两个参数的商
	 */
	public static double divide(double v1, double v2) {
		return divide(v1, v2, DEF_DIV_SCALE);
	}

	/**
	 * 提供(相对)精确的除法运算.
	 * 当发生除不尽的情况时,由scale参数指 定精度,以后的数字四舍五入.
	 * 
	 * @param v1 被除数
	 * @param v2 除数
	 * @param scale 表示需要精确到小数点以后几位
	 * @return 两个参数的商
	 */
	public static double divide(double v1, double v2, int scale) {
		if (scale < 0) {
			throw new IllegalArgumentException("The scale must be a positive integer or zero");
		}
		
		BigDecimal b1 = new BigDecimal(Double.toString(v1));
		BigDecimal b2 = new BigDecimal(Double.toString(v2));
		return b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
	}

	/**
	 * 提供精确的小数位四舍五入处理
	 * @param v 需要四舍五入的数字
	 * @param scale 小数点后保留几位
	 * @return 四舍五入后的结果
	 */
	public static double round(double v, int scale) {
		if (scale < 0) {
			throw new IllegalArgumentException("The scale must be a positive integer or zero");
		}
		
		BigDecimal b = new BigDecimal(Double.toString(v));
		BigDecimal one = new BigDecimal("1");
		return b.divide(one, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
	}

	
	 public static void main(String[] args) {
		 //直接使用浮点数进行计算,得到的结果是有问题的
		 System.out.println(0.01 + 0.05);
		 
		 //使用了BigDecimal类进行计算后,可以做到精确计算
		 System.out.println(BaseCalculate.add(0.0000000000005, 0.00000001));
	}
}

 

 

<think>好的,我现在需要帮助用户了解如何使用Java开发和部署银行系统相关的小程序。首先,用户的问题涉及Java开发、银行系统、小程序以及部署实战教程。我需要结合之前的引用内容来构建一个结构清晰的回答,同时生成相关问题。 首先,引用中提到微信小程序的前后端交互使用JSON报文,而Spring Boot的@RestController适合处理这种请求。这可能与银行系统小程序的后端开发相关。此外,部署方面引用了宝塔面板部署Java项目的步骤,用户可能需要类似的实战指导。 接下来,我需要考虑银行系统的特殊性,比如安全性、事务管理、合规性等。这些方面可能在常规的小程序开发中不太突出,但在银行系统中至关重要。需要确保回答中涵盖这些要点,例如使用Spring Security进行安全控制,数据库事务管理,以及合规性设计。 然后,分步骤讲解开发流程。可能包括技术选型(Spring Boot、MyBatis、MySQL)、模块设计(用户认证、账户管理、交易处理)、安全措施(HTTPS、加密算法、风控系统)、前后端交互(RESTful API设计)、测试与部署(宝塔面板、Nginx配置、压力测试)等。 在部署部分,引用[3]提到了使用宝塔部署Spring Boot项目,绑定域名和端口配置。需要详细说明这些步骤,并强调银行系统在部署时的注意事项,比如SSL证书、防火墙设置、数据备份等。 最后,生成的相关问题需要围绕银行系统的安全性、技术实现细节、合规性以及部署优化等方面,帮助用户深入理解可能遇到的挑战和解决方案。</think># Java开发与部署银行系统小程序的实战指南 ## 一、技术架构设计 1. **核心框架选择** - 后端:采用Spring Boot 2.7 + Spring Security 5.8实现安全认证[^2] - 数据库:MySQL 8.0 + Redis 7.0集群 - 接口规范:RESTful API设计,响应报文格式: ```json { "code": 200, "msg": "操作成功", "data": {} } ``` 2. **安全架构设计** ```java @Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/api/v1/transfer").hasAuthority('TRANSFER') .antMatchers("/api/v1/balance").authenticated() .and() .apply(new JwtConfigurer(jwtTokenProvider)); } } ``` ## 二、核心功能开发 1. **账户管理模块** ```java @RestController @RequestMapping("/api/account") public class AccountController { @PostMapping("/transfer") @Transactional public Response transfer(@Valid @RequestBody TransferDTO dto) { // 实现双写一致性校验 accountService.transferFunds(dto); return Response.success(); } } ``` 2. **交易流水记录** ```sql CREATE TABLE transaction_record ( id BIGINT PRIMARY KEY, from_account VARCHAR(32) NOT NULL, to_account VARCHAR(32) NOT NULL, amount DECIMAL(18,2) NOT NULL, create_time DATETIME DEFAULT CURRENT_TIMESTAMP, INDEX idx_account (from_account, to_account) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; ``` ## 三、安全防护方案 1. **五层防护体系** - 传输层:强制HTTPS + TLS 1.3 - 数据层:AES-256加密敏感字段 - 接口层:JWT令牌 + 防重放攻击 - 业务层:交易密码二次验证 - 系统层:硬件加密机存储密钥 2. **风控规则示例** ```java public class RiskControlRule { private static final BigDecimal DAILY_LIMIT = new BigDecimal("50000"); public boolean checkDailyLimit(String account) { BigDecimal todaySum = transactionMapper.sumTodayAmount(account); return todaySum.compareTo(DAILY_LIMIT) < 0; } } ``` ## 四、部署实施流程 1. **宝塔面板部署步骤** ```bash # 1. 安装Java项目管理器 bt 7 # 2. 新建Spring Boot项目 项目路径:/www/bank-app JDK版本:Amazon Corretto 17 端口:8443(HTTPS专用) # 3. 配置Nginx反向代理 location / { proxy_pass https://127.0.0.1:8443; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } ``` 2. **生产环境配置建议 - 使用硬件安全模块(HSM)管理密钥 - 部署两地三中心架构 - 配置每日自动备份策略 ```bash # 数据库备份脚本示例 mysqldump -u root -p bank_db | gzip > /backup/$(date +%Y%m%d).sql.gz ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值