java开发之Java ORM 框架推荐(1)

本文介绍了ObjectiveSQL如何在Java和数据库间进行自动转换,包括类名与表名的映射规则,关联对象处理,领域模型定义,数据操作(查询、更新、事务),复杂SQL编程,以及与面试技巧相关的内容。
摘要由CSDN通过智能技术生成

缺省情况下,ObjectiveSQL 以驼峰与下划线的形式对Java 元素与数据库元素进行互相转换,示例如下:

1)Java 定义如下:

class Member {

private String memberNo;

private String name;

}

复制代码

2)数据库表定义如下:

create table members (

member_no varchar not null,

name varchar

);

复制代码

类名:Member 在数据库中对应的名称为 members,而字段名memberNo 对应的列名为 member_no,而字段名name 没有任何变化

4.1.1 关联对象

1)Java 定义如下:

class Member {

private String memberNo;

private String name;

@Relation(relationType = RelationType.HAS_MANY)

private List orders;

}

class Order {

private String no;

private Long memberId;

@Relation(relationType = RelationType.BELONGS_TO)

private Member member;

}

复制代码

2)数据库表定义如下:

create table members (

member_no varchar not null,

name varchar

);

create table members (

member_no varchar not null,

member_id int(10) not null,

name varchar

);

复制代码

通过上面的结构定义,可以看出几个关键特征:

  • 用于承载HAS_MANY 关联对象的实例变量members 是由类型转换成复数,而BELONGS_TO 与HAS_ONE则为单数

  • Order 类中存在一个外键对应的实例变量memberId,同时在表中也存在一个member_id与其对应

  • 其它规则与类与表转换的规则一致

注意: 所有类名在转换为复杂时,遵循英文的规律,例如:person 对应 pepole

4.2 领域模型定义

@DomainModel

public class Member {

@Size(min = 5, max = 20)

private String no;

@Queryable

private String name;

private Integer gender;

private String mobile;

@Transient

private String otherInfo;

@Relation(relationType = RelationType.HAS_MANY)

private List orders;

}

复制代码

ObjectiveSQL 会根据上述模型定义,自动生成基础的SQL 编程相关方法和SQL 抽象模型定义

4.3 数据查询

Member.countAll();

Member.count(“name = ?”, “braisdom”);

Member.queryByPrimaryKey(1);

Member.queryFirst(“id > ?”, 1);

Member.query(“id > ?”, 1);

Member.queryAll();

复制代码

4.4 数据更新

Member.create(newMember);

Member.create(newMember, true); // Create a member without validating

Member.create(Member.newInstanceFrom(memberHash));

Member.create(new Member[]{newMember1, newMember2, newMember3}, false);

Member.update(1L, newMember, true); // Update a member by primary key and skip validationg

Member.update(“name = ?”, “name = ?”, newName, oldName);

Member.destroy(1L); // Delete a member by primary key

Member.destroy(“name = ?”, “Mary”);

复制代码

4.5 事务

4.5.1 基于Annotation 的事务

// The method will be executed in a database thransaction

@Transactional

public static void makeOrder(Order order, OrderLine… orderLines) throws SQLException {

Order.create(order, false);

OrderLine.create(orderLines, false);

}

复制代码

4.5.2 手动事务管理

// Transaction executing manually

Databases.executeTransactionally(((connection, sqlExecutor) -> {

Member.update(1L, newMember, true);

Member.update(“name = ?”, “name = ?”, newName, oldName);

return null;

}));

复制代码

4.6 关联对象查询

Member.queryAll(Member.HAS_MANY_ORDERS);

Member.queryFirst(“id > ?”, Member.HAS_MANY_ORDERS, 1);

Member.query(“id > ?”, Member.HAS_MANY_ORDERS, 1);

Member.queryByPrimaryKey(1, Member.HAS_MANY_ORDERS);

Member.queryByName(“braisdom”, Member.HAS_MANY_ORDERS);

复制代码

上述代码中的 Member.HAS_MANY_ORDERS 属性为ObjectiveSQL 自动生成,在特殊情况下,可以基于 com.github.braisdom.objsql.relation.Relationship 自定义关联关系的构建逻辑。

4.7 分页查询

// Create a Page instance with current page and page size

Page page = Page.create(0, 10);

PagedList members = Member.pagedQueryAll(page, Member.HAS_MANY_ORDERS);

PagedList members = Member.pagedQuery(page, “name = ?”, “braisdom”);

复制代码

4.8 Query 接口编程

Query query = Member.createQuery();

query.project(“name”).groupBy(“name”).having(“COUNT(*) > 0”).orderBy(“name DESC”);

List members = query.execute(Member.HAS_MANY_ORDERS);

// Paged querying with querying dynamically

Paginator paginator = Databases.getPaginator();

Page page = Page.create(0, 10);

PagedList pagedMembers = paginator

.paginate(page, query, Member.class, Member.HAS_MANY_ORDERS);

复制代码

针对SQL 中的分组和排序,需要通过Query 接口完成,同时Query 接口也可以进行分页和关联对象查询。

4.9 Validation

ObjectiveSQL Validation 内部集成了Jakarta Bean Validation

详细使用方法请参考:beanvalidation.org/

4.9.1 手工调用 validate 方法

Member newMember = new Member()

.setNo(“100”)

.setName(“Pamela”)

.setGender(1)

.setMobile(“15011112222”);

// Violations occurred in field ‘no’

Validator.Violation[] violations = newMember.validate();

复制代码

4.9.2 创建对象时 validate

Member newMember = new Member()

.setNo(“100000”)

.setName(“Pamela”)

.setGender(1)

.setMobile(“15011112222”);

Member.create(newMember);

Member.create(newMember, true); // Skip validation

复制代码

4.10 自定义SQL

Member.execute(“DELETE FROM members WHERE name = ?”, “Pamela”);

复制代码

5 复杂SQL 编程指南

ObjectiveSQL 提供的复杂SQL 编程,其实是对SQL 语法的一种抽象和建模,以Java API 形式进行互相作用,使得复杂SQL 不再以字符串的形式出现在Java 中,从而实现动态化SQL 变得清晰易理解,不同的业务系统也可以基于ObjectiveSQL 对自身业务的再抽象和建模,实现SQL 逻辑的复用。

5.1 JOIN 查询

5.1.1 隐式 Join

Member.Table member = Member.asTable();

Order.Table order = Order.asTable();

Select select = new Select();

select.project(member.no, member.name, count().as(“order_count”))

.from(member, order)

.where(member.id.eq(order.memberId))

.groupBy(member.no, member.name);

List members = select.execute(Member.class);

复制代码

SELECT T0.NO , T0.name , COUNT(*) AS order_count

FROM members AS T0, orders AS T1

WHERE (T0.id = T1.member_id )

GROUP BY T0.NO , T0.name

复制代码

5.1.2 显式Join

Member.Table member = Member.asTable();

Order.Table order = Order.asTable();

Select select = new Select();

select.project(member.no, member.name, count().as(“order_count”))

.from(member)

.leftOuterJoin(order, order.memberId.eq(member.id))

.groupBy(member.no, member.name);

List members = select.execute(Member.class);

复制代码

SELECT T0.NO , T0.name , COUNT(*) AS order_count

FROM members AS T0

LEFT OUTER JOIN orders AS T1 ON (T1.member_id = T0.id )

GROUP BY T0.NO , T0.name

复制代码

5.2 分页查询

Member.Table member = Member.asTable();

Order.Table order = Order.asTable();

Paginator paginator = Databases.getPaginator();

Page page = Page.create(0, 20);

Select select = new Select();

select.project(member.no, member.name, count().as(“order_count”))

.from(member, order)

.where(member.id.eq(order.memberId))

.groupBy(member.no, member.name);

PagedList members = paginator.paginate(page, select, Member.class);

复制代码

– Counting SQL

SELECT COUNT(*) AS count_

FROM (

SELECT

T0.NO,

T0.name,

COUNT(*) AS order_count

FROM members AS T0, orders AS T1

WHERE (T0.id = T1.member_id)

GROUP BY T0.NO, T0.name

) T

复制代码

– Querying SQL

SELECT T0.NO, T0.name, COUNT(*) AS order_count

FROM members AS T0, orders AS T1

WHERE (T0.id = T1.member_id)

GROUP BY T0.NO, T0.name

LIMIT 0, 20

复制代码

5.3 复杂表达式查询

ObjectiveSQL 通过运算符重域技术使得Expression 也可以参与各类运算符计算,从而使得Java 代码变得简单易懂,而不是通过各类运算符方法进行计算。ObjectiveSQL 表达式计算时并不能够与SQL 表达完匹配,默认情况下所有表达式均可以进行算术运算,在IntelliJ IDEA 中并不能给出完整的提醒,例如:JoinExpression 也可以进行算术运算,此时在IntelliJ IDEA 中并不会出现语法错误的提醒,但在执行运算过程中会抛出 UnsupportedArithmeticalException,该异常为RuntimeException 的子类。

Order.Table orderTable = Order.asTable();

Select select = new Select();

select.project((sum(orderTable.amount) / sum(orderTable.quantity) * 100).as(“unit_amount”))

.from(orderTable)

.where(orderTable.quantity > 30 &&

orderTable.salesAt.between(“2020-05-01 00:00:00”, “2020-05-02 23:59:59”))

.groupBy(orderTable.memberId);

List orders = select.execute(Order.class);

复制代码

SELECT ((((SUM(T0.amount ) / SUM(T0.quantity ) )) * 100)) AS unit_amount

FROM orders AS T0

WHERE ((T0.quantity > 30)

AND T0.sales_at BETWEEN ‘2020-05-01 00:00:00’ AND ‘2020-05-02 23:59:59’ )

GROUP BY T0.member_id

复制代码

5.4 动态查询

所谓动态查询,实际上就是表达式的构建过程跟随着参数的有无而变化,基于这种使用场景,ObjectiveSQL 设计了一个永真的逻辑表达式EternalExpression ,永真表达式是程序上的一种巧妙设计,使得代码逻辑变得更清晰,即使所有参数均未赋值,整个表达式也会存在一个永的表达,确保最终SQL 语句的正常。

String[] filteredNo = {“202000001”, “202000002”, “202000003”};

int filteredQuantity = 0;

Order.Table orderTable = Order.asTable();

Select select = new Select();

LogicalExpression eternalExpression = new EternalExpression();

if(filteredNo.length > 0) {

eternalExpression = eternalExpression.and(orderTable.no.in(filteredNo));

}

if(filteredQuantity != 0) {

eternalExpression = eternalExpression.and(orderTable > filteredQuantity);

}

select.project((sum(orderTable.amount) / sum(orderTable.quantity) * 100).as(“unit_amount”))

.from(orderTable)

.where(eternalExpression)

.groupBy(orderTable.memberId);

List orders = select.execute(Order.class);

复制代码

SELECT ((((SUM(T0.amount ) / SUM(T0.quantity ) )) * 100)) AS unit_amount

FROM orders AS T0
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

总结

虽然面试套路众多,但对于技术面试来说,主要还是考察一个人的技术能力和沟通能力。不同类型的面试官根据自身的理解问的问题也不尽相同,没有规律可循。

上面提到的关于这些JAVA基础、三大框架、项目经验、并发编程、JVM及调优、网络、设计模式、spring+mybatis源码解读、Mysql调优、分布式监控、消息队列、分布式存储等等面试题笔记及资料

有些面试官喜欢问自己擅长的问题,比如在实际编程中遇到的或者他自己一直在琢磨的这方面的问题,还有些面试官,尤其是大厂的比如 BAT 的面试官喜欢问面试者认为自己擅长的,然后通过提问的方式深挖细节,刨根到底。
《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》点击传送门即可获取!
029)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

总结

虽然面试套路众多,但对于技术面试来说,主要还是考察一个人的技术能力和沟通能力。不同类型的面试官根据自身的理解问的问题也不尽相同,没有规律可循。

[外链图片转存中…(img-zDwPTlbl-1712027478029)]

[外链图片转存中…(img-sLiZtcjN-1712027478030)]

上面提到的关于这些JAVA基础、三大框架、项目经验、并发编程、JVM及调优、网络、设计模式、spring+mybatis源码解读、Mysql调优、分布式监控、消息队列、分布式存储等等面试题笔记及资料

有些面试官喜欢问自己擅长的问题,比如在实际编程中遇到的或者他自己一直在琢磨的这方面的问题,还有些面试官,尤其是大厂的比如 BAT 的面试官喜欢问面试者认为自己擅长的,然后通过提问的方式深挖细节,刨根到底。
《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》点击传送门即可获取!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值