gaarason / database-all Goto Github PK
View Code? Open in Web Editor NEWEloquent ORM for Java 8, 11, 17 and Spring boot 2.x , 3.x
License: MIT License
Eloquent ORM for Java 8, 11, 17 and Spring boot 2.x , 3.x
License: MIT License
能不能添加@transient类似的可以跳过某一个字段的实体,在数据库更新或者插入的时候不赋值。
感觉是事物管理出问题了,我这边因为还使用了hibernate,会导致下面的配置报错。
@Bean
@ConditionalOnMissingBean
public GaarasonTransactionManager gaarasonTransactionManager() {
logger.info("-------------------- gaarasonTransactionManager init ------------------");
return new GaarasonTransactionManager(gaarasonDataSource());
}
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());
}
}
请教怎么在多个数据源里让事务可以正常执行。
Error:(40, 41) java: cannot find symbol
symbol: method create()
location: class gaarason.database.connection.GaarasonDataSourceBuilder.
很好的东西,就是想问一下,有没有群之类的
在文档的事件中提到“允许你在模型生命周期中的多个时间点调用如下这些方法”。
然后我一开始直接复制文档代码,发现并不生效。然后在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();
}
}
}
不支持jdk8的新api localDate localtime localDatetime等实体类型
定义好数据关系, 就可以直接无限with ...
关键是, 还没有多余重复的查询.
我愿称之为最强
请问什么时候添加findOrNew,firstOrNew,firstOrCreate,updateOrCreate等相关函数
目前看到where中的value类型为String,针对比如int类型的字段,会导致mysql执行时将该字段类型转换为字符串,引起一些隐藏bug或索引失效的问题。所以whereParameterList是否应当设置为List而非List类型(并同步调整最后执行sql时的参数绑定逻辑)?
我是刚从laravel 转过来的。刚接触框架,是我那里没配置好吗
可以提供以下信息
我感觉这个框架不应该叫这个名字,应该叫MyBatis什么的,比如隔壁的MyBatis-flex现在就感觉人气不错
还想提一个建议,希望尽量和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方法的实现了。
比如我想在belongsto里面需要用通过两个组合外键的形式来关联查询父表中的信息。但是好像不支持多列。请问我是否有办法重写BelongsToQueryRelation来达到我的目的呢?谢谢
可以提供以下信息
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中.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.