# [18🈲]增删改查大法-六合篇-2022(不限语言)

@todo 总结一下, 大致分5种思路

  • 拼接占位字符串 --> golang与php的主流方法, java的nutz
快速灵活
但不方便维护, 重构火葬场

  • 代码与SQL分离 @nice --> java的Mybatis与BeetlSQL(太小众不敢用)
四两拨千斤, 最划算的实现方法
已经会SQL的学习成本很低
但不方便迁移数据库和重构

===
@ps 但我不能接受写在xml里
@ps 直接在字符串里写SQL, 就没有语法高亮了

  • 设计查询规约 @nice --> nodejs的GraphQL或者json对象, java的apijson(GraphQL感觉)
分摊了前后端压力
但设计规约不通用并难推广

===
@ps 相当于重新设计了SQL

JPA也可以算属于这种, 为什么会有这种诡异的脑洞...
findByUserIdAndTotal(String userid, BigDecimal total)

  • 扩展实体功能 --> C#与Python, java的jooq(繁琐)
便于维护类型与重构, 不易出错, 可以扩展更多功能
但代码量瞬间上去了, 没啥美感

  • 运算符开挂或重载 @nice @peek --> C#与kotlin是天然支持的, java有objectivesql(但不好用)
技术上最赏心悦目
但一般是新兴的语言才用


# 工作语言

  • java ->>
  • python
  • javascript

# 熟悉语言 @sub

  • golang
  • kotlin
  • scala

# 陌生语言 @other

  • c#
  • php
  • ruby

# 风格 @diff

  • Active Record
  • Mapper
  • Example @old
Java前期吃了静态语言不够灵活的亏

# Python

  • SQLAlchemy
instances = db.session.query(Instance.name, Instance.sep_status, User.email)
  .outerjoin( User, Instance.user_id==User.id)
  .filter(Instance.is_terminated==0)

# JavaScript

  • prisma

  • typeorm

const results = await this.app.mysql.select('posts', { // 搜索 post 表
  where: { status: 'draft', author: ['author1', 'author2'] }, // WHERE 条件
  columns: ['author', 'title'], // 要查询的表字段
  orders: [['created_at','desc'], ['id','desc']], // 排序方式
  limit: 10, // 返回数据量
  offset: 0, // 数据偏移量
});

=> SELECT `author`, `title` FROM `posts`
  WHERE `status` = 'draft' AND `author` IN('author1','author2')
  ORDER BY `created_at` DESC, `id` DESC LIMIT 0, 10;
await Flight.where(Flight.field('departure'), 'Paris')
  .leftJoin(Airport, Airport.field('id'), Flight.field('airportId'))
  .get();

# Kotlin

val employees = Employees
    .joinReferencesAndSelect()
    .whereWithConditions {
        if (someCondition) {
            it += Employees.managerId.isNull()
        }
        if (otherCondition) {
            it += Employees.departmentId eq 1
        }
    }
    .orderBy(Employees.id.asc())
    .limit(0, 10)
    .map { Employees.createEntity(it) }
兼容java, 但不建议  

===
val select = db
    .select(case(User.gender eq 1 then "男") elseIs "女" alias "gender")
    .select(sum(User.id) * 100 alias "sum_id")
    .from(User)
    .groupBy(case(User.gender eq 1 then "男") elseIs "女")

# golang

  • gorm

# Scala

函数式编程
@ps 看不懂


# C#

db.Set<UserInfor>().ToList();
 
//查询表达式
var account = (
  from u in _context.Users
  where u.Id == id
  select u.Account
).ToList();
 
//查询单个
_context.Movie.FirstOrDefaultAsync(m => m.ID == id);
_context.Movie.FindAsync(id); 
//查询指定列
_context.Set<User>().AsNoTracking().Where(t=>t.Id=="11").Select(t => new { t.Account, t.PassWord }).FirstOrDefaultAsync();
 
// 预先加载查询
var blogs = context.Blogs.Include(blog => blog.Posts).ToList();
// 包含多个层级的查询
var blogs = context.Blogs.Include(blog => blog.Posts).ThenInclude(post => post.Author).ToList();
fsql.Select<Topic, Category, CategoryType>()
  .LeftJoin((a,b,c) => a.CategoryId == b.Id)
  .LeftJoin((a,b,c) => b.ParentId == c.Id)
  .Where((a,b,c) => c.Id > 0)
  .ToList((a,b,c) => new { a,b,c });

# PHP

// 简单查询
Db::table('think_user')
    ->where('status',1)
    ->order('create_time')
    ->limit(10)
    ->select();

// 关联
Db::table('think_user')
  ->alias('a')
  ->join(['think_work'=>'w'],'a.id=w.artist_id')
  ->join(['think_card'=>'c'],'a.card_id=c.id')
  ->select();    

# Ruby

# 简单的更新
user = User.find_by(name: 'David')
user.name = 'Dave'
user.save

# 用update方法
user = User.find_by(name: 'David')
user.update(name: 'Dave')

# user = User.find_by(name: 'David')
user.update(name: 'Dave')

# 批量修改
User.update_all "name = 'cwh'"