集成和Demo

集成和Demo

Spring集成和Demo

集成提供了Mapper类的自动注入以及SQLManager的自动注入,以及与spring事务集成

  1. <!-- DAO接口所在包名,Spring会自动查找其下的类 -->
  2. <bean name="beetlSqlScannerConfigurer" class="org.beetl.sql.ext.spring4.BeetlSqlScannerConfigurer">
  3. <!-- 哪些类可以自动注入 -->
  4. <property name="basePackage" value="org.beetl.sql.ext.spring4"/>
  5. <!-- 通过类后缀 来自动注入Dao -->
  6. <property name="daoSuffix" value="Dao"/>
  7. <property name="sqlManagerFactoryBeanName" value="sqlManagerFactoryBean"/>
  8. </bean>
  9. <bean id="sqlManagerFactoryBean" class="org.beetl.sql.ext.spring4.SqlManagerFactoryBean">
  10. <property name="cs" >
  11. <bean class="org.beetl.sql.ext.spring4.BeetlSqlDataSource">
  12. <property name="masterSource" ref="dataSource"></property>
  13. </bean>
  14. </property>
  15. <property name="dbStyle">
  16. <bean class="org.beetl.sql.core.db.H2Style"/>
  17. </property>
  18. <property name="sqlLoader">
  19. <bean class="org.beetl.sql.core.ClasspathLoader">
  20. <property name="sqlRoot" value="/sql"></property>
  21. </bean>
  22. </property>
  23. <property name="nc">
  24. <bean class="org.beetl.sql.core.UnderlinedNameConversion"/>
  25. </property>
  26. <property name="interceptors">
  27. <list>
  28. <bean class="org.beetl.sql.ext.DebugInterceptor"></bean>
  29. </list>
  30. </property>
  31. </bean>
  • BeetlSqlScannerConfigurer 根据包名和类后缀来自动注入Dao类,如果没有Dao,可以不配置此项
  • cs: 指定ConnectionSource,可以用系统提供的DefaultConnectionSource,支持按照CRUD决定主从。例子里只有一个master库
  • dbStyle: 数据库类型,目前只支持org.beetl.sql.core.db.MySqlStyle,以及OralceSytle,PostgresStyle,SQLiteStyle,SqlServerStyle,H2Style
  • sqlLoader: sql语句加载来源
  • nc: 命名转化,有默认的DefaultNameConversion,数据库跟类名一致,还有有数据库下划线的UnderlinedNameConversion,JPANameConversion,
  • interceptors:DebugInterceptor 用来打印sql语句,参数和执行时间

注意: 任何使用了Transactional 注解的,将统一使用Master数据源,例外的是@Transactional(readOnly=true),这将让Beetsql选择从数据库。

  1. @Service
  2. public class MyServiceImpl implements MyService {
  3. @Autowired
  4. UserDao dao; // UserDao extends BaseMapper<User>
  5. @Autowired
  6. SQLManager sql;
  7. @Override
  8. @Transactional()
  9. public int total(User user) {
  10. int total = list .size();
  11. dao.deleteById(3);
  12. User u =new User();
  13. u.id = 3;
  14. u.name="hello";
  15. u.age = 12;
  16. dao.insert(u);
  17. return total;
  18. }
  19. }

其他集成配置还包括:

  • functions 配置扩展函数
  • tagFactorys 配置扩展标签
  • configFileResource 扩展配置文件位置,beetlsql将读取此配置文件覆盖beetlsql默认选项
  • defaultSchema 数据库访问schema

参考

可以参考demo https://git.oschina.net/xiandafu/springbeetlsql

SpringBoot集成

未来版本不在使用单数据源集成方式,建议即使你有一个数据源,也采用下一节多数据源集成方式

  1. <dependency>
  2. <groupId>com.ibeetl</groupId>
  3. <artifactId>beetl-framework-starter</artifactId>
  4. <version>1.2.14.RELEASE</version>
  5. </dependency>
@Configuration
public class DataSourceConfig {    

 @Bean(name="datasource")
  public DataSource datasource(Environment env) {
    HikariDataSource ds = new HikariDataSource();
    ds.setJdbcUrl(env.getProperty("spring.datasource.url"));
    ds.setUsername(env.getProperty("spring.datasource.username"));
    ds.setPassword(env.getProperty("spring.datasource.password"));
    ds.setDriverClassName(env.getProperty("spring.datasource.driver-class-name"));
    return ds;
  }
}

提供如下配置

beetl-framework-starter 会读取application.properites如下配置

  • beetlsql.sqlPath,默认为/sql, 作为存放sql文件的根目录,位于/resources/sql目录下

  • beetlsql.nameConversion: 默认是org.beetl.sql.core.UnderlinedNameConversion,能将下划线分割的数据库命名风格转化为java驼峰命名风格,还有常用的DefaultNameConversion,数据库命名完全和Java命名一直,以及JPA2NameConversion,兼容JPA命名

  • beetl-beetlsql.dev:默认是true,即向控制台输出执行时候的sql,参数,执行时间,以及执行的位置,每次修改sql文件的时候,自动检测sql文件修改.

  • beetlsql.daoSuffix:默认为Dao。

  • beetlsql.basePackage:默认为com,此选项配置beetlsql.daoSuffix来自动扫描com包极其子包下的所有以Dao结尾的Mapper类。以本章例子而言,你可以配置“com.bee.sample.ch5.dao”

  • beetlsql.dbStyle :数据库风格,默认是org.beetl.sql.core.db.MySqlStyle.对应不同的数据库,其他还有OracleStyle,PostgresStyle,SqlServerStyle,DB2SqlStyle,SQLiteStyle,H2Style

如果你想配置主从或者指定一个已经配置好的数据源,可以自己创建一个 BeetlSqlDataSource的Bean,比如,在你的配置代码里

@Bean
public BeetlSqlDataSource beetlSqlDataSource(@Qualifier("master")  DataSource dataSource,@Qualifier("slave")  DataSource slave){
    BeetlSqlDataSource source = new BeetlSqlDataSource();
    source.setMasterSource(dataSource);
    source.setSlaves(new DataSource[]{slave});
    return source;
}

注意,可以通过Application.properties 配置如下属性禁用BeetlSQL或者禁用Beetl

beetlsql.enabled=false
beetl.enabled=false

如果不满足你要求,你也可以采用java config方式自己配置,或者参考beetl-framework-starter源码,参考 demo ,http://git.oschina.net/xiandafu/springboot_beetl_beetlsql,自己完成

可以实现BeetlSqlCustomize接口来定制BeetlSQL,比如

@Configuration
public MyConfig{
  @Bean
  public BeetlSqlCustomize beetlSqlCustomize(){
    return  new BeetlSqlCustomize(){
      public void customize(SqlManagerFactoryBean sqlManagerFactoryBean){
        //....
      } 
    };
  }
}

可以掉用SqlManagerFactoryBean来配置,或者获得SQLManager 进一步配置

SpringBoot集成多数据源

单数据源情况,BeetlSQL配置方式如上一节所示,BeetlSQL会自动根据单数据源配置好BeetlSQL,多数据源情况下,需要配置指定的多数据源,如下俩个数据源

@Configuration
public class DataSourceConfig {

    @Bean(name = "a")
    public DataSource datasource(Environment env) {
        HikariDataSource ds = new HikariDataSource();
        ds.setJdbcUrl(env.getProperty("spring.datasource.a.url"));
        ds.setUsername(env.getProperty("spring.datasource.a.username"));
        ds.setPassword(env.getProperty("spring.datasource.a.password"));
        ds.setDriverClassName(env.getProperty("spring.datasource.a.driver-class-name"));
        return ds;
    }

    @Bean(name = "b")
    public DataSource datasourceOther(Environment env) {
        HikariDataSource ds = new HikariDataSource();
        ds.setJdbcUrl(env.getProperty("spring.datasource.b.url"));
        ds.setUsername(env.getProperty("spring.datasource.b.username"));
        ds.setPassword(env.getProperty("spring.datasource.b.password"));
        ds.setDriverClassName(env.getProperty("spring.datasource.b.driver-class-name"));
        return ds;
    }

对于数据源a,b,需要配置beetlsql如下配置

beetlsql.ds.a.basePackage=com.bee.sample.ch5.xxxdao.
beetlsql.ds.b.basePackage=com.bee.sample.ch5.yyyydao
beetlsql.mutiple.datasource=a,b

以beetlsql.ds 为前缀,需要分别配置每个数据源的basePackage,nameConversion等配置,如果没有,则使用默认配置,比如beetlsql.ds.a.nameConversion= ….OralceStyle;beetlsql.ds.b.nameConversion= ….MySqlStyle;beetlsql.mutiple.datasource 则配置了多个数据源列表。

如果需要定制每一个SQLManager,需要提供BeetlSqlMutipleSourceCustomize

@Bean
    public BeetlSqlMutipleSourceCustomize beetlSqlCustomize() {
        return new BeetlSqlMutipleSourceCustomize() {
            @Override
            public void customize(String dataSource,SQLManager sqlManager) {
                //可以在这里添加各种扩展,指定主从等
            }

        };
    }

JFinal集成和Demo

在configPlugin 里配置BeetlSql

JFinalBeetlSql.init();

默认会采用c3p0 作为数据源,其配置来源于jfinal 配置,如果你自己提供数据源或者主从,可以如下

JFinalBeetlSql.init(master,slaves);

由于使用了Beetlsql,因此你无需再配置 数据库连接池插件,和ActiveRecordPlugin,可以删除相关配置。

在controller里,可以通过JFinalBeetlSql.dao 方法获取到SQLManager

SQLManager dao = JFinalBeetlSql.dao();
BigBlog blog = getModel(BigBlog.class);
dao.insert(BigBlog.class, blog);

如果想控制事物,还需要注册Trans

public void configInterceptor(Interceptors me) {
    me.addGlobalActionInterceptor(new Trans());
}

然后业务方法使用

@Before(Trans.class)
public void doXXX(){....}

这样,方法执行完毕才会提交事物,任何RuntimeException将回滚,如果想手工控制回滚.也可以通过

Trans.commit()
Trans.rollback()

如果习惯了JFinal Record模式,建议用户创建一个BaseBean,封装SQLManager CRUD 方法即可。然后其他模型继承此BaseBean

注意

可以通过jfinal属性文件来配置sqlManager,比如 PropKit.use("config.txt", "UTF-8"),然后可以配置 sql.nc,sql.root,sql.interceptor,sql.dbStyle,具体参考源代码

JFinalBeetlSql.initProp

参考

可以参考demo https://git.oschina.net/xiandafu/jfinal_beet_beetsql_btjson

demo https://code.csdn.net/xiandafu/beetlsql_orm_sample/tree/master

动态切换数据源

Spring提供了一个AbstractRoutingDataSource,可以使用此类构建DataSource从而完成数据源切换操作,在BeetlSQL里,这要求数据源对应的数据库schema 是一样的,否则切换到其他数据源会出现找不到表,或者列不匹配情况。

也可以参考org.beetl.sql.ext.spring.MultiTenantSpringConnectionSourcece 实现一个SQLManager的ConnectionSource,这是再BeetlSQL层进行数据源切换,代码如下

public class MultiTenantSpringConnectionSourcec extends SpringConnectionSource {
    //当前上下文所属多租户
    static ThreadLocal<String> local = new ThreadLocal<String>();

    //所有的数据源
    Map<String, DataSource> datasources = new HashMap<String, DataSource>();

    @Override
    public Connection getConn(String sqlId, boolean isUpdate, String sql, List paras) {
        String tenant = local.get();
        if (tenant == null) {
            throw new IllegalArgumentException("tenant 为空");
        }

        DataSource ds = datasources.get(tenant);
        if (ds == null) {
            throw new IllegalArgumentException("tenant: " + tenant + " 对应的数据库为空");
        }

        return super.doGetConnectoin(ds);
    }

    public void setCurrentTenant(String tenant) {
        local.set(tenant);
    }

    public Map<String, DataSource> getDatasources() {
        return datasources;
    }

    public void setDatasources(Map<String, DataSource> datasources) {
        this.datasources = datasources;
    }

}

需要注意,切换数据源,必须要保证数据源的shcema是一样的,否则不叫切换,叫不同数据源