springboot和mybatis整合mybatis用BigDecimal查询出现转换异常,之前java项目就没有出现这个问题

16:00 提问
数据库与Java类型转换过程中关于decimal,BigDecimal 和 Double的一个问题。
大家都知道,浮点数 double 在某些过程中数据会失真。
于是我想问两个问题:
1,double是否只在计算或者转换为其它类型时数据失真。
2,数据库中 decimal 若映射成java类型 double,这个过程中数据会不会失真。
其实我面临的问题是这样的,我有一个项目是SSH框架做的,但里面有许多展示价格或者金额的功能,由于我不计算只是展示它们,若转换为BigDecimal显然耗性能,我想直接转换为double,但又担心过程中数据失真,望有大神指点迷津,小弟感激不尽!
按赞数排序
----------------------biu~biu~biu~~~在下问答机器人小D,这是我依靠自己的聪明才智给出的答案,如果不正确,你来咬我啊!
decimal的本质其实是整数,或者说是定点数(相当于把小数点往左移动n位),所以不存在进制转换的问题,也就是你说的“失真”。double存在两个精度误差,一个是本身的精度误差,一个是进制转换的误差,这是难以避免的。
……只是展示而已 不会失真
准确详细的回答,更有利于被提问者采纳,从而获得C币。复制、灌水、广告等回答会被删除,是时候展现真正的技术了!
其他相关推荐Spring Boot集成MyBatis开发Web项目
1、Maven构建Spring Boot
创建Maven Web工程,引入spring-boot-starter-parent依赖
xyz.ibenben
0.0.1-SNAPSHOT
zhongdian Maven Webapp
https://maven.apache.org
org.springframework.boot
spring-boot-starter-parent
1.4.0.BUILD-SNAPSHOT
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-maven-plugin
spring-snapshots
https://repo.spring.io/snapshot
spring-milestones
https://repo.spring.io/milestone
spring-snapshots
https://repo.spring.io/snapshot
spring-milestones
https://repo.spring.io/milestone
使用spring-boot-starter-parent来构建Spring Boot项目是一个很好的方法,但很多项目本身就是依赖其它的父模块的,再或者spring-boot-starter-parent默认提供的那么多配置和功能我们用不到。
我们也可以使用其它的依赖方式来引入Spring Boot。
org.springframework.boot
spring-boot-dependencies
1.4.0.BUILD-SNAPSHOT
2、Spring Boot项目的代码结构
Spring Boot项目与一般的 Web项目的代码结构没有太大的区别或要求,但为了减少配置的数量(无配置),Spring Boot也有一些比较好的建议。
+- example
+- myproject
+- Application.java
+- Customer.java
+- CustomerRepository.java
+- service
+- CustomerService.java
+- CustomerController.java
2.1 不要使用默认的包路径
我们交由Spring管理的类,需要放入一个包下。如下图中的DefaultClass.java是不行的。因为Spring Boot对带注解的类进行扫描的时候,这些默认包路径下的类会出问题。
当然,基于代码规范的要求,一般的程序员都不会这样子构建自己的代码,这里说明是为了真的遇到这种情况出问题时,可以快速地解决问题。
2.2 Spring Boot应用入口
package com.example.
import org.springframework.boot.SpringA
import org.springframework.boot.autoconfigure.EnableAutoC
import org.springframework.context.annotation.ComponentS
import org.springframework.context.annotation.C
@Configuration
@EnableAutoConfiguration
@ComponentScan
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
入口类Application带main方法,我们直接运行main方法就能启动Spring Boot项目了,这样极大程序地方便了我们调试程序和项目。
Application类说明自己是Spring Boot的入口类,那么需要加入@Configuration注解。
@EnableAutoConfiguration习惯放在主方法类Application上,当项目运行时,Spring容器去自动查找带特定注解的类,如:带@Entity、@Service等类。
@ComponentScan如果不带basePackage 属性的话,它会自动扫描以入口类所在的包为父节点下所有子包下的类。这也是Spring Boot会提议我们把Application类放于根包路径下。
如果我们的项目和Spring Boot建议的代码结构一样,Application类放在根包路径下。那么我们可以使用@SpringBootApplication来代替上面三个注解。
package com.example.
import org.springframework.boot.SpringA
import org.springframework.boot.autoconfigure.SpringBootA
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
3、Spring Boot的Web项目实现
3.1 Application类支持Web应用
@SpringBootApplication
public class Application extends SpringBootServletInitializer {
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(Application.class);
public static void main(String[] args) throws Exception {
SpringApplication.run(Application.class, args);
入口类Application继承SpringBootServletInitializer并重写configure方法。运行主方法后,会将我们的web项目打包成war,并默认启动一个端口为8080的tomcat容器来运行我们的Web项目。
3.2 其它服务器软件支持
如果我们不想使用tomcat,而是其它的服务器软件,如Jetty。你需要移除tomcat的依赖,并加入Jetty的依赖。
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-tomcat
org.springframework.boot
spring-boot-starter-jetty
3.3 服务器端口更改
增加application.yml配置文件。
# Server settings
address: 127.0.0.1
这里需要注意,yml配置文件是的值属性前面必须有一个空格,如果没有空格,Spring的解析器会忽略此配置项。
3.4 Controller
Spring支持Spring MVC的Controler的使用方式。
Spring Boot应用中@RestController的Controller带有默认基于Jackson2的对象转JSON功能。如:
@RestController
public class MyController {
@RequestMapping(&/thing&)
public MyThing thing() {
return new MyThing();
3.5 配置编码及JSP支持
# SPRING PROFILES
# HTTP ENCODING
encoding.charset: UTF-8
encoding.enable: true
encoding.force: true
view.prefix: /WEB-INF/jsp/
view.suffix: .jsp
加入以上配置后,还需要引入用于编译jsp的jer包依赖。
org.apache.tomcat.embed
tomcat-embed-jasper
加入JSP支持配置后,下面a方法和b方法者是跳转到/WEB-INF/jsp/regiester.jsp页面。
package xyz.letus.boot.
import java.util.M
import javax.servlet.http.HttpServletR
import org.springframework.stereotype.C
import org.springframework.web.bind.annotation.RequestM
import org.springframework.web.servlet.ModelAndV
@Controller
@RequestMapping(&/page&)
public class PageController {
@RequestMapping(&/a&)
public String b(Map model){
model.put(&msg&, &张三&);
return &regiester&;
@RequestMapping(&/b&)
public ModelAndView b(HttpServletRequest request){
ModelAndView view = new ModelAndView();
view.setViewName(&regiester&);
request.setAttribute(&msg&, &Davie&);
3.6 Spring Boot应用实现热部署
在插件管理中加入springloaded依赖就可以。
org.springframework.boot
spring-boot-maven-plugin
org.springframework
springloaded
当通过 mvn spring-boot:run启动或者 右键application debug 启动java文件时,系统会监视classes文件,当有classes文件被改动时,系统会重新加载类文件,不用重启启动服务。
注:使用application run(非debug模式下),热部署功能会失效。
4、Spring Boot集成MyBatis
4.1 加入基础依赖
org.mybatis
mybatis-spring-boot-starter:
org.mybatis.spring.boot
mybatis-spring-boot-starter
mysql-connector-java
4.2 数据库配置
# SPRING PROFILES
# DATASOURCE
datasource:
driverClass: com.mysql.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/hire?useUnicode=true&characterEncoding=utf-8
username: root
password: test
4.3 引入通用Mapper
tk.mybatis
配置通用Mapper
package xyz.ibenben.zhongdian.common.
import org.springframework.boot.autoconfigure.AutoConfigureA
import org.springframework.context.annotation.B
import org.springframework.context.annotation.C
import tk.mybatis.spring.mapper.MapperScannerC
import java.util.P
@Configuration
public class MyBatisMapperScannerConfig {
public MapperScannerConfigurer mapperScannerConfigurer() {
MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();
mapperScannerConfigurer.setSqlSessionFactoryBeanName(&sqlSessionFactory&);
mapperScannerConfigurer.setBasePackage(&xyz.ibenben.zhongdian.*.dao&);
Properties properties = new Properties();
properties.setProperty(&mappers&, &xyz.ibenben.zhongdian.common.BaseDao&);
properties.setProperty(&notEmpty&, &false&);
properties.setProperty(&IDENTITY&, &MYSQL&);
mapperScannerConfigurer.setProperties(properties);
return mapperScannerC
其实MyBatisMapperScannerConfig 是一个MyBatis扫描Mapper接口扫描。
MapperScannerConfigurer根据指定的创建接口或注解创建映射器。我们这里映射了xyz.ibenben.zhongdian.*.dao包下的接口。
使用MapperScannerConfigurer,没有必要去指定SqlSessionFactory或SqlSessionTemplate,因为MapperScannerConfigurer将会创建MapperFactoryBean,之后自动装配。但是,如果你使用了一个以上的DataSource(因此,也是多个的SqlSessionFactory),那么自动装配可能会失效。这种情况下,你可以使用sqlSessionFactory或sqlSessionTemplate属性来设置正确的工厂/模板。
注意的是网络上有些文章中在MapperScannerConfigurer之前还配置了 MyBatisConfig,因为MapperScannerConfigurer会创建MapperFactoryBean,所以我的项目中没有再配置MyBatisConfig。经使用没有出现任何问题。
4.4 通用Mapper的使用(Dao层)
package xyz.ibenben.zhongdian.
import tk.mybatis.mapper.common.M
import tk.mybatis.mapper.common.MySqlM
public interface BaseDao extends Mapper,MySqlMapper{
package xyz.ibenben.zhongdian.system.
import java.util.L
import org.apache.ibatis.annotations.S
import xyz.ibenben.zhongdian.common.BaseD
import xyz.ibenben.zhongdian.system.entity.U
public interface UserDao extends BaseDao{
@Select(&select * from user where state = #{state}&)
public List selectByState(Integer state);
MyBatis的Dao与其它的ORM框架不一样的是,MyBatis的Dao其实就是Mapper,是一个接口,是通过MapperScannerConfigurer扫描后生成实现的,我们不需要再写Dao接口的实现。
4.5 业务处理及事务(Service层)
package xyz.ibenben.zhongdian.system.
import xyz.ibenben.zhongdian.system.entity.U
public interface UserService {
public void saveUser(User user);
package xyz.ibenben.zhongdian.system.service.
import java.util.L
import org.apache.ibatis.session.RowB
import org.springframework.beans.factory.annotation.A
import org.springframework.stereotype.S
import org.springframework.transaction.annotation.T
import xyz.ibenben.zhongdian.system.dao.TaskD
import xyz.ibenben.zhongdian.system.dao.UserD
import xyz.ibenben.zhongdian.system.entity.T
import xyz.ibenben.zhongdian.system.entity.U
import xyz.ibenben.zhongdian.system.service.UserS
public class UserServiceImpl implements UserService{
@Autowired
private UserDao userD
@Autowired
private TaskDao taskD
@Transactional
public void saveUser(User user){
user = userDao.selectByPrimaryKey(1);
user.setUsername(&5566&);
userDao.updateByPrimaryKey(user);
int i = 10/0;
Task task = new Task();
task.setName(&task 100&);
task.setDescript(&task100 descriot&);
task.setState(1);
taskDao.insert(task);
Task temp = new Task();
task.setState(1);
List list = taskDao.selectByRowBounds(temp, new RowBounds(2, 12));
System.out.println(list.size());
for(Task t : list){
System.out.println(t.getName());
List users = userDao.selectByState(1);
for(User u : users){
System.out.println(u.getUsername());
Spring Boot集成MyBatis后,实现事物管理的方法很简单,只需要在业务方法前面加上@Transactional注解就可以了。
上面方法中用了一个被除数为0的表达式来进行测试事务。为了账号安全,请及时绑定邮箱和手机
点击这里,将文章分享到自己的动态
SpringBoot项目实战(4):集成Mybatis
前三节为开发SpringBoot项目的基础工作,接下来就正式开发web项目开发。本篇文章介绍SpringBoot如何集成Mybatis,往后会慢慢整理,比如整合logback日志记录、Aop、Filter、读取自定义配置文件、如何使用Idea+Maven构建SpringBoot多模块项目以及如何打包部署等等文章。
OK,继续。整合Mybatis前的准备工作:建数据库(mysql)
构建测试数据库(Mysql)
CREATE TABLE `message` (
`ID` int(50) NOT NULL AUTO_INCREMENT COMMENT 'ID',
`NICK_NAME` varchar(50) DEFAULT NULL COMMENT '昵称',
`IP` varchar(50) DEFAULT NULL COMMENT 'IP',
`INSERT_TIME` datetime DEFAULT NULL COMMENT '提交时间',
PRIMARY KEY (`ID`)
) ENGINE=InnoDB AUTO_INCREMENT=51 DEFAULT CHARSET=utf8;
插一下哈: 是否有小伙伴经常遇到过这种情况:主键为自增,我开发期间插入了100条测试数据,开发完成后,直接通过工具导出mysql表,然后导入的生产线上的数据库中,当插入数据时,主键并不是从预想的0开始增加。曾经我就被这整懵逼过,后来下决心仔细看了看建表语句才发现了一些端倪。仔细看上面的建表语句,主键是自增的,并且在语句最后有这么一句:ENGINE=InnoDB AUTO_INCREMENT=51 DEFAULT CHARSET=utf8;这句的意思依次是:使用InnoDB 引擎,自增键的起始序号为51,默认编码为UTF-8。看到了吧?就是这个东西AUTO_INCREMENT。你建表的时候改成0哈,否则你懵逼了别怨我。
另附一个批量插入的存储过程
DELIMITER ;;
CREATE DEFINER=`root`@`localhost` PROCEDURE `autoInsert`()
i INT DEFAULT 0 ; -- 开始
SET autocommit = 0 ; -- 结束
WHILE (i & 1000) DO
REPLACE INTO message (
`NICK_NAME`,
`INSERT_TIME`
'zhangyd',
'127.0.0.1',
SET i = i + 1 ;
SET autocommit = 1 ; COMMIT ;
DELIMITER ;
POM.xml配置
&?xml version="1.0" encoding="UTF-8"?&
&project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"&
&modelVersion&4.0.0&/modelVersion&
&groupId&com.blog&/groupId&
&artifactId&blog&/artifactId&
&version&1.0-SNAPSHOT&/version&
&groupId&org.springframework.boot&/groupId&
&artifactId&spring-boot-starter-parent&/artifactId&
&version&1.4.0.RELEASE&/version&
&relativePath/& &!-- lookup parent from repository --&
&properties&
&project.build.sourceEncoding&UTF-8&/project.build.sourceEncoding&
&project.reporting.outputEncoding&UTF-8&/project.reporting.outputEncoding&
&java.version&1.7&/java.version&
&/properties&
&dependencies&
&!--支持 Web 应用开发,包含 Tomcat 和 spring-mvc。 --&
&dependency&
&groupId&org.springframework.boot&/groupId&
&artifactId&spring-boot-starter-web&/artifactId&
&/dependency&
&dependency&
&groupId&org.springframework.boot&/groupId&
&artifactId&spring-boot-starter-test&/artifactId&
&scope&test&/scope&
&/dependency&
&!--模板引擎--&
&dependency&
&groupId&org.springframework.boot&/groupId&
&artifactId&spring-boot-starter-thymeleaf&/artifactId&
&/dependency&--&
&dependency&
&groupId&org.springframework.boot&/groupId&
&artifactId&spring-boot-starter-freemarker&/artifactId&
&/dependency&
&!--springboot 集成Mybatis所需jar配置 start--&
&!--支持使用 JDBC 访问数据库--&
&dependency&
&groupId&org.springframework.boot&/groupId&
&artifactId&spring-boot-starter-jdbc&/artifactId&
&/dependency&
&!--Mybatis--&
&dependency&
&groupId&org.mybatis&/groupId&
&artifactId&mybatis-spring&/artifactId&
&version&1.2.2&/version&
&/dependency&
&dependency&
&groupId&org.mybatis&/groupId&
&artifactId&mybatis&/artifactId&
&version&3.2.8&/version&
&/dependency&
&!--Mysql / DataSource--&
&dependency&
&groupId&org.apache.tomcat&/groupId&
&artifactId&tomcat-jdbc&/artifactId&
&/dependency&
&dependency&
&groupId&mysql&/groupId&
&artifactId&mysql-connector-java&/artifactId&
&/dependency&
&!--springboot 集成Mybatis所需jar配置 end--&
&!--Json Support--&
&dependency&
&groupId&com.alibaba&/groupId&
&artifactId&fastjson&/artifactId&
&version&1.1.43&/version&
&/dependency&
&!--springboot中修改完文件后自动reload的插件,修改完文件Ctrl + F9 Make一下就可以--&
&dependency&
&groupId&org.springframework&/groupId&
&artifactId&springloaded&/artifactId&
&version&1.2.3.RELEASE&/version&
&/dependency&
&!--springboot中修改完文件后自动reload的插件 end--&
&/dependencies&
&groupId&org.springframework.boot&/groupId&
&artifactId&spring-boot-maven-plugin&/artifactId&
&dependencies&
&dependency&
&groupId&org.springframework&/groupId&
&artifactId&springloaded&/artifactId&
&version&1.2.3.RELEASE&/version&
&/dependency&
&/dependencies&
&/plugins&
&!--配置远程仓库地址--&
&repositories&
&repository&
&id&spring-milestone&/id&
&url&https://repo.spring.io/libs-release&/url&
&/repository&
&/repositories&
&!--配置远程仓库地址--&
&pluginRepositories&
&pluginRepository&
&id&spring-milestone&/id&
&url&https://repo.spring.io/libs-release&/url&
&/pluginRepository&
&/pluginRepositories&
&/project&
application.properties文件配置
spring.datasource.url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
SB程序主函数
package com.
import org.apache.ibatis.session.SqlSessionF
import org.apache.tomcat.jdbc.pool.DataS
import org.mybatis.spring.SqlSessionFactoryB
import org.mybatis.spring.annotation.MapperS
import org.mybatis.spring.mapper.MapperScannerC
import org.springframework.beans.factory.annotation.A
import org.springframework.boot.SpringA
import org.springframework.boot.autoconfigure.EnableAutoC
import org.springframework.boot.autoconfigure.SpringBootA
import org.springframework.boot.context.properties.ConfigurationP
import org.springframework.context.annotation.B
import org.springframework.context.annotation.ComponentS
import org.springframework.core.io.support.PathMatchingResourcePatternR
import org.springframework.jdbc.datasource.DataSourceTransactionM
import org.springframework.transaction.PlatformTransactionM
import org.springframework.transaction.annotation.EnableTransactionM
import org.springframework.web.bind.annotation.RequestM
import org.springframework.web.bind.annotation.RestC
* Created by yadong.zhang on com.blog.application
* User:yadong.zhang
* Time:18:15
* 1).@SpringBootApplication标注启动配置入口,run()方法会创建一个Spring应用上下文(Application Context)。
* SpringBoot通过启动内嵌的Servlet容器(默认tomcat)用来处理Http请求。
* 2).@RestController是特殊的Controller,他的返回值直接作为Http Response的Body部分返回给浏览器
* 3).Spring WebMvc框架会将Servlet容器里收到的Http请求根据路径分发到对应的@Controller下进行处理。
@EnableAutoConfiguration
@SpringBootApplication
@ComponentScan
//指定扫描的mapper接口所在的包
@MapperScan("com.blog.mapper")
//启动注解事务管理
@EnableTransactionManagement
//@RestController
public class Applaction {
private static final String TYPE_ALIASES_PACKAGE = "com.blog.model";
private static final String MAPPER_LOCATION = "classpath:/mybatis/*.xml";
@Autowired
public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
final SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(dataSource);
//mybatis.typeAliasesPackage:指定domain类的基包,即指定其在*Mapper.xml文件中可以使用简名来代替全类名(看后边的UserMapper.xml介绍)
sqlSessionFactoryBean.setTypeAliasesPackage(TYPE_ALIASES_PACKAGE);
mybatis.mapperLocations:指定*Mapper.xml的位置
如果不加会报org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.blog.mapper.MessageMapper.findMessageInfo异常
因为找不到*Mapper.xml,也就无法映射mapper中的接口方法。
sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(MAPPER_LOCATION));
return sqlSessionFactoryBean.getObject();
public static void main(String[] args) {
SpringApplication.run(Applaction.class, args);
注:sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(MAPPER_LOCATION));这一句话一定要有,就是指定程序去哪儿查找Mapper.xml文件
Mapper、Mapper.xml
package com.blog.
import com.blog.model.M
import org.springframework.stereotype.R
import java.util.L
* Created by yadong.zhang on com.blog.mapper
* User:yadong.zhang
* Time:11:19
@Repository
public interface MessageMapper{
public List&Message& findMessageInfo();
&?xml version="1.0" encoding="UTF-8"?&
&!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"&
&mapper namespace="com.blog.mapper.MessageMapper"&
&resultMap id="message_map" type="com.blog.model.Message"&
&id property="id" column="ID" jdbcType="INTEGER"&&/id&
&result property="ip" column="IP" jdbcType="VARCHAR"&&/result&
&result property="insertDate" column="INSERT_TIME" jdbcType="DATE"&&/result&
&result property="nickName" column="NICK_NAME" jdbcType="VARCHAR"&&/result&
&/resultMap&
&select id="findMessageInfo" resultMap="message_map"&
select * from message
Controller(中间还有Service层以及其实现,此处略)
package com.blog.
import com.blog.service.IMessageS
import org.springframework.stereotype.C
import org.springframework.ui.M
import org.springframework.web.bind.annotation.PathV
import org.springframework.web.bind.annotation.RequestM
import org.springframework.web.bind.annotation.ResponseB
import javax.annotation.R
import java.util.D
import java.util.HashM
import java.util.M
* Created by yadong.zhang on com.blog.controller
* User:yadong.zhang
* Time:18:26
@Controller
public class HelloController {
private IMessageService messageS
@RequestMapping("/message")
public String message(Model model){
model.addAttribute("messages", messageService.findMessageInfo());
return "message";
message.ftl
&!DOCTYPE html&
&html lang="en"&
&meta charset="UTF-8"&
&title&Spring Boot 集成Mybatis 测试例子&/title&
&h1&Spring Boot 集成Mybatis 测试例子&/h1&
&em&${.now}&/em&
&#if messages?exists&
&table style="border: 1"&
&#assign index = 1&
&#list messages as message&
&tr &#if index%2 == 0&style="color:"&/#if&&
&td&${message.id}&/td&
&td&${message.ip}&/td&
&td&${message.nickName}&/td&
&td&${message.insertDate?date}&/td&
&#assign index = index + 1&
OK,整合Mybatis到此结束,下节总结Spring Boot 集成分页插件
项目地址:
我可以对一个人无限的好,前提是值得。 ——慕冬雪
本文原创发布于慕课网 ,转载请注明出处,谢谢合作
若觉得本文不错,就分享一下吧!
评论加载中...
看过此文的用户,还看了以下文章
正在加载中
JAVA开发工程师
作者相关文章

我要回帖

更多关于 springboot和mybatis 的文章

 

随机推荐