Spring jdbc 入门

spring学习的仓库:  git@gitee.com:jackyqidldd/spring.git

  • 先来一个入门的例子,不用任何配置,方便理解
  1. DataSourceProperties.java   数据源配置的JavaBean类
    @Data
    @Validated
    public class DataSourceProperties extends AbstractMappedProperties{
    
            @NotBlank
            private String url;
    
            @NotBlank
            private String password;
    
            @NotBlank
            private String username;
    
            /**
             * query timeout in seconds
             */
            @Min(0)
            private int timeout=30;
    
            private String driverClassName;
            Map<String,Object> properties;
            /**
             * 其他配置项,例如setting.maxWait,setting.minIdle等(不同的数据源配置不一样)
             * 对于druid,可配置项请参考{@link com.alibaba.druid.pool.DruidDataSource}
             */
            private Map<String,Object> setting=new HashMap<>();
    
    }
    
  2. DefaultDataSource  数据源,用到阿里的DruidDataSource
    public class DefaultDataSource extends DruidDataSource{
    
        private DataSourceProperties dataSourceProperties;
    
        private Map<String,String> driverMap;
    
        private String dbType;
    
        public DefaultDataSource(DataSourceProperties dataSourceProperties) {
            this.dataSourceProperties = dataSourceProperties;
            String url=dataSourceProperties.getUrl();
            this.dbType=getDbType(url);
            this.driverMap=getDriverMap();
    
       
            //1,从dataSourceProperties配置读取
            setUrl(url);
            setDriverClassName(getDriverClassNameByUrl());
            setPassword(dataSourceProperties.getPassword());
            setUsername(dataSourceProperties.getUsername());
            setQueryTimeout(dataSourceProperties.getTimeout());
    
            //2. 从dataSourceProperties.setting配置读取
            initDataSourceReflectively(dataSourceProperties.getSetting());
    
        }

     

  3. 动态数据源
    public class DynamicDataSource extends AbstractRoutingDataSource {
        public DynamicDataSource() {
            setTargetDataSources(TargetDataSourceHolder.get());
        }
    
        @Override
        public void setTargetDataSources(Map targetDataSources) {
            super.setTargetDataSources(targetDataSources);
        }
    
        @Override
        public Object unwrap(Class iface) throws SQLException {
            return null;
        }
    
        @Override
        public boolean isWrapperFor(Class iface) throws SQLException {
            return false;
        }
    //这里为了方便演示,直接写死的数据源名字,实际应用中是当前的数据源
        @Override
        protected Object determineCurrentLookupKey() {
            String dataSourceName = "default";
            return dataSourceName;
        }
    
        @Override
        public void afterPropertiesSet() {
            super.afterPropertiesSet();
            Map<Object, Object> targetDataSources = ReflectionUtils.getFieldValue(this, "targetDataSources");
            ReflectionUtils.setFieldValue(this, "resolvedDataSources", targetDataSources);
        }
  4. DynamicDataSource 注册到容器
    @Configuration
    public class DbConfiguration {
        @Bean
        @ConditionalOnMissingBean
        public DynamicDataSource dynamicDataSource() {
            DynamicDataSource dataSource = new DynamicDataSource();
            return dataSource;
        }
    }

     

  5. 至此准备完成,开始写测试方法
    @RunWith(SpringJUnit4ClassRunner.class)
    @ComponentScan(value = {"com.example.spring"})
    @EnableAutoConfiguration
    public class TestMain {
        @Autowired
        DataSource dataSource;
    
        @Test
        public void testDb() {
            NamedParameterJdbcTemplate namedParameterJdbcTemplate;
            DataSourceProperties dataSourceProperties = new DataSourceProperties();
            dataSourceProperties.setDriverClassName("com.mysql.jdbc.Driver");
            dataSourceProperties.setPassword("1111");
            dataSourceProperties.setUrl("jdbc:mysql://10.11.11.1:3306/point");
            dataSourceProperties.setUsername("root");
    
            Map<String, DataSource> map = new HashMap<>();
            map.put("default", new DefaultDataSource(dataSourceProperties));
            TargetDataSourceHolder.put("default", new DefaultDataSource(dataSourceProperties));
    
    
            MapSqlParameterSource mapSqlParameterSource = new MapSqlParameterSource();
            mapSqlParameterSource.addValue("id", "50");
            namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(dataSource);
            List<Map<String, Object>> result = namedParameterJdbcTemplate.query("select * from pk_config where step=:id", mapSqlParameterSource, new ColumnMapRowMapper());
            System.out.println("******************************");
            System.out.println(JSONUtils.toJSONString(result));
            System.out.println("******************************");

    执行结果:

 

一个简单的jdbc操作就完成了,但是还有很多需要改进的地方

  • db的配置冗余在代码里,可以放到配置文件里,格式如下
default:
  url: jdbc:mysql://10.10.10.10:3306/xx
  username: root
  password: 111

db1:
  url: jdbc:mysql://10.10.10.10:3306/xxx
  username: root
  password: 222
  • 动态数据源DynamicDataSource#determineCurrentLookupKey 写死了数据源"default",改进如下
  1. 初始化把所有数据源保存到DataSourceHolder,类型为:Map<String, DataSource> 
  2. 用户指定了数据源,如:
     //动态设置数据源
        @DataSourceKey("db1")

    则同样把name放到一个DataSourceHolder,类型为ThreadLocal<String>

    ThreadLocal<String> holder = new ThreadLocal<String>();

    所以determineCurrentLookupKey方法可以写成:

    @Override
    	protected Object determineCurrentLookupKey() {
    		String dataSourceName = DynamicDataSourceHolder.getDataSourceName();
    		return dataSourceName;
    	}

    还有可以扩展的地方:

namedParameterJdbcTemplate.query(String sql, SqlParameterSource paramSource, RowMapper<T> rowMapper)

SqlParameterSource sql里的参数传参的方法有2个实现类:

  • BeanPropertySqlParameterSource 直接把bean转成输入参数
  • MapSqlParameterSource  输入参数为map,sql中可以用:对象.变量 的格式

RowMapper db数据和Javabean的映射,也有2个实现类:

  • ColumnMapRowMapper
  • BeanPropertyRowMapper 将数据库查询结果转换为Java类对象。 常应用于使用Spring的JdbcTemplate查询数据库,获取List结果列表,数据库表字段和实体类自动对应。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值