有多少 Java 程序员用 jOOQ ?

2018-11-12 21:35:26 +08:00
 Jex

都是习惯用 Mybatis 在 XML 里面拼 SQL ? (看了隔壁关于 SQL 的讨论产生了这个疑问

8430 次点击
所在节点    Java
38 条回复
letitbesqzr
2018-11-13 10:24:19 +08:00
@519718366 #20 对,如果到 join 已经严重影响性能的地步,其实更好的选择是进行冗余,像很多高迸发的程序肯定是不允许进行 join 操作的,多加几个字段进行冗余会比较好。
letitbesqzr
2018-11-13 10:24:59 +08:00
@wysnylc #5 jpa 的语法的确很难用,所以配合了 querydsl,那个 api 设计的就很不错了。
clearbug
2018-11-13 10:33:34 +08:00
第一次听说,之前比较喜欢 mybatis
wysnylc
2018-11-13 11:00:26 +08:00
BQsummer
2018-11-13 12:49:22 +08:00
难道不是每个公司都封装了通用 mapper 吗
xypcn
2018-11-13 12:57:18 +08:00
https://github.com/ecdiy/goserver 看看这个项目,后台程序员的福音,苦逼的 Mybatis
specita
2018-11-13 13:27:54 +08:00
我其实是比较讨厌 xml 的,但是又觉得在代码写着 table().where().find()这种代码还不如 xml 里直接看 sql 来得直观.....
mineqiqi
2018-11-13 14:16:05 +08:00
我觉得不管什么框架 如果需要在代码里写 sql 或者类似 sql 的函数 都不如直接在 xml 写 sql 直观和更好维护
jorneyr
2018-11-13 15:01:38 +08:00
看一个我们的 mapper 吧, 绝大部分都不是单表语句, 觉得 MyBatis 比较合适:

```xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<!--namespace 非常重要:必须是 Mapper 类的全路径-->
<mapper namespace="ebag.mapper.ClazzMapper">
<!-- 老师或者学生的列 -->
<sql id="student_or_teacher_columns">
user.id AS id,
user.username AS username,
user.nickname AS nickname,
user.avatar AS avatar,
user.school_id AS school_id,
user.is_enabled AS is_enabled,
user.gender AS gender,
clazz.name AS clazz_name,
clazz.code AS clazz_code,
clazz.phase AS clazz_phase,
clazz.id AS clazz_id,
cts.subject AS clazz_subject
</sql>

<!-- 查找学校的班级 -->
<select id="findClazzesBySchoolId" resultType="Clazz">
SELECT id, school_id AS schoolId, code, name, phase, grade, type,
enrollment_year AS enrollmentYear, graduation_year AS graduationYear
FROM clazz
WHERE school_id = #{schoolId} AND is_history=#{history}
</select>

<!-- 查询指定 ID 的班级 -->
<select id="findClazzById" parameterType="long" resultType="Clazz">
SELECT id, school_id AS schoolId, code, name, phase, grade, type,
enrollment_year AS enrollmentYear, graduation_year AS graduationYear
FROM clazz WHERE id = #{clazzId}
</select>

<!-- 查找学校的老师 -->
<select id="findTeachersBySchoolId" resultMap="teacherResultMap">
SELECT <include refid="student_or_teacher_columns"/>
FROM (
SELECT * FROM user
WHERE school_id = #{schoolId} AND role = 'ROLE_TEACHER'
LIMIT #{offset}, #{count}
) AS user
LEFT JOIN clazz_teacher_subject AS cts ON cts.teacher_id = user.id
LEFT JOIN clazz ON clazz.id = cts.clazz_id
</select>

<!-- 使用账号查找学校的老师 -->
<select id="findTeachersBySchoolIdAndUsernameLike" resultMap="teacherResultMap">
SELECT <include refid="student_or_teacher_columns"/>
FROM (
SELECT * FROM user
WHERE school_id = #{schoolId} AND role = 'ROLE_TEACHER' AND username LIKE CONCAT('%', #{username}, '%')
LIMIT #{offset}, #{count}
) AS user
LEFT JOIN clazz_teacher_subject AS cts ON cts.teacher_id = user.id
LEFT JOIN clazz ON clazz.id = cts.clazz_id
</select>

<!-- 使用昵称查找学校的老师 -->
<select id="findTeachersBySchoolIdAndNicknameLike" resultMap="teacherResultMap">
SELECT <include refid="student_or_teacher_columns"/>
FROM (
SELECT * FROM user
WHERE school_id = #{schoolId} AND role = 'ROLE_TEACHER' AND nickname LIKE CONCAT('%', #{nickname}, '%')
LIMIT #{offset}, #{count}
) AS user
LEFT JOIN clazz_teacher_subject AS cts ON cts.teacher_id = user.id
LEFT JOIN clazz ON clazz.id = cts.clazz_id
</select>

<!-- 查找学校的学生 -->
<select id="findStudentsBySchoolId" resultMap="studentResultMap">
SELECT <include refid="student_or_teacher_columns"/>
FROM (
SELECT * FROM user
WHERE school_id = #{schoolId} AND role='ROLE_STUDENT'
LIMIT #{offset}, #{count}
) AS user
LEFT JOIN clazz_student AS cs ON cs.student_id = user.id
LEFT JOIN clazz ON clazz.id = cs.clazz_id
LEFT JOIN clazz_teacher_subject cts ON cts.clazz_id = cs.clazz_id
</select>

<!-- 使用账号查找学校的学生 -->
<!-- 注意 LIMIT 必须放到子查询内部,否则数量限制不对 -->
<select id="findStudentsBySchoolIdAndUsernameLike" resultMap="studentResultMap">
SELECT <include refid="student_or_teacher_columns"/>
FROM (
SELECT * FROM user
WHERE school_id = #{schoolId} AND role='ROLE_STUDENT' AND username LIKE CONCAT('%', #{username}, '%')
LIMIT #{offset}, #{count}
) AS user
LEFT JOIN clazz_student AS cs ON cs.student_id = user.id
LEFT JOIN clazz ON clazz.id = cs.clazz_id
LEFT JOIN clazz_teacher_subject cts ON cts.clazz_id = cs.clazz_id
</select>

<!-- 使用名字查找学校的学生 -->
<select id="findStudentsBySchoolIdAndNicknameLike" resultMap="studentResultMap">
SELECT <include refid="student_or_teacher_columns"/>
FROM (
SELECT * FROM user
WHERE school_id = #{schoolId} AND role='ROLE_STUDENT' AND nickname LIKE CONCAT('%', #{nickname}, '%')
LIMIT #{offset}, #{count}
) AS user
LEFT JOIN clazz_student AS cs ON cs.student_id = user.id
LEFT JOIN clazz ON clazz.id = cs.clazz_id
LEFT JOIN clazz_teacher_subject cts ON cts.clazz_id = cs.clazz_id
</select>

<!-- 查找班级下的老师 -->
<select id="findTeachersByClazzId" resultMap="teacherResultMap">
SELECT <include refid="student_or_teacher_columns"/>
FROM clazz_teacher_subject cts
LEFT JOIN clazz ON clazz.id = cts.clazz_id
LEFT JOIN user ON user.id = cts.teacher_id
WHERE cts.clazz_id = #{clazzId}
</select>

<!-- 查找班级下的所有学生 -->
<select id="findStudentsByClazzId" resultMap="studentResultMap">
SELECT <include refid="student_or_teacher_columns"/>
FROM clazz_student cs
LEFT JOIN user ON user.id = cs.student_id
LEFT JOIN clazz ON clazz.id = cs.clazz_id
LEFT JOIN clazz_teacher_subject cts ON cts.clazz_id = cs.clazz_id
WHERE cs.clazz_id=#{clazzId}
ORDER BY cs.student_username
</select>

<!-- 查找指定 ID 的老师 -->
<select id="findTeacherById" resultMap="teacherResultMap">
SELECT <include refid="student_or_teacher_columns"/>
FROM clazz_teacher_subject cts
LEFT JOIN clazz ON clazz.id = cts.clazz_id
LEFT JOIN user ON user.id = cts.teacher_id
WHERE cts.teacher_id = #{teacherId}
</select>

<!-- 查找指定 ID 的老师 -->
<select id="findTeacherByClazzIdAndSubject" resultMap="teacherResultMap">
SELECT <include refid="student_or_teacher_columns"/>
FROM clazz_teacher_subject cts
LEFT JOIN clazz ON clazz.id = cts.clazz_id
LEFT JOIN user ON user.id = cts.teacher_id
WHERE cts.clazz_id = #{clazzId} AND cts.subject = #{subject}
</select>

<!-- 查找指定 ID 的学生 -->
<select id="findStudentById" parameterType="long" resultMap="studentResultMap">
SELECT <include refid="student_or_teacher_columns"/>
FROM clazz_student cs
LEFT JOIN clazz ON clazz.id = cs.clazz_id
LEFT JOIN clazz_teacher_subject cts ON cts.clazz_id = cs.clazz_id
LEFT JOIN user ON user.id = cs.student_id
WHERE cs.student_id = #{studentId}
</select>

<!--查询班级学生人数-->
<select id="findStudentCount" resultType="int">
SELECT count(*) FROM clazz_student WHERE clazz_student.clazz_id = #{clazzId}
</select>

<!-- 启用或禁用老师 -->
<update id="enableTeacher">
UPDATE clazz_teacher_subject SET is_enabled=#{enabled} WHERE teacher_id=#{teacherId};
UPDATE user SET is_enabled=#{enabled} WHERE id=#{teacherId};
</update>

<!-- 启用或禁用学生 -->
<update id="enableStudent">
UPDATE clazz_student SET is_enabled=#{enabled} WHERE student_id=#{studentId};
UPDATE user SET is_enabled=#{enabled} WHERE id=#{studentId};
</update>

<!-- 删除老师 -->
<delete id="deleteTeacher">
DELETE FROM user WHERE id = #{teacherId};
DELETE FROM clazz_teacher_subject WHERE teacher_id = #{teacherId};
</delete>

<!-- 删除学生 -->
<delete id="deleteStudent">
DELETE FROM user WHERE id = #{studentId};
DELETE FROM clazz_student WHERE student_id = #{studentId};
</delete>

<!-- 插入或更新已有班级 -->
<insert id="insertOrUpdateClazz" parameterType="Clazz">
INSERT INTO clazz (id, school_id, code, name, phase, grade, type, enrollment_year, graduation_year, created_time)
VALUES (#{id}, #{schoolId}, #{code}, #{name}, #{phase}, #{grade}, #{type}, #{enrollmentYear}, #{graduationYear}, now())

ON DUPLICATE KEY
UPDATE name = #{name}, phase = #{phase}, grade = #{grade}, type = #{type},
enrollment_year = #{enrollmentYear}, graduation_year = #{graduationYear}
</insert>

<!-- 插入班级学生关系 -->
<insert id="insertClazzStudent">
INSERT INTO clazz_student (school_id, clazz_code, student_username, created_time)
SELECT #{schoolId}, #{clazzCode}, #{studentUsername}, now()
FROM dual
WHERE NOT EXISTS (
SELECT 1 FROM clazz_student
WHERE school_id = #{schoolId} AND clazz_code = #{clazzCode} AND student_username = #{studentUsername}
)
</insert>

<!-- 插入班级老师学科关系 -->
<insert id="insertClazzTeacherSubject">
INSERT INTO clazz_teacher_subject (school_id, clazz_code, teacher_username, subject, created_time)
SELECT #{schoolId}, #{clazzCode}, #{teacherUsername}, #{subject}, now()
FROM dual
WHERE NOT EXISTS (
SELECT 1 FROM clazz_teacher_subject
WHERE school_id = #{schoolId} AND clazz_code = #{clazzCode} AND teacher_username = #{teacherUsername} AND subject = #{subject}
)
</insert>
...
```
zcsz
2018-11-13 15:09:30 +08:00
后端用 Mybatis,SQL 都写 Dao 里,还算简单明了,讲道理现在心思都在前端上,后端快速搭建就成
hsuvee
2018-11-13 15:39:36 +08:00
自研超爽,性能堪比 jdbc,使用感觉堪比....堪比什么想不到,反正剩下的都是垃圾,说 jpa 好的看看性能分析 0.0
Jex
2018-11-13 15:53:08 +08:00
@jorneyr 我回复你一下,只为让评论早点翻页让你那坨 XML 消失
qiyuey
2018-11-13 16:03:13 +08:00
@jorneyr 你这个 xml 感觉不具备可读性
godoway
2018-11-13 16:04:37 +08:00
面对着 Oracle,想用 jooq 都用不了。
面对着一堆 Oracle 自定义函数,jpa 又很麻烦(貌似还不能在插入的时候调用,其实是我不懂...)
最后只能上 mybatis 了,蛋疼...
jorneyr
2018-11-13 16:12:19 +08:00
@qiyuey 有更好的办法吗?
Jex
2018-11-23 12:27:24 +08:00
@jorneyr 在 XML 里面拼 SQL 跟直接在 Java 里面拼 SQL 有多大区别?
applehater
2019-01-15 04:29:26 +08:00
@letitbesqzr 发现工作一年多,还真没写过 join 语句。。
letitbesqzr
2019-01-15 09:07:26 +08:00
@applehater #37 互联网产品吧? 企业产品几乎不可能的,那几千上万张表的业务,不关联很麻烦。。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/507160

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX