123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372 |
- package org.ssssssss.magicapi.modules;
- import org.springframework.jdbc.core.ArgumentPreparedStatementSetter;
- import org.springframework.jdbc.core.RowMapper;
- import org.springframework.jdbc.support.GeneratedKeyHolder;
- import org.springframework.jdbc.support.KeyHolder;
- import org.ssssssss.magicapi.adapter.ColumnMapperAdapter;
- import org.ssssssss.magicapi.adapter.DialectAdapter;
- import org.ssssssss.magicapi.cache.SqlCache;
- import org.ssssssss.magicapi.config.MagicModule;
- import org.ssssssss.magicapi.controller.MagicDynamicDataSource;
- import org.ssssssss.magicapi.controller.MagicDynamicDataSource.DataSourceNode;
- import org.ssssssss.magicapi.dialect.Dialect;
- import org.ssssssss.magicapi.interceptor.SQLInterceptor;
- import org.ssssssss.magicapi.model.Page;
- import org.ssssssss.magicapi.provider.PageProvider;
- import org.ssssssss.magicapi.provider.ResultProvider;
- import org.ssssssss.script.MagicScriptContext;
- import org.ssssssss.script.annotation.Comment;
- import org.ssssssss.script.annotation.UnableCall;
- import java.sql.PreparedStatement;
- import java.sql.Statement;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
- import java.util.function.Function;
- public class SQLModule extends HashMap<String, SQLModule> implements MagicModule {
- @UnableCall
- private MagicDynamicDataSource dynamicDataSource;
- @UnableCall
- private DataSourceNode dataSourceNode;
- @UnableCall
- private PageProvider pageProvider;
- @UnableCall
- private ResultProvider resultProvider;
- @UnableCall
- private ColumnMapperAdapter columnMapperAdapter;
- @UnableCall
- private DialectAdapter dialectAdapter;
- @UnableCall
- private RowMapper<Map<String, Object>> columnMapRowMapper;
- @UnableCall
- private Function<String, String> rowMapColumnMapper;
- @UnableCall
- private SqlCache sqlCache;
- @UnableCall
- private String cacheName;
- @UnableCall
- private List<SQLInterceptor> sqlInterceptors;
- @UnableCall
- private long ttl;
- public SQLModule() {
- }
- public SQLModule(MagicDynamicDataSource dynamicDataSource) {
- this.dynamicDataSource = dynamicDataSource;
- this.dataSourceNode = dynamicDataSource.getDataSource();
- }
- @UnableCall
- public void setPageProvider(PageProvider pageProvider) {
- this.pageProvider = pageProvider;
- }
- @UnableCall
- public void setResultProvider(ResultProvider resultProvider) {
- this.resultProvider = resultProvider;
- }
- @UnableCall
- public void setColumnMapperProvider(ColumnMapperAdapter columnMapperAdapter) {
- this.columnMapperAdapter = columnMapperAdapter;
- }
- @UnableCall
- public void setDialectAdapter(DialectAdapter dialectAdapter) {
- this.dialectAdapter = dialectAdapter;
- }
- @UnableCall
- public void setColumnMapRowMapper(RowMapper<Map<String, Object>> columnMapRowMapper) {
- this.columnMapRowMapper = columnMapRowMapper;
- }
- @UnableCall
- public void setRowMapColumnMapper(Function<String, String> rowMapColumnMapper) {
- this.rowMapColumnMapper = rowMapColumnMapper;
- }
- private void setDynamicDataSource(MagicDynamicDataSource dynamicDataSource) {
- this.dynamicDataSource = dynamicDataSource;
- }
- @UnableCall
- public void setSqlInterceptors(List<SQLInterceptor> sqlInterceptors) {
- this.sqlInterceptors = sqlInterceptors;
- }
- @UnableCall
- public void setSqlCache(SqlCache sqlCache) {
- this.sqlCache = sqlCache;
- }
- private void setDataSourceNode(DataSourceNode dataSourceNode) {
- this.dataSourceNode = dataSourceNode;
- }
- private void setCacheName(String cacheName) {
- this.cacheName = cacheName;
- }
- private void setTtl(long ttl) {
- this.ttl = ttl;
- }
- @UnableCall
- private SQLModule cloneSQLModule() {
- SQLModule sqlModule = new SQLModule();
- sqlModule.setDynamicDataSource(this.dynamicDataSource);
- sqlModule.setDataSourceNode(this.dataSourceNode);
- sqlModule.setPageProvider(this.pageProvider);
- sqlModule.setColumnMapperProvider(this.columnMapperAdapter);
- sqlModule.setColumnMapRowMapper(this.columnMapRowMapper);
- sqlModule.setRowMapColumnMapper(this.rowMapColumnMapper);
- sqlModule.setSqlCache(this.sqlCache);
- sqlModule.setTtl(this.ttl);
- sqlModule.setResultProvider(this.resultProvider);
- sqlModule.setDialectAdapter(this.dialectAdapter);
- sqlModule.setSqlInterceptors(this.sqlInterceptors);
- return sqlModule;
- }
-
- @Comment("开启事务,并在回调中处理")
- public Object transaction(@Comment("回调函数,如:()=>{....}") Function<?, ?> function) {
- Transaction transaction = transaction();
- try {
- Object val = function.apply(null);
- transaction.commit();
- return val;
- } catch (Throwable throwable) {
- transaction.rollback();
- throw throwable;
- }
- }
-
- @Comment("开启事务,返回事务对象")
- public Transaction transaction() {
- return new Transaction(this.dataSourceNode.getDataSourceTransactionManager());
- }
-
- @Comment("使用缓存")
- public SQLModule cache(@Comment("缓存名") String cacheName, @Comment("过期时间") long ttl) {
- if (cacheName == null) {
- return this;
- }
- SQLModule sqlModule = cloneSQLModule();
- sqlModule.setCacheName(cacheName);
- sqlModule.setTtl(ttl);
- return sqlModule;
- }
-
- @Comment("使用缓存,过期时间采用默认配置")
- public SQLModule cache(@Comment("缓存名") String cacheName) {
- return cache(cacheName, 0);
- }
- @Comment("采用驼峰列名")
- public SQLModule camel() {
- return columnCase("camel");
- }
- @Comment("采用帕斯卡列名")
- public SQLModule pascal() {
- return columnCase("pascal");
- }
- @Comment("采用全小写列名")
- public SQLModule lower() {
- return columnCase("lower");
- }
- @Comment("采用全大写列名")
- public SQLModule upper() {
- return columnCase("upper");
- }
- @Comment("列名保持原样")
- public SQLModule normal() {
- return columnCase("default");
- }
- @Comment("指定列名转换")
- public SQLModule columnCase(String name) {
- SQLModule sqlModule = cloneSQLModule();
- sqlModule.setColumnMapRowMapper(this.columnMapperAdapter.getColumnMapRowMapper(name));
- sqlModule.setRowMapColumnMapper(this.columnMapperAdapter.getRowMapColumnMapper(name));
- return sqlModule;
- }
-
- @Override
- public SQLModule get(Object key) {
- SQLModule sqlModule = cloneSQLModule();
- if (key == null) {
- sqlModule.setDataSourceNode(dynamicDataSource.getDataSource());
- } else {
- sqlModule.setDataSourceNode(dynamicDataSource.getDataSource(key.toString()));
- }
- return sqlModule;
- }
-
- @Comment("查询SQL,返回List类型结果")
- public List<Map<String, Object>> select(@Comment("`SQL`语句") String sql) {
- BoundSql boundSql = new BoundSql(sql, this.sqlCache, this.cacheName, this.ttl);
- return boundSql.getCacheValue(this.sqlInterceptors, () -> dataSourceNode.getJdbcTemplate().query(boundSql.getSql(), this.columnMapRowMapper, boundSql.getParameters()));
- }
-
- @Comment("执行update操作,返回受影响行数")
- public int update(@Comment("`SQL`语句") String sql) {
- BoundSql boundSql = new BoundSql(sql);
- sqlInterceptors.forEach(sqlInterceptor -> sqlInterceptor.preHandle(boundSql));
- int value = dataSourceNode.getJdbcTemplate().update(boundSql.getSql(), boundSql.getParameters());
- if (this.cacheName != null) {
- this.sqlCache.delete(this.cacheName);
- }
- return value;
- }
-
- @Comment("执行insert操作,返回插入条数")
- public long insert(@Comment("`SQL`语句") String sql) {
- BoundSql boundSql = new BoundSql(sql);
- sqlInterceptors.forEach(sqlInterceptor -> sqlInterceptor.preHandle(boundSql));
- KeyHolder keyHolder = new GeneratedKeyHolder();
- dataSourceNode.getJdbcTemplate().update(con -> {
- PreparedStatement ps = con.prepareStatement(boundSql.getSql(), Statement.RETURN_GENERATED_KEYS);
- new ArgumentPreparedStatementSetter(boundSql.getParameters()).setValues(ps);
- return ps;
- }, keyHolder);
- if (this.cacheName != null) {
- this.sqlCache.delete(this.cacheName);
- }
- Number key = keyHolder.getKey();
- if (key == null) {
- return -1;
- }
- return key.longValue();
- }
-
- @Comment("执行分页查询,分页条件自动获取")
- public Object page(@Comment("`SQL`语句") String sql) {
- Page page = pageProvider.getPage(MagicScriptContext.get());
- return page(sql, page.getLimit(), page.getOffset());
- }
-
- @Comment("执行分页查询,分页条件手动传入")
- public Object page(@Comment("`SQL`语句") String sql, @Comment("限制条数") long limit, @Comment("跳过条数") long offset) {
- BoundSql boundSql = new BoundSql(sql, this.sqlCache, this.cacheName, this.ttl);
- Dialect dialect = dataSourceNode.getDialect(dialectAdapter);
- BoundSql countBoundSql = boundSql.copy(dialect.getCountSql(boundSql.getSql()));
- int count = countBoundSql.getCacheValue(this.sqlInterceptors, () -> dataSourceNode.getJdbcTemplate().queryForObject(countBoundSql.getSql(), Integer.class, countBoundSql.getParameters()));
- List<Map<String, Object>> list = null;
- if (count > 0) {
- String pageSql = dialect.getPageSql(boundSql.getSql(), boundSql, offset, limit);
- BoundSql pageBoundSql = boundSql.copy(dialect.getCountSql(boundSql.getSql()));
- list = pageBoundSql.getCacheValue(this.sqlInterceptors, () -> dataSourceNode.getJdbcTemplate().query(pageBoundSql.getSql(), this.columnMapRowMapper, pageBoundSql.getParameters()));
- }
- return resultProvider.buildPageResult(count, list);
- }
-
- @Comment("查询int值,适合单行单列int的结果")
- public Integer selectInt(@Comment("`SQL`语句") String sql) {
- BoundSql boundSql = new BoundSql(sql, this.sqlCache, this.cacheName, this.ttl);
- return boundSql.getCacheValue(this.sqlInterceptors, () -> dataSourceNode.getJdbcTemplate().queryForObject(boundSql.getSql(), boundSql.getParameters(), Integer.class));
- }
-
- @Comment("查询单条结果,查不到返回null")
- public Map<String, Object> selectOne(@Comment("`SQL`语句") String sql) {
- BoundSql boundSql = new BoundSql(sql, this.sqlCache, this.cacheName, this.ttl);
- return boundSql.getCacheValue(this.sqlInterceptors, () -> {
- List<Map<String, Object>> list = dataSourceNode.getJdbcTemplate().query(boundSql.getSql(), this.columnMapRowMapper, boundSql.getParameters());
- return list != null && list.size() > 0 ? list.get(0) : null;
- });
- }
-
- @Comment("查询单行单列的值")
- public Object selectValue(@Comment("`SQL`语句") String sql) {
- BoundSql boundSql = new BoundSql(sql, this.sqlCache, this.cacheName, this.ttl);
- return boundSql.getCacheValue(this.sqlInterceptors, () -> dataSourceNode.getJdbcTemplate().queryForObject(boundSql.getSql(), boundSql.getParameters(), Object.class));
- }
- @Comment("指定table,进行一系列操作")
- public NamedTable table(String tableName) {
- return new NamedTable(tableName, this.dataSourceNode);
- }
- @UnableCall
- @Override
- public String getModuleName() {
- return "db";
- }
- }
|