├── .gitignore ├── README.md └── mysql ├── init-test-data.sql ├── java ├── pom.xml └── src │ └── main │ └── java │ └── com │ └── itranswarp │ └── learnsql │ ├── LearnSql.java │ ├── SqlExecutor.java │ └── Student.java └── nodejs ├── learnsql.js └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | 3 | *.py[cod] 4 | 5 | test.db 6 | test.txt 7 | sina.html 8 | 9 | # C extensions 10 | *.so 11 | 12 | # Packages 13 | *.egg 14 | *.egg-info 15 | dist 16 | build 17 | eggs 18 | parts 19 | bin 20 | var 21 | sdist 22 | develop-eggs 23 | .installed.cfg 24 | lib 25 | lib64 26 | __pycache__ 27 | 28 | # Installer logs 29 | pip-log.txt 30 | 31 | # Unit test / coverage reports 32 | .coverage 33 | .tox 34 | nosetests.xml 35 | 36 | *.class 37 | 38 | # Mobile Tools for Java (J2ME) 39 | .mtj.tmp/ 40 | 41 | .vscode 42 | 43 | # Package Files # 44 | *.jar 45 | *.war 46 | *.ear 47 | 48 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 49 | hs_err_pid* 50 | 51 | mysql-data/ 52 | es-data/ 53 | 54 | # Maven.gitignore ############################################################# 55 | 56 | target/ 57 | pom.xml.tag 58 | pom.xml.releaseBackup 59 | pom.xml.versionsBackup 60 | pom.xml.next 61 | release.properties 62 | dependency-reduced-pom.xml 63 | buildNumber.properties 64 | .mvn/timing.properties 65 | 66 | ###################### 67 | # OS generated files # 68 | ###################### 69 | .DS_Store 70 | .DS_Store? 71 | ._* 72 | .Spotlight-V100 73 | .Trashes 74 | Icon? 75 | ehthumbs.db 76 | Thumbs.db 77 | dist 78 | MANIFEST 79 | 80 | # Translations 81 | *.mo 82 | 83 | # Mr Developer 84 | .mr.developer.cfg 85 | .project 86 | .pydevproject 87 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | SQL 教程 2 | ======== 3 | -------------------------------------------------------------------------------- /mysql/init-test-data.sql: -------------------------------------------------------------------------------- 1 | -- 如果test数据库不存在,就创建test数据库: 2 | CREATE DATABASE IF NOT EXISTS test; 3 | 4 | -- 切换到test数据库 5 | USE test; 6 | 7 | -- 删除classes表和students表(如果存在): 8 | DROP TABLE IF EXISTS classes; 9 | DROP TABLE IF EXISTS students; 10 | 11 | -- 创建classes表: 12 | CREATE TABLE classes ( 13 | id BIGINT NOT NULL AUTO_INCREMENT, 14 | name VARCHAR(100) NOT NULL, 15 | PRIMARY KEY (id) 16 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 17 | 18 | -- 创建students表: 19 | CREATE TABLE students ( 20 | id BIGINT NOT NULL AUTO_INCREMENT, 21 | class_id BIGINT NOT NULL, 22 | name VARCHAR(100) NOT NULL, 23 | gender VARCHAR(1) NOT NULL, 24 | score INT NOT NULL, 25 | PRIMARY KEY (id) 26 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 27 | 28 | -- 插入classes记录: 29 | INSERT INTO classes(id, name) VALUES (1, '一班'); 30 | INSERT INTO classes(id, name) VALUES (2, '二班'); 31 | INSERT INTO classes(id, name) VALUES (3, '三班'); 32 | INSERT INTO classes(id, name) VALUES (4, '四班'); 33 | 34 | -- 插入students记录: 35 | INSERT INTO students (id, class_id, name, gender, score) VALUES (1, 1, '小明', 'M', 90); 36 | INSERT INTO students (id, class_id, name, gender, score) VALUES (2, 1, '小红', 'F', 95); 37 | INSERT INTO students (id, class_id, name, gender, score) VALUES (3, 1, '小军', 'M', 88); 38 | INSERT INTO students (id, class_id, name, gender, score) VALUES (4, 1, '小米', 'F', 73); 39 | INSERT INTO students (id, class_id, name, gender, score) VALUES (5, 2, '小白', 'F', 81); 40 | INSERT INTO students (id, class_id, name, gender, score) VALUES (6, 2, '小兵', 'M', 55); 41 | INSERT INTO students (id, class_id, name, gender, score) VALUES (7, 2, '小林', 'M', 85); 42 | INSERT INTO students (id, class_id, name, gender, score) VALUES (8, 3, '小新', 'F', 91); 43 | INSERT INTO students (id, class_id, name, gender, score) VALUES (9, 3, '小王', 'M', 89); 44 | INSERT INTO students (id, class_id, name, gender, score) VALUES (10, 3, '小丽', 'F', 85); 45 | 46 | -- OK: 47 | SELECT 'ok' as 'result:'; 48 | -------------------------------------------------------------------------------- /mysql/java/pom.xml: -------------------------------------------------------------------------------- 1 | 4 | 4.0.0 5 | com.itranswarp 6 | learn-sql 7 | 0.0.1-SNAPSHOT 8 | 9 | 10 | UTF-8 11 | 1.8 12 | 1.8 13 | 1.8 14 | 15 | 16 | 17 | 18 | 19 | mysql 20 | mysql-connector-java 21 | 8.0.28 22 | 23 | 24 | com.zaxxer 25 | HikariCP 26 | 3.1.0 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /mysql/java/src/main/java/com/itranswarp/learnsql/LearnSql.java: -------------------------------------------------------------------------------- 1 | package com.itranswarp.learnsql; 2 | 3 | import java.sql.SQLException; 4 | import java.util.List; 5 | 6 | public class LearnSql { 7 | 8 | public static void main(String[] args) throws SQLException { 9 | try (SqlExecutor executor = new SqlExecutor("jdbc:mysql://localhost:3306/test", "root", "password")) { 10 | // raw query: 11 | List> results = executor.select("SELECT * FROM students WHERE score >= ?", 85); 12 | results.forEach(row -> { 13 | System.out.println(String.join(", ", row.stream().map(String::valueOf).toArray(String[]::new))); 14 | }); 15 | // update: 16 | executor.update("UPDATE students SET score = 99 WHERE id = ?", 1); 17 | // delete: 18 | executor.delete("DELETE FROM students WHERE class_id = ?", 2); 19 | // query as object: 20 | List students = executor.select(Student.class, 21 | "SELECT id, class_id classId, name, gender, score FROM students"); 22 | students.forEach(System.out::println); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /mysql/java/src/main/java/com/itranswarp/learnsql/SqlExecutor.java: -------------------------------------------------------------------------------- 1 | package com.itranswarp.learnsql; 2 | 3 | import java.lang.reflect.Field; 4 | import java.sql.Connection; 5 | import java.sql.PreparedStatement; 6 | import java.sql.ResultSet; 7 | import java.sql.ResultSetMetaData; 8 | import java.sql.SQLException; 9 | import java.util.ArrayList; 10 | import java.util.List; 11 | 12 | import com.zaxxer.hikari.HikariConfig; 13 | import com.zaxxer.hikari.HikariDataSource; 14 | 15 | public class SqlExecutor implements AutoCloseable { 16 | 17 | private HikariDataSource dataSource; 18 | 19 | public SqlExecutor(String url, String username, String password) { 20 | HikariConfig config = new HikariConfig(); 21 | config.setJdbcUrl(url); 22 | config.setUsername(username); 23 | config.setPassword(password); 24 | config.setAutoCommit(true); 25 | this.dataSource = new HikariDataSource(config); 26 | } 27 | 28 | public Connection openConnection() throws SQLException { 29 | return dataSource.getConnection(); 30 | } 31 | 32 | public List> select(String sql, Object... args) throws SQLException { 33 | try (Connection conn = openConnection()) { 34 | try (PreparedStatement ps = conn.prepareStatement(sql)) { 35 | for (int i = 0; i < args.length; i++) { 36 | ps.setObject(i + 1, args[i]); 37 | } 38 | try (ResultSet rs = ps.executeQuery()) { 39 | List> list = new ArrayList<>(); 40 | int columns = rs.getMetaData().getColumnCount(); 41 | while (rs.next()) { 42 | List cols = new ArrayList<>(); 43 | for (int i = 1; i <= columns; i++) { 44 | cols.add(rs.getObject(i)); 45 | } 46 | list.add(cols); 47 | } 48 | return list; 49 | } 50 | } 51 | } 52 | } 53 | 54 | public List select(Class clazz, String sql, Object... args) throws SQLException { 55 | try (Connection conn = openConnection()) { 56 | try (PreparedStatement ps = conn.prepareStatement(sql)) { 57 | for (int i = 0; i < args.length; i++) { 58 | ps.setObject(i + 1, args[i]); 59 | } 60 | try (ResultSet rs = ps.executeQuery()) { 61 | List list = new ArrayList<>(); 62 | ResultSetMetaData meta = rs.getMetaData(); 63 | List columns = new ArrayList<>(); 64 | for (int i = 1; i <= meta.getColumnCount(); i++) { 65 | columns.add(meta.getColumnLabel(i)); 66 | } 67 | while (rs.next()) { 68 | list.add(instanceOf(clazz, columns, rs)); 69 | } 70 | return list; 71 | } 72 | } 73 | } 74 | } 75 | 76 | public int update(String sql, Object... args) throws SQLException { 77 | try (Connection conn = openConnection()) { 78 | try (PreparedStatement ps = conn.prepareStatement(sql)) { 79 | for (int i = 0; i < args.length; i++) { 80 | ps.setObject(i + 1, args[i]); 81 | } 82 | return ps.executeUpdate(); 83 | } 84 | } 85 | } 86 | 87 | public int delete(String sql, Object... args) throws SQLException { 88 | return update(sql, args); 89 | } 90 | 91 | public void close() { 92 | this.dataSource.close(); 93 | } 94 | 95 | private T instanceOf(Class clazz, List columns, ResultSet rs) { 96 | try { 97 | T bean = clazz.newInstance(); 98 | int index = 0; 99 | for (String column : columns) { 100 | index++; 101 | Field f = clazz.getField(column); 102 | f.set(bean, rs.getObject(index, f.getType())); 103 | } 104 | return bean; 105 | } catch (InstantiationException | IllegalAccessException | IllegalArgumentException | SQLException 106 | | NoSuchFieldException | SecurityException e) { 107 | throw new RuntimeException(e); 108 | } 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /mysql/java/src/main/java/com/itranswarp/learnsql/Student.java: -------------------------------------------------------------------------------- 1 | package com.itranswarp.learnsql; 2 | 3 | public class Student { 4 | 5 | public long id; 6 | public long classId; 7 | public String name; 8 | public String gender; 9 | public double score; 10 | 11 | @Override 12 | public String toString() { 13 | return String.format("{Student: id=%s, classId=%s, name=%s, gender=%s, score=%s}", id, classId, name, gender, 14 | score); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /mysql/nodejs/learnsql.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const mysql = require('mysql2'); 4 | 5 | const config = { 6 | host: 'localhost', 7 | user: 'root', 8 | password: 'password', 9 | database: 'test' 10 | }; 11 | 12 | const pool = mysql.createPool(config).promise(); 13 | 14 | async function main() { 15 | let rows, fields, results; 16 | 17 | [rows, fields] = await pool.query('SELECT * FROM students WHERE score >= ?', 80); 18 | for (let row of rows) { 19 | console.log(row); 20 | } 21 | 22 | [results, fields] = await pool.execute('UPDATE students SET score = score - 5 WHERE score > ? AND score < ?', [80, 90]); 23 | console.log(`${results.changedRows} records are updated.`); 24 | 25 | pool.end(); 26 | } 27 | 28 | main(); 29 | -------------------------------------------------------------------------------- /mysql/nodejs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "learnsql", 3 | "description": "A nodejs sample code for MySQL.", 4 | "version": "1.0.0", 5 | "main": "learnsql.js", 6 | "scripts": { 7 | "start": "node learnsql.js" 8 | }, 9 | "keywords": [ 10 | "SQL", 11 | "mysql", 12 | "liaoxuefeng", 13 | "Node.js" 14 | ], 15 | "author": "Liao Xuefeng", 16 | "dependencies": { 17 | "mysql2": "1.6.4" 18 | }, 19 | "devDependencies": {} 20 | } 21 | --------------------------------------------------------------------------------