GithubHelp home page GithubHelp logo

gaarason / database-all Goto Github PK

View Code? Open in Web Editor NEW
707.0 10.0 25.0 1.89 MB

Eloquent ORM for Java 8, 11, 17 and Spring boot 2.x , 3.x

License: MIT License

Java 99.80% FreeMarker 0.20%
laravel java orm database spring-boot starter eloquent-orm mysql model orm-framework

database-all's Issues

Springboot TransactionManager 报错

感觉是事物管理出问题了,我这边因为还使用了hibernate,会导致下面的配置报错。

@Bean
@ConditionalOnMissingBean
public GaarasonTransactionManager gaarasonTransactionManager() {
    logger.info("-------------------- gaarasonTransactionManager init ------------------");
    return new GaarasonTransactionManager(gaarasonDataSource());
}

报错截图
image

GaarasonDatabaseConfiguration自定义的代码,因为database-spring-boot-starter里没有配置@primary优先级,也会导致出问题

@Slf4j
@Configuration
@AutoConfigureBefore(DruidDataSourceAutoConfigure.class)
@EnableConfigurationProperties({GaarasonDatabaseProperties.class})
@Import({GeneralModel.class})
public class GaarasonDatabaseConfiguration {

    private static final Logger logger = LoggerFactory.getLogger(GaarasonDatabaseConfiguration.class);

    /**
     * 指定 model 扫描范围
     */
    GaarasonDatabaseConfiguration(ApplicationContext applicationContext, GaarasonDatabaseProperties gaarasonDatabaseProperties) {
        // 注册 model实例获取方式
        ModelInstanceProvider.register(modelClass -> {
            try {
                return ObjectUtils.typeCast(applicationContext.getBean(modelClass));
            } catch (BeansException e) {
                return ObjectUtils.typeCast(applicationContext.getBean(StringUtils.lowerFirstChar(modelClass.getSimpleName())));
            }
        });
        logger.info("Model instance provider has been registered success.");

        // 注册 雪花id实现
        final int workerId = gaarasonDatabaseProperties.getSnowFlake().getWorkerId();
        final int dataId = gaarasonDatabaseProperties.getSnowFlake().getDataId();
        ContainerProvider.register(IdGenerator.SnowFlakesID.class, clazz -> new SnowFlakeIdGenerator(workerId, dataId));

        logger.info("SnowFlakesID[ workId: {}, dataId: {}] instance has been registered success.", workerId, dataId);
    }

    @Primary
    @Bean
    @ConfigurationProperties(prefix = "spring.datasource2")
    @ConditionalOnMissingBean
    public DataSource dataSourceDruidConfig() {
        logger.info("-------------------- dataSource druid config init ---------------------");
        return DruidDataSourceBuilder.create().build();
    }

    @Bean
    @ConditionalOnMissingBean
    public GaarasonDataSource gaarasonDataSource() {
        logger.info("-------------------- gaarasonDataSource init --------------------------");
        return ContainerProvider.getBean(GaarasonDataSourceConfig.class).build(Collections.singletonList(dataSourceDruidConfig()));
    }

    @Bean
    @ConditionalOnMissingBean
    public GaarasonTransactionManager gaarasonTransactionManager() {
        logger.info("-------------------- gaarasonTransactionManager init ------------------");
        return new GaarasonTransactionManager(gaarasonDataSource());
    }
}

请教怎么在多个数据源里让事务可以正常执行。

希望尽量和Eloquent设计的api保持一致,这样有助于使用过Eloquent的人,更简单的上手,也不容易引起歧义。

还想提一个建议,希望尽量和Eloquent设计的api保持一致,这样有助于使用过Eloquent的人,更简单的上手,也不容易引起歧义。毕竟目前在其他语言中,都有Eloquent的实现,在我个人看来,Eloquent就是对ORM的一次重新定义,特别是在JAVA里。
另外我们知道,在laravel中的api中,对每一个方法的命名,每一个功能的实现,都经过反复的推敲,据作者所说,有时候为了一个命名都会消耗几天的时间。其实能在java中看到这个现实是很高兴的,对那些JPA+Hibernate、mybatis等框架表示要抓狂的感觉。我坦白我是刚转到java不久,没有那些沉重的历史包袱,特别深恶痛觉把sql写到xml中的方式。以上观点,仅代表自己,不接受反驳。

public Record<T, K> findOrNew(Object id) {
      Record<T, K> first = this.newQuery().where(this.getPrimaryKeyColumnName(), id).first();
        if (first != null) {
            return first;
        } else {
            return this.newRecord();
        }
}

public Record<T, K> firstOrNew(T entity) {
        Record<T, K> first = this.newQuery().where(entity).first();
        if (first != null) {
            return first;
        } else {
            Record<T, K> tkRecord = this.newRecord();
            tkRecord.getEntity(entity);
            return tkRecord;
        }
 }

就如上面两个方法,是我自己在BaseModel里面加的。
1、findOrNew是传入PrimaryKey值,获取记录,这样既简单又好理解。
2、firstOrNew是传入实体然后进行查询,一般情况下,除非知道实体里的值,才会实现。但是实际情况。我们从POST请求接收到的就是实体,这个时候不能作为where的参数,当然在我自己的项目中firstOrNew是有机会出场的,比如要多条件查询一个记录,就显得非常方便了,但是平时并不需要这样处理, 其实本项目内部已经有find方法的实现了。

where检索条件中的value类型问题

目前看到where中的value类型为String,针对比如int类型的字段,会导致mysql执行时将该字段类型转换为字符串,引起一些隐藏bug或索引失效的问题。所以whereParameterList是否应当设置为List而非List类型(并同步调整最后执行sql时的参数绑定逻辑)?

maven package error

Error:(40, 41) java: cannot find symbol
symbol: method create()
location: class gaarason.database.connection.GaarasonDataSourceBuilder.

请问可否支持重写关联关系?

比如我想在belongsto里面需要用通过两个组合外键的形式来关联查询父表中的信息。但是好像不支持多列。请问我是否有办法重写BelongsToQueryRelation来达到我的目的呢?谢谢

直接使用实例化Model对象, 报 NoSuchMethodException QueryBuilderConfig.<init>()

可以提供以下信息
bug类:

1 .使用的代码库的方式 ? (源码编译 / maven依赖 / 源码拷贝 ..)

repositories {
    mavenCentral()
    maven {
        url 'https://jitpack.io'
    }
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-data-jdbc'
    implementation 'com.mysql:mysql-connector-j'
    implementation 'com.github.gaarason.database-all:database-spring-boot-starter:4.8.0'
}

2 .使用的代码库的方式版本 ? ( tag版本 / maven依赖版本 / commit hash ..)

3 .java版本
java 17

4 .框架以及版本 ( eg : spring boot 3.0.0 )
无框架

5 .数据库以及版本 ( eg : mysql 8.0.0 )
mysql8.0.27
6 .问题简述 ( 有必要的话, 可以贴下相关调用代码以及定义代码 )
以下是报错代码


public class Person {
    Integer id;
    String name;
    String firstname;
    String lastname;
    String addr;
}


public class PersonModel extends Model<Person, Integer> {
    @Override
    public GaarasonDataSource getGaarasonDataSource() {
        GaarasonDataSource build = GaarasonDataSourceBuilder.build(new Sdata2Application().dataSource());

        // 注释掉这行 就会报错 
//        new MysqlAutoconfiguration().init(build.getContainer());
        return build;
    }

    public static void main(String[] args) {
        var generalModel = new PersonModel();
        var record = generalModel.newQuery()
                .first();
        System.out.println("record = " + record);
    }
}

7 .预期效果

Exception in thread "main" gaarason.database.exception.ObjectNewInstanceException: Error instantiating object[interface gaarason.database.config.QueryBuilderConfig] with message : Error instantiating object[interface gaarason.database.config.QueryBuilderConfig]
	at gaarason.database.provider.ContainerProvider.getBeansInside(ContainerProvider.java:144)
	at gaarason.database.provider.ContainerProvider.getBeans(ContainerProvider.java:86)
	at gaarason.database.connection.GaarasonDataSourceWrapper.getQueryBuilder(GaarasonDataSourceWrapper.java:329)
	at gaarason.database.connection.GaarasonDataSourceWrapper.getQueryBuilder(GaarasonDataSourceWrapper.java:316)
	at gaarason.database.eloquent.ModelOfQuery.theBuilder(ModelOfQuery.java:50)
	at gaarason.database.eloquent.ModelOfQuery.newQuery(ModelOfQuery.java:55)
	at com.example.sdata2.PersonModel.main(PersonModel.java:23)
Caused by: gaarason.database.exception.ObjectNewInstanceException: Error instantiating object[interface gaarason.database.config.QueryBuilderConfig]
	at gaarason.database.util.ClassUtils.newInstance(ClassUtils.java:56)
	at gaarason.database.provider.ContainerProvider.lambda$defaultNewInstance$1(ContainerProvider.java:160)
	at gaarason.database.provider.ContainerProvider.getBeansInside(ContainerProvider.java:136)
	... 6 more
Caused by: java.lang.NoSuchMethodException: gaarason.database.config.QueryBuilderConfig.<init>()
	at java.base/java.lang.Class.getConstructor0(Class.java:3585)
	at java.base/java.lang.Class.getDeclaredConstructor(Class.java:2754)
	at gaarason.database.util.ClassUtils.newInstance(ClassUtils.java:52)
	... 8 more

Caused by: gaarason.database.exception.ObjectNewInstanceException: Error instantiating object[interface gaarason.database.config.QueryBuilderConfig]

Caused by: java.lang.NoSuchMethodException: gaarason.database.config.QueryBuilderConfig.<init>()

建议类:

感觉像是直接实例化Model对象的时候, 没有把 MysqlQueryBuilderConfig 这个类给注册到container中.

我在做created_at和updated_at自动生成的时候遇到了问题

在文档的事件中提到“允许你在模型生命周期中的多个时间点调用如下这些方法”。

然后我一开始直接复制文档代码,发现并不生效。然后在ORMEvent找到说明“其中以 record 为参数的事件, 仅在使用ORM风格时, 会触发”。

现在问题是这样的,在文档中并没有告知“使用ORM风格”是什么意思。我翻了Query和Model都没有提到ORM风格。且使用Query插入的a方式并不能触发creating和created。

我想询问的是是我使用方法有问题还是需要添加什么注解或者是我操作有什么问题,以及ORM风格是什么意思。

代码如下:
main:

        UserData userData=new UserData();
        userData.setNumber("123456");
        userDataModel.newQuery().insert(userData);

UserData(采用生成):

public class UserData extends BaseEntity {
    private static final long serialVersionUID = 1L;

    /** auto generator start **/


    @Column(name = "number", length = 12L, comment = "学生:学号 老师:工号")
    private String number;

    @Column(name = "created_at", nullable = true)
    private LocalDateTime createdAt;

    @Column(name = "updated_at", nullable = true)
    private LocalDateTime updatedAt;

    @Column(name = "deleted_at", nullable = true)
    private LocalDateTime deletedAt;


    /** auto generator end **/

    @Repository
    public static class Model extends BaseEntity.BaseModel<UserData, Long> {
    }
}

BaseEntity(采用生成):

public abstract class BaseEntity implements Serializable {
    private static final long serialVersionUID = 1L;

    /**
     * auto generator start
     **/


    @Primary()
    @Column(name = "id", unsigned = true)
    private Long id;

    @Column(name = "created_at", nullable = true)
    private LocalDateTime createdAt;

    @Column(name = "updated_at", nullable = true)
    private LocalDateTime updatedAt;

    @Column(name = "deleted_at", nullable = true)
    private LocalDateTime deletedAt;

    /**
     * auto generator end
     **/
    public abstract static class BaseModel<T extends BaseEntity, K> extends Model<T, K> {

        @Resource
        @Lazy
        protected GaarasonDataSource gaarasonDataSource;

        @Override
        public GaarasonDataSource getGaarasonDataSource() {
            return gaarasonDataSource;
        }

        /**
         * sql日志记录
         *
         * @param sql           带占位符的sql
         * @param parameterList 参数
         */
        @Override
        public void log(String sql, Collection<?> parameterList) {
            String format = String.format(sql.replace(" ? ", "\"%s\""), parameterList.toArray());
            System.out.println(format);
            //log.debug("SQL complete : {}", format);
        }

        @Override

        public boolean creating(Record<T, K> record) {
            System.out.println("orm creating");
            return super.creating(record);
        }

        /**
         * 是否启用软删除
         */
        @Override
        protected boolean softDeleting() {
            return false;
        }

        /**
         * 删除(软/硬删除)
         *
         * @param builder 查询构造器
         * @return 删除的行数
         */
        @Override
        public int delete(Builder<T, K> builder) {
            return softDeleting() ? softDelete(builder) : builder.forceDelete();
        }

        /**
         * 恢复软删除
         *
         * @param builder 查询构造器
         * @return 删除的行数
         */
        @Override
        public int restore(Builder<T, K> builder) {
            return softDeleteRestore(builder);
        }

        /**
         * 软删除查询作用域(反)
         *
         * @param builder 查询构造器
         */
        @Override
        protected void scopeSoftDeleteOnlyTrashed(Builder<T, K> builder) {
            builder.whereNotNull("deleted_at");
        }

        /**
         * 软删除查询作用域(反)
         *
         * @param builder 查询构造器
         */
        protected void scopeSoftDeleteWithTrashed(Builder<T, K> builder) {

        }

        /**
         * 软删除查询作用域
         *
         * @param builder 查询构造器
         */
        @Override
        protected void scopeSoftDelete(Builder<T, K> builder) {
            builder.whereNull("deleted_at");
        }


        /**
         * 软删除实现
         *
         * @param builder 查询构造器
         * @return 删除的行数
         */
        @Override
        protected int softDelete(Builder<T, K> builder) {
            return builder.data("deleted_at", LocalDateTime.now()).update();
        }

        /**
         * 恢复软删除实现
         *
         * @param builder 查询构造器
         * @return 恢复的行数
         */
        @Override
        protected int softDeleteRestore(Builder<T, K> builder) {
            return builder.data("deleted_at", null).update();
        }
    }
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.