zoukankan      html  css  js  c++  java
  • spring 整合 mybatis 中数据源的几种配置方式

      因为spring 整合mybatis的过程中, 有好几种整合方式,尤其是数据源那块,经常看到不一样的配置方式,总感觉有点乱,所以今天有空总结下。

      

      一、采用org.mybatis.spring.mapper.MapperScannerConfigurer

      其实逆向工程也是这种方式

      1、数据源配配置文件

     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <beans xmlns="http://www.springframework.org/schema/beans"
     3     xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
     4     xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
     5     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     6     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
     7     http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
     8     http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
     9     http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd">
    10 
    11     <!-- 加载配置文件 -->
    12     <context:property-placeholder location="classpath:resource/*.properties" />
    13 
    14     <!-- 数据库连接池 -->
    15     <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
    16         destroy-method="close">
    17         <property name="driverClassName" value="${jdbc.driver}" />
    18         <property name="url" value="${jdbc.url}" />
    19         <property name="username" value="${jdbc.username}" />
    20         <property name="password" value="${jdbc.password}" />
    21         <property name="maxActive" value="10" />
    22         <property name="minIdle" value="5" />
    23     </bean>
    24     <!-- sqlsessionFactory -->
    25     <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    26         <property name="configLocation" value="classpath:mybatis/SqlMapConfig.xml"></property>
    27         <property name="dataSource" ref="dataSource"></property>
    28     </bean>
    29 
    30     <!-- 加载mapper代理对象 -->
    31     <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
    32         <property name="basePackage" value="com.jdd.mapper"></property>
    33         <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>
    34     </bean>
    35 
    36 </beans>

      2、DAO文件

     1 package com.jdd.mapper;
     2 
     3 import com.jdd.pojo.Employee;
     4 import java.util.List;
     5 
     6 public interface EmployeeMapper {
     7 
     8     public Employee getEmployeeById(int id);
     9 
    10     public List<Employee> findAllEmployees();
    11 
    12 }

      3、Mapper.xml 文件

     1 <?xml version="1.0" encoding="UTF-8" ?>
     2 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
     3 "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
     4 
     5 <mapper namespace="com.jdd.mapper.EmployeeMapper">
     6 
     7     <select id="getEmployeeById" parameterType="int" resultType="com.jdd.pojo.Employee">
     8         <![CDATA[
     9             select * from employee where id = #{id};
    10         ]]>
    11     </select>
    12     
    13     <select id="findAllEmployees" resultType="com.jdd.pojo.Employee">
    14         <![CDATA[
    15             select * from employee where status='1';
    16         ]]>
    17     </select>
    18 
    19     
    20 </mapper>

      这样在service类里就可以直接注入dao接口了

     1 package com.jdd.service.impl;
     2 
     3 import com.jdd.mapper.EmployeeMapper;
     4 import com.jdd.pojo.Employee;
     5 import com.jdd.service.EmployeeService;
     6 import org.springframework.beans.factory.annotation.Autowired;
     7 import org.springframework.stereotype.Service;
     8 import java.util.List;
     9 
    10 @Service("employeeService")
    11 public class EmployeeServiceImpl implements EmployeeService{
    12 
    13     @Autowired
    14     private EmployeeMapper employeeMapper;
    15 
    16     @Override
    17     public Employee getEmployeeById(int id) {
    18         return employeeMapper.getEmployeeById(id);
    19     }
    20 
    21     @Override
    22     public List<Employee> findAllEmployees() {
    23         return employeeMapper.findAllEmployees();
    24     }
    25 
    26 }

      

      二、 采用抽象类org.mybatis.spring.support.SqlSessionDaoSupport, 给它注入 sqlSessionFactory的方式

      1、数据源配置文件

     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <beans xmlns="http://www.springframework.org/schema/beans"
     3     xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
     4     xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
     5     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     6     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
     7     http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
     8     http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
     9     http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd">
    10 
    11     <!-- 加载配置文件 -->
    12     <context:property-placeholder location="classpath:resource/*.properties" />
    13 
    14     <!-- 数据库连接池 -->
    15     <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
    16         destroy-method="close">
    17         <property name="driverClassName" value="${jdbc.driver}" />
    18         <property name="url" value="${jdbc.url}" />
    19         <property name="username" value="${jdbc.username}" />
    20         <property name="password" value="${jdbc.password}" />
    21         <property name="maxActive" value="10" />
    22         <property name="minIdle" value="5" />
    23     </bean>
    24 
    25     
    26     <!-- sqlsessionFactory -->
    27     <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    28         <property name="configLocation" value="classpath:mybatis/SqlMapConfig.xml"></property>
    29         <property name="dataSource" ref="dataSource"></property>
    30         <property name="mapperLocations" value="classpath:com/jdd/mapper/*.xml"></property>
    31     </bean>
    32     
    34 </beans>

      2、baseDao类

     1 package com.hd.dao;
     2 
     3 import org.apache.ibatis.session.SqlSessionFactory;
     4 import org.mybatis.spring.support.SqlSessionDaoSupport;
     5 import javax.annotation.Resource;
     6 
     7 public abstract class BaseDao extends SqlSessionDaoSupport {
     8 
     9     @Resource
    10     public void setSqlSessionFactory(SqlSessionFactory sqlSessionFactory) {
    11         super.setSqlSessionFactory(sqlSessionFactory);
    12     }
    13 
    14 }

      3、接口 EmployeeDao.java 类

     1 package com.hd.dao;
     2 
     3 import com.hd.pojo.Employee;
     4 
     5 import java.util.List;
     6 
     7 public interface EmployeeDao {
     8 
     9     Employee getEmployeeById(int id);
    10 
    11     List<Employee> findAllEmployees();
    12 
    13 }

      4、dao实现类 EmployeeDaoImpl

     1 package com.hd.dao.impl;
     2 
     3 import com.hd.dao.BaseDao;
     4 import com.hd.dao.EmployeeDao;
     5 import com.hd.pojo.Employee;
     6 import org.springframework.stereotype.Repository;
     7 import java.util.List;
     8 
     9 @Repository("employeeDao")
    10 public class EmployeeDaoImpl extends BaseDao implements EmployeeDao {
    11 
    12     @Override
    13     public Employee getEmployeeById(int id) {
    14         return this.getSqlSession().selectOne("com.jdd.dao.EmployeeDao.getEmployeeById", id);
    15     }
    16 
    17     @Override
    18     public List<Employee> findAllEmployees() {
    19         return this.getSqlSession().selectList("com.jdd.dao.EmployeeDao.findAllEmployees");
    20     }
    21 
    22    
    23 }

      5、这样就可以在service类里注入 employeeDao了

      三、采用 org.mybatis.spring.SqlSessionTemplate 模板类

      1、数据源文件

     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <beans xmlns="http://www.springframework.org/schema/beans"
     3     xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
     4     xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
     5     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     6     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
     7     http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
     8     http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
     9     http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd">
    10 
    11     <!-- 加载配置文件 -->
    12     <context:property-placeholder location="classpath:resource/*.properties" />
    13 
    14     <!-- 数据库连接池 -->
    15         <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
    16         destroy-method="close">
    17         <property name="driverClassName" value="${jdbc.driver}" />
    18         <property name="url" value="${jdbc.url}" />
    19         <property name="username" value="${jdbc.username}" />
    20         <property name="password" value="${jdbc.password}" />
    21         <property name="maxActive" value="10" />
    22         <property name="minIdle" value="5" />
    23     </bean>
    24     
    25     <!-- sqlsessionFactory -->
    26     <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    27         <property name="configLocation" value="classpath:mybatis/SqlMapConfig.xml"></property>
    28         <property name="dataSource" ref="dataSource"></property>
    29         <property name="mapperLocations" value="classpath:com/jdd/mapper/*.xml"></property>
    30     </bean>
    31 
    32     <bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">
    33         <constructor-arg index="0" ref="sqlSessionFactory"/>
    34     </bean>
    35 
    36 </beans>

      2、 basedao.java 类

     1 package com.hd.dao;
     2 
     3 import org.mybatis.spring.SqlSessionTemplate;
     4 import javax.annotation.Resource;
     5 
     6 public abstract class BaseDao {
     7 
     8     public SqlSessionTemplate sqlSessionTemplate;
     9     @Resource
    10     public void setSqlSessionTemplate(SqlSessionTemplate sqlSessionTemplate) {
    11         this.sqlSessionTemplate = sqlSessionTemplate;
    12     }
    13 }

      3、接口 EmployeeDao.java 类

     1 package com.hd.dao;
     2 
     3 import com.hd.pojo.Employee;
     5 import java.util.List;
     6 
     7 public interface EmployeeDao {
     8 
     9     Employee getEmployeeById(int id);
    10 
    11     List<Employee> findAllEmployees();
    12 }

      4、dao实现类 EmployeeDaoImpl

     1 package com.hd.dao.impl;
     2 
     3 import com.hd.dao.BaseDao;
     4 import com.hd.dao.EmployeeDao;
     5 import com.hd.pojo.Employee;
     6 import org.springframework.stereotype.Repository;
     7 import java.util.List;
     8 
     9 @Repository("employeeDao")
    10 public class EmployeeDaoImpl extends BaseDao implements EmployeeDao {
    11 
    12     @Override
    13     public Employee getEmployeeById(int id) {
    14         return sqlSessionTemplate.selectOne("com.jdd.dao.EmployeeDao.getEmployeeById", id);
    15     }
    16 
    17     @Override
    18     public List<Employee> findAllEmployees() {
    19         return sqlSessionTemplate.selectList("com.jdd.dao.EmployeeDao.findAllEmployees");
    20     }
    21 
    22 
    23 }

      5、同样现在也可以在service类里直接注入 employeeDao使用了。

      注:这里basedao的注入比较灵活,也可以注入 SqlSessionFactory, 然后再setter方法里创建 SqlSessionTemplate,如下:

     1 package com.hd.dao;
     2 
     3 import org.apache.ibatis.session.SqlSessionFactory;
     4 import org.mybatis.spring.SqlSessionTemplate;
     5 
     6 import javax.annotation.Resource;
     7 
     8 public abstract class BaseDao {
     9 
    10     public SqlSessionTemplate sqlSessionTemplate;
    11     @Resource
    12     public void setSqlSessionFactory(SqlSessionFactory sqlSessionFactory) {
    13         sqlSessionTemplate = new SqlSessionTemplate(sqlSessionFactory);
    14     }
    15 
    16 }

      

      其实不管是采用 继承SqlSessionDaoSupport类, 注入 sqlSessionFactory的方式, 还是直接注入 SqlSessionTemplate 的方式, 本质上是一样的。

      如果你采用 注入 sqlSessionFactory的方式, 它在底层也是通过sqlSessionFactory 来创建 SqlSessionTemplate ,然后通过其api来操作。

      不信给你们看下 SqlSessionDaoSupport 的源码:

     1 //
     2 // Source code recreated from a .class file by IntelliJ IDEA
     3 // (powered by Fernflower decompiler)
     4 //
     5 
     6 package org.mybatis.spring.support;
     7 
     8 import org.apache.ibatis.session.SqlSession;
     9 import org.apache.ibatis.session.SqlSessionFactory;
    10 import org.mybatis.spring.SqlSessionTemplate;
    11 import org.springframework.dao.support.DaoSupport;
    12 import org.springframework.util.Assert;
    13 
    14 public abstract class SqlSessionDaoSupport extends DaoSupport {
    15     private SqlSession sqlSession;
    16     private boolean externalSqlSession;
    17 
    18     public SqlSessionDaoSupport() {
    19     }
    20 
    21     public void setSqlSessionFactory(SqlSessionFactory sqlSessionFactory) {
    22         if (!this.externalSqlSession) {
    23             this.sqlSession = new SqlSessionTemplate(sqlSessionFactory);
    24         }
    25 
    26     }
    27 
    28     public void setSqlSessionTemplate(SqlSessionTemplate sqlSessionTemplate) {
    29         this.sqlSession = sqlSessionTemplate;
    30         this.externalSqlSession = true;
    31     }
    32 
    33     public SqlSession getSqlSession() {
    34         return this.sqlSession;
    35     }
    36 
    37     protected void checkDaoConfig() {
    38         Assert.notNull(this.sqlSession, "Property 'sqlSessionFactory' or 'sqlSessionTemplate' are required");
    39     }
    40 }

      同样 SqlSessionTemplate 继承了 SqlSession 接口, 因此不管操作哪个效果都一样

      1 //
      2 // Source code recreated from a .class file by IntelliJ IDEA
      3 // (powered by Fernflower decompiler)
      4 //
      5 
      6 package org.mybatis.spring;
      7 
      8 import java.lang.reflect.InvocationHandler;
      9 import java.lang.reflect.Method;
     10 import java.lang.reflect.Proxy;
     11 import java.sql.Connection;
     12 import java.util.List;
     13 import java.util.Map;
     14 import org.apache.ibatis.exceptions.PersistenceException;
     15 import org.apache.ibatis.executor.BatchResult;
     16 import org.apache.ibatis.reflection.ExceptionUtil;
     17 import org.apache.ibatis.session.Configuration;
     18 import org.apache.ibatis.session.ExecutorType;
     19 import org.apache.ibatis.session.ResultHandler;
     20 import org.apache.ibatis.session.RowBounds;
     21 import org.apache.ibatis.session.SqlSession;
     22 import org.apache.ibatis.session.SqlSessionFactory;
     23 import org.springframework.dao.support.PersistenceExceptionTranslator;
     24 import org.springframework.util.Assert;
     25 
     26 public class SqlSessionTemplate implements SqlSession {
     27     private final SqlSessionFactory sqlSessionFactory;
     28     private final ExecutorType executorType;
     29     private final SqlSession sqlSessionProxy;
     30     private final PersistenceExceptionTranslator exceptionTranslator;
     31 
     32     public SqlSessionTemplate(SqlSessionFactory sqlSessionFactory) {
     33         this(sqlSessionFactory, sqlSessionFactory.getConfiguration().getDefaultExecutorType());
     34     }
     35 
     36     public SqlSessionTemplate(SqlSessionFactory sqlSessionFactory, ExecutorType executorType) {
     37         this(sqlSessionFactory, executorType, new MyBatisExceptionTranslator(sqlSessionFactory.getConfiguration().getEnvironment().getDataSource(), true));
     38     }
     39 
     40     public SqlSessionTemplate(SqlSessionFactory sqlSessionFactory, ExecutorType executorType, PersistenceExceptionTranslator exceptionTranslator) {
     41         Assert.notNull(sqlSessionFactory, "Property 'sqlSessionFactory' is required");
     42         Assert.notNull(executorType, "Property 'executorType' is required");
     43         this.sqlSessionFactory = sqlSessionFactory;
     44         this.executorType = executorType;
     45         this.exceptionTranslator = exceptionTranslator;
     46         this.sqlSessionProxy = (SqlSession)Proxy.newProxyInstance(SqlSessionFactory.class.getClassLoader(), new Class[]{SqlSession.class}, new SqlSessionTemplate.SqlSessionInterceptor());
     47     }
     48 
     49     public SqlSessionFactory getSqlSessionFactory() {
     50         return this.sqlSessionFactory;
     51     }
     52 
     53     public ExecutorType getExecutorType() {
     54         return this.executorType;
     55     }
     56 
     57     public PersistenceExceptionTranslator getPersistenceExceptionTranslator() {
     58         return this.exceptionTranslator;
     59     }
     60 
     61     public <T> T selectOne(String statement) {
     62         return this.sqlSessionProxy.selectOne(statement);
     63     }
     64 
     65     public <T> T selectOne(String statement, Object parameter) {
     66         return this.sqlSessionProxy.selectOne(statement, parameter);
     67     }
     68 
     69     public <K, V> Map<K, V> selectMap(String statement, String mapKey) {
     70         return this.sqlSessionProxy.selectMap(statement, mapKey);
     71     }
     72 
     73     public <K, V> Map<K, V> selectMap(String statement, Object parameter, String mapKey) {
     74         return this.sqlSessionProxy.selectMap(statement, parameter, mapKey);
     75     }
     76 
     77     public <K, V> Map<K, V> selectMap(String statement, Object parameter, String mapKey, RowBounds rowBounds) {
     78         return this.sqlSessionProxy.selectMap(statement, parameter, mapKey, rowBounds);
     79     }
     80 
     81     public <E> List<E> selectList(String statement) {
     82         return this.sqlSessionProxy.selectList(statement);
     83     }
     84 
     85     public <E> List<E> selectList(String statement, Object parameter) {
     86         return this.sqlSessionProxy.selectList(statement, parameter);
     87     }
     88 
     89     public <E> List<E> selectList(String statement, Object parameter, RowBounds rowBounds) {
     90         return this.sqlSessionProxy.selectList(statement, parameter, rowBounds);
     91     }
     92 
     93     public void select(String statement, ResultHandler handler) {
     94         this.sqlSessionProxy.select(statement, handler);
     95     }
     96 
     97     public void select(String statement, Object parameter, ResultHandler handler) {
     98         this.sqlSessionProxy.select(statement, parameter, handler);
     99     }
    100 
    101     public void select(String statement, Object parameter, RowBounds rowBounds, ResultHandler handler) {
    102         this.sqlSessionProxy.select(statement, parameter, rowBounds, handler);
    103     }
    104 
    105     public int insert(String statement) {
    106         return this.sqlSessionProxy.insert(statement);
    107     }
    108 
    109     public int insert(String statement, Object parameter) {
    110         return this.sqlSessionProxy.insert(statement, parameter);
    111     }
    112 
    113     public int update(String statement) {
    114         return this.sqlSessionProxy.update(statement);
    115     }
    116 
    117     public int update(String statement, Object parameter) {
    118         return this.sqlSessionProxy.update(statement, parameter);
    119     }
    120 
    121     public int delete(String statement) {
    122         return this.sqlSessionProxy.delete(statement);
    123     }
    124 
    125     public int delete(String statement, Object parameter) {
    126         return this.sqlSessionProxy.delete(statement, parameter);
    127     }
    128 
    129     public <T> T getMapper(Class<T> type) {
    130         return this.getConfiguration().getMapper(type, this);
    131     }
    132 
    133     public void commit() {
    134         throw new UnsupportedOperationException("Manual commit is not allowed over a Spring managed SqlSession");
    135     }
    136 
    137     public void commit(boolean force) {
    138         throw new UnsupportedOperationException("Manual commit is not allowed over a Spring managed SqlSession");
    139     }
    140 
    141     public void rollback() {
    142         throw new UnsupportedOperationException("Manual rollback is not allowed over a Spring managed SqlSession");
    143     }
    144 
    145     public void rollback(boolean force) {
    146         throw new UnsupportedOperationException("Manual rollback is not allowed over a Spring managed SqlSession");
    147     }
    148 
    149     public void close() {
    150         throw new UnsupportedOperationException("Manual close is not allowed over a Spring managed SqlSession");
    151     }
    152 
    153     public void clearCache() {
    154         this.sqlSessionProxy.clearCache();
    155     }
    156 
    157     public Configuration getConfiguration() {
    158         return this.sqlSessionFactory.getConfiguration();
    159     }
    160 
    161     public Connection getConnection() {
    162         return this.sqlSessionProxy.getConnection();
    163     }
    164 
    165     public List<BatchResult> flushStatements() {
    166         return this.sqlSessionProxy.flushStatements();
    167     }
    168 
    169     private class SqlSessionInterceptor implements InvocationHandler {
    170         private SqlSessionInterceptor() {
    171         }
    172 
    173         public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    174             SqlSession sqlSession = SqlSessionUtils.getSqlSession(SqlSessionTemplate.this.sqlSessionFactory, SqlSessionTemplate.this.executorType, SqlSessionTemplate.this.exceptionTranslator);
    175 
    176             Object unwrapped;
    177             try {
    178                 Object result = method.invoke(sqlSession, args);
    179                 if (!SqlSessionUtils.isSqlSessionTransactional(sqlSession, SqlSessionTemplate.this.sqlSessionFactory)) {
    180                     sqlSession.commit(true);
    181                 }
    182 
    183                 unwrapped = result;
    184             } catch (Throwable var11) {
    185                 unwrapped = ExceptionUtil.unwrapThrowable(var11);
    186                 if (SqlSessionTemplate.this.exceptionTranslator != null && unwrapped instanceof PersistenceException) {
    187                     SqlSessionUtils.closeSqlSession(sqlSession, SqlSessionTemplate.this.sqlSessionFactory);
    188                     sqlSession = null;
    189                     Throwable translated = SqlSessionTemplate.this.exceptionTranslator.translateExceptionIfPossible((PersistenceException)unwrapped);
    190                     if (translated != null) {
    191                         unwrapped = translated;
    192                     }
    193                 }
    194 
    195                 throw (Throwable)unwrapped;
    196             } finally {
    197                 if (sqlSession != null) {
    198                     SqlSessionUtils.closeSqlSession(sqlSession, SqlSessionTemplate.this.sqlSessionFactory);
    199                 }
    200 
    201             }
    202 
    203             return unwrapped;
    204         }
    205     }
    206 }
  • 相关阅读:
    对生产稳定的一些思考
    tsar指标解释
    tsar采集nginx指标
    Nginx如何处理一个连接
    Java : 如何更优雅的设计异常
    MySql的索引实现
    IntelliJ Idea 常用配置
    ICSharpCode.SharpZipLib.dll 压缩、解压Zip文件 附源码
    Java BigDecimal使用
    社交系统中用户好友关系数据库设计
  • 原文地址:https://www.cnblogs.com/xiexin2015/p/8998331.html
Copyright © 2011-2022 走看看