Lightsleep est une bibliothèque de mappage O / R (Object-Relational) légère disponible dans Java 8 et supérieur.
--2017-01-14 --3-1-15. Ajout de l'exemple SELECT COUNT (*) et de l'exemple SQL (PostgrSQL, Oracle, SQL Server) --2017-01-29- * version 1.7.0 * compatible (compatible SQLite) --2017-02-11- * version 1.8.0 * prise en charge (@ColumnType, @ColumnTypeProperty ajouté) --2017-02-18 --Correction de la description du pilote JDBC pour SQL Server dans l'exemple build.gradle. --2017-02-26- * version 1.8.2 * compatible --2017-04-16 --Modifier le téléchargement en lien --2017-06-05- * version 1.9.0 * compatible (compatible DB2) --2017-09-09- * version 2.0.0 * compatible, exemple de description ajouté dans Groovy --2017-11-14- * version 2.1.0 * prise en charge (plusieurs URL JDBC prises en charge) --2017-12-06 --Ajout d'un exemple de description de lightsleep.properties qui spécifie plusieurs sources de données avec Jndi. --2018-10-07- * version 3.0.0 * prise en charge (type d'API DateTime pris en charge) --2019-07-17- * version 3.1.0 * prise en charge (sous-requête de clause FROM, création SQL UNION prise en charge) --2019-09-25- * version 3.2.0 * compatible (compatible MariaDB)
--API utilisant des fonctionnalités ajoutées dans Java 8 (interface fonctionnelle, classe facultative).
build.gradle
Exemple de description:
build.gradle
apply plugin: 'java-library'
repositories {
jcenter()
}
dependencies {
compile 'org.lightsleep:lightsleep:3.2.0'
}
Exemple de description lorsque la bibliothèque de journalisation, le pilote JDBC et la bibliothèque du pool de connexions sont ajoutés:
build.gradle
apply plugin: 'java-library'
repositories {
jcenter()
}
dependencies {
compile 'org.lightsleep:lightsleep:3.2.0'
//Lors de l'utilisation d'une bibliothèque de journalisation
runtimeOnly 'log4j:log4j:1.2.17' // Log4j
runtimeOnly 'org.apache.logging.log4j:log4j-core:2.12.1' // Log4j2
runtimeOnly 'ch.qos.logback:logback-classic:1.2.3' // LogBack
//L'un des pilotes JDBC suivants ou d'autres
runtimeOnly 'com.ibm.db2.jcc:db2jcc4:db2jcc4' // DB2
runtimeOnly 'org.mariadb.jdbc:mariadb-java-client:2.4.4' // MariaDB
runtimeOnly 'mysql:mysql-connector-java:8.0.17' // MySQL
runtimeOnly 'com.oracle.ojdbc:ojdbc8:19.3.0.0' // Oracle
runtimeOnly 'org.postgresql:postgresql:42.2.8' // PostgreSQL
runtimeOnly 'org.xerial:sqlite-jdbc:3.28.0' // SQLite
runtimeOnly 'com.microsoft.sqlserver:mssql-jdbc:7.4.1.jre8' // SQLServer
//Lors de l'utilisation de la bibliothèque du pool de connexions
runtimeOnly 'com.mchange:c3p0:0.9.5.4' // C3p0
runtimeOnly 'org.apache.commons:commons-dbcp2:2.7.0' // Dbcp
runtimeOnly 'com.zaxxer:HikariCP:3.4.1' // HikariCP
runtimeOnly 'org.apache.tomcat:tomcat-jdbc:9.0.26' // TomcatCP
}
Définissez une classe d'entité (un conteneur pour les données) pour chaque table de la base de données.
Exemple de définition:
Contact.java
package org.lightsleep.example.entity;
import java.sql.Date;
import org.lightsleep.entity.*;
public class Contact {
@Key
public int id;
public String firstName;
public String lastName;
public LocalDate birthday;
}
Phone.java
package org.lightsleep.example.entity;
import org.lightsleep.entity.*;
public class Phone {
@Key
public int contactId;
public short childIndex;
public String label;
public String content;
}
Contact.groovy
package org.lightsleep.example.entity
import java.sql.Date
import org.lightsleep.entity.*
class Contact {
@Key
int id
String firstName
String lastName
LocalDate birthday
}
Phone.groovy
package org.lightsleep.example.entity
import org.lightsleep.entity.*
class Phone {
@Key
int contactId
short childIndex
String label
String content
}
Dans l'exemple ci-dessus, le champ «public» est défini, mais il est possible de combiner le champ «private» et la méthode «public getter / setter». La méthode getter
peut être effectuée avec ʻis ou sans préfixe en plus du préfixe
get. La méthode
setter prend également en charge avec ou sans le préfixe
set`.
Java
private int id;
public int getId() {return id;}
public void setId(int id) {this.id = id;}
Groovy
int id
int getId() {return id}
void setId(int id) {this.id = id}
Si le nom de la classe et le nom de la table associée sont différents, ajoutez «@ Table» à la classe.
Java
import org.lightsleep.entity.*;
@Table("CONTACTS")
public class Contact {
Groovy
import org.lightsleep.entity.*
@Table('CONTACTS')
public class Contact {
Ajoutez «@ Key» au champ correspondant à la colonne de la ou des clés primaires.
Si le nom de la colonne et le nom du champ sont différents, ajoutez «@ Column» au champ.
Java
import org.lightsleep.entity.*;
...
@Column("LAST_NAME")
public String lastName;
Groovy
import org.lightsleep.entity.*
...
@Column('LAST_NAME')
String lastName
Si le type de colonne et le type de champ sont différents, ajoutez «@ ColumnType» au champ.
Java
import org.lightsleep.entity.*;
...
@ColumnType(Long.class)
public LocalDate birthday;
Groovy
import org.lightsleep.entity.*
...
@ColumnType(Long)
LocalDate birthday
Les champs non statiques sont automatiquement associés aux colonnes, donc ajoutez «@ NonColumn» aux champs qui ne sont pas liés aux colonnes.
Java
import java.util.ArrayList;
import java.util.List;
import org.lightsleep.entity.*;
...
@NonColumn
public List<Phone> phones = new ArrayList<>();
Groovy
import org.lightsleep.entity.*
...
@NonColumn
List<Phone> phones = []
Si vous voulez que SQL spécifie une expression au lieu d'une valeur de champ, ajoutez @ Select
, @ Insert
, @ Update
.
Si vous souhaitez spécifier qu'il n'est pas utilisé pour SQL, ajoutez @ NonSelect
, @ NonInsert
, @ NonUpdate
.
Java
import java.time.LocalDateTime;
import org.lightsleep.entity.*;
...
@Insert("0")
@Update("{updateCount}+1")
public int updateCount;
@Insert("CURRENT_TIMESTAMP")
@NonUpdate
public LocalDateTime createdTime;
@Insert("CURRENT_TIMESTAMP")
@Update("CURRENT_TIMESTAMP")
public LocalDateTime updatedTime;
Groovy
import java.time.LocalDateTime
import org.lightsleep.entity.*
...
@Insert('0')
@Update('{updateCount}+1')
int updateCount
@Insert('CURRENT_TIMESTAMP')
@NonUpdate
LocalDateTime createdTime
@Insert('CURRENT_TIMESTAMP')
@Update('CURRENT_TIMESTAMP')
LocalDateTime updatedTime
Il comporte les annotations suivantes.
Nom de l'annotation | Contenu à préciser | Cible à spécifier |
---|---|---|
@Table |
nom de la table | classe |
@Key |
Prend en charge la clé primaire | champ |
@Column |
Nom de colonne | champ |
@ColumnType |
Type de colonne | champ |
@NonColumn |
Non lié aux colonnes | champ |
@NonSelect |
Non utilisé pour SELECT SQL | champ |
@NonInsert |
Non utilisé pour INSERT SQL | champ |
@NonUpdate |
Non utilisé pour UPDATE SQL | champ |
@Select |
Expressions utilisées dans SELECT SQL | champ |
@Insert |
Expressions utilisées dans INSERT SQL | champ |
@Update |
Expressions utilisées dans UPDATE SQL | champ |
@KeyProperty |
Prend en charge la clé primaire | classe |
@ColumnProperty |
Nom de colonne | classe |
@ColumnTypeProperty |
Type de colonne | classe |
@NonColumnProperty |
Non lié aux colonnes | classe |
@NonSelectProperty |
Non utilisé pour SELECT SQL | classe |
@NonInsertProperty |
Non utilisé pour INSERT SQL | classe |
@NonUpdateProperty |
Non utilisé pour UPDATE SQL | classe |
@SelectProperty |
Expressions utilisées dans SELECT SQL | classe |
@InsertProperty |
Expressions utilisées dans INSERT SQL | classe |
@UpdateProperty |
Expressions utilisées dans UPDATE SQL | classe |
@XxxxxProperty est utilisé pour spécifier les champs définis dans les superclasses. Vous pouvez spécifier la même annotation plusieurs fois dans une classe.
Exemple de définition:
lightsleep.properties
Logger = Log4j2
#Database =PostgreSQL * version 2.1.Aboli à 0
ConnectionSupplier = Dbcp
url = jdbc:postgresql://postgresqlserver/example
username = example
password = _example_
initialSize = 10
maxTotal = 100
Logger est une spécification de la méthode de sortie du journal, et sélectionnez l'une des options suivantes.
Contenu spécifié | Bibliothèque de journalisation à utiliser | Niveau de journal | Fichier de définition |
---|---|---|---|
Jdk |
Java Runtime | - | logging.Défini dans les propriétés |
Log4j |
Log4j 1.x.x | - | log4j.properties ou log4j.Défini en xml |
Log4j2 |
Log4j 2.x.x | - | log4j2.Défini en xml |
SLF4J |
SLF4J | - | Dépend de l'implémentation de la bibliothèque de journalisation cible |
Std$Out$Trace |
System.Sortie vers sortie | trace | - |
Std$Out$Debug |
Comme ci-dessus | debug | - |
Std$Out$Info |
Comme ci-dessus | info | - |
Std$Out$Warn |
Comme ci-dessus | warn | - |
Std$Out$Error |
Comme ci-dessus | error | - |
Std$Out$Fatal |
Comme ci-dessus | fatal | - |
Std$Err$Trace |
System.Sortie à err | trace | - |
Std$Err$Debug |
Comme ci-dessus | debug | - |
Std$Err$Info |
Comme ci-dessus | info | - |
Std$Err$Warn |
Comme ci-dessus | warn | - |
Std$Err$Error |
Comme ci-dessus | error | - |
Std$Err$Fatal |
Comme ci-dessus | fatal | - |
S'il n'est pas spécifié, Std $ Out $ Info
est sélectionné.
~~ Database est la spécification du SGBD cible et est sélectionné parmi les suivants. ~~
~~ Si vous souhaitez utiliser un SGBD autre que celui ci-dessus, ne le spécifiez pas et ne spécifiez pas «Standard». ~~
ConnectionSupplier est sélectionné parmi les éléments suivants en spécifiant le fournisseur de connexion (pool de connexions, etc.) à utiliser.
Contenu spécifié | Fournisseur de connexion |
---|---|
C3p0 | c3p0 |
Dbcp | Apache Commons DBCP |
HikariCP | HikariCP |
TomcatCP | Tomcat JDBC Connection Pool |
Jndi | Java Naming and Directory Interface (JNDI) (Pour Tomcat) |
Jdbc | DriverManager#getConnection(String url, Properties info)Méthode |
Sous le fournisseur de connexion (url ~ maxTotal) dans l'exemple de définition lightsleep.properties ci-dessus se trouve le contenu de la définition à transmettre à chaque fournisseur de connexion.
lightsleep.properties
Logger = Std$Out$Info
#Database =DB2 * version 2.1.Aboli à 0
ConnectionSupplier = Jdbc
url = jdbc:db2://db2:50000/example
lightsleep.properties
Logger = Jdk
#Database =MySQL * version 2.1.Aboli à 0
ConnectionSupplier = C3p0
url = jdbc:mysql://mysql:3306/example
user = example
password = _example_
Les définitions autres que url, utilisateur et mot de passe sont décrites dans c3p0.properties ou c3p0-config.xml.
lightsleep.properties
Logger = Log4j
#Database =Oracle * Version 2.1.Aboli à 0
ConnectionSupplier = Dbcp
url = jdbc:oracle:thin:@oracle:1521:example
username = example
password = _example_
initialSize = 10
maxTotal = 100
...
lightsleep.properties
Logger = Log4j2
#Database =PostgreSQL * version 2.1.Aboli à 0
ConnectionSupplier = HikariCP
jdbcUrl = jdbc:postgresql://postgresql:5432/example
username = example
password = _example_
minimumIdle = 10
maximumPoolSize = 100
...
lightsleep.properties
Logger = SLF4J
#Database =SQLServer * Version 2.1.Aboli à 0
ConnectionSupplier = TomcatCP
url = jdbc:sqlserver://sqlserver:1433;database=example
username = example
password = _example_
initialSize = 10
maxActive = 100
...
lightsleep.properties
Logger = Log4j
#Database =MySQL * version 2.1.Aboli à 0
ConnectionSupplier = Jndi
dataSource = jdbc/example
** (Version 2.1.0 ~) **
lightsleep.properties
#Lors de la spécification de plusieurs URL JDBC
Logger = Log4j2
ConnectionSupplier = Dbcp
urls = jdbc:postgresql://postgresql:5432/example,\
jdbc:postgresql://postgresql:5433/example
user = example
password = _example_
initialSize = 10
maxTotal = 100
** (Version 2.1.0 ~) **
lightsleep.properties
#Lors de l'utilisation de plusieurs SGBD(Spécifiez l'utilisateur et le mot de passe dans l'URL)
Logger = Log4j2
ConnectionSupplier = Dbcp
urls = \
jdbc:db2://db2:50000/example:user=example;password=_example_;,\
jdbc:mariadb://mariadb:3306/example?user=example&password=_example_,\
jdbc:mysql://mysql:3306/example?user=example&password=_example_,\
jdbc:oracle:thin:example/_example_@oracle:1521:example,\
jdbc:postgresql://postgresql:5432/example?user=example&password=_example_,\
jdbc:sqlite:C:/sqlite/example,\
jdbc:sqlserver://sqlserver:1433;database=example;user=example;password=_example_,\
<Ligne blanche>
initialSize = 10
maxTotal = 100
** (Version 2.1.0 ~) **
lightsleep.properties
#Lors de la spécification d'un fournisseur de connexion pour chaque URL
Logger = Log4j2
urls = \
[ Jdbc ]jdbc:db2://db2:50000/example:user=example;password=_example_;,\
[ C3p0 ]jdbc:mariadb://mariadb:3306/example?user=example&password=_example_,\
[ Dbcp ]jdbc:mysql://mysql:3306/example?user=example&password=_example_,\
[HikariCP]jdbc:oracle:thin:example/_example_@oracle:1521:example,\
[TomcatCP]jdbc:postgresql://postgresql:5432/example?user=example&password=_example_,\
[ Jdbc ]jdbc:sqlite:C:/sqlite/example,\
[ C3p0 ]jdbc:sqlserver://sqlserver:1433;database=example;user=example;password=_example_,\
<Ligne blanche>
# Dbcp, HikariCP, TomcatCP
initialSize = 10
# Dbcp
maxTotal = 10
# TomcatCP
maxActive = 10
# HikariCP
minimumIdle = 10
maximumPoolSize = 10
** (Version 2.1.0 ~) ** ** (PostScript du 06/12/2017) **
Dans le cas de la définition de * dataSource / dataSources, contrairement à url / urls, le mot clé qui identifie le gestionnaire de base de données n'est pas inclus (dans certains cas), de sorte que l'URL est obtenue à partir de DatabaseMetaData de l'objet Connection qui a été obtenu et jugé en premier. .. * ** (Version 2.1.1 ~) **
lightsleep.properties
#Lors de l'utilisation de Jndi
Logger = Log4j2
ConnectionSupplier = Jndi
dataSources = \
jdbc/db2_example,\
jdbc/mariadb_example,\
jdbc/mysql_example,\
jdbc/oracle_example,\
postgresql_example,\
sqlite_example,\
sqlserver_example,\
<Ligne blanche>
# ↑"jdbc/"Avec ou sans
Exécuter la méthode Transaction.execute
équivaut à exécuter une transaction.
Le contenu de la transaction est défini par l'argument transaction
(expression lambda).
L'expression lambda correspond au contenu de la méthode Transaction.executeBody
, et l'argument de cette méthode est Connection
.
Java
Contact contact = new Contact(1, "Akane", "Apple");
//Exemple de transaction
Transaction.execute(conn -> {
//Début de la transaction
new Sql<>(Contact.class).connection(conn)
.insert(contact);
...
//Fin de transaction
});
Groovy
def contact = new Contact(1, 'Akane', 'Apple')
//Exemple de transaction
Transaction.execute {
//Début de la transaction
new Sql<>(Contact).connection(it)
.insert(contact)
...
//Fin de transaction
}
Si vous avez plusieurs URL JDBC (ou sources de données) définies dans lightsleep.properties
, vous devez spécifier pour quelle URL (ou source de données) exécuter la transaction. La méthode ConnectionSupplier.find
recherche une URL (ou une source de données) qui contient le tableau de chaînes entier (arguments variables) de ses arguments.
Une exception sera levée si plus d'un est trouvé ou introuvable. ** (Version 2.1.0 ~) **
lightsleep.properties
urls = jdbc:postgresql://postgresql:5432/example1,\
jdbc:postgresql://postgresql:5432/example2,\
jdbc:postgresql://postgresql:5433/example1,\
jdbc:postgresql://postgresql:5433/example2
Java
public static final ConnectionSupplier supplier1 = ConnectionSupplier.find("5432", "example1");
public static final ConnectionSupplier supplier2 = ConnectionSupplier.find("5432", "example2");
public static final ConnectionSupplier supplier3 = ConnectionSupplier.find("5433", "example1");
public static final ConnectionSupplier supplier4 = ConnectionSupplier.find("5433", "example2");
...
Contact contact = new Contact(1, "Akane", "Apple");
//Exemple de transaction
Transaction.execute(supplier1, conn -> {
//Début de la transaction
new Sql<>(Contact.class).connection(conn)
.insert(contact);
...
//Fin de transaction
});
Groovy
static final supplier1 = ConnectionSupplier.find('5432', 'example1')
static final supplier2 = ConnectionSupplier.find('5432', 'example1')
static final supplier3 = ConnectionSupplier.find('5433', 'example1')
static final supplier4 = ConnectionSupplier.find('5433', 'example1')
...
def contact = new Contact(1, 'Akane', 'Apple')
//Exemple de transaction
Transaction.execute(supplier1) {
//Début de la transaction
new Sql<>(Contact).connection(it)
.insert(contact)
...
//Fin de transaction
}
Si une exception est levée pendant la transaction, la méthode Transaction.rollback
est exécutée et
Sinon, la méthode Transaction.commit
sera exécutée.
Voici un exemple de description en Java et Groovy et le SQL généré. Le SQL généré a des sauts de ligne pour plus de clarté, mais en réalité il n'y a pas de sauts de ligne.
3-1. SELECT
Java
Transaction.execute(conn -> {
Optional<Contact> contactOpt = new Sql<>(Contact.class)
.where("{id}={}", 1)
.connection(conn)
.select();
});
Groovy
Transaction.execute {
def contactOpt = new Sql<>(Contact)
.where('{id}={}', 1)
.connection(it)
.select()
}
SQL
SELECT id, firstName, lastName, birthday, updateCount, createdTime, updatedTime
FROM Contact
WHERE id=1
Java
Contact contact = new Contact();
contact.id = 1;
Transaction.execute(conn -> {
Optional<Contact> contactOpt = new Sql<>(Contact.class)
.where(contact)
.connection(conn)
.select();
});
Groovy
def contact = new Contact()
contact.id = 1
Transaction.execute {
def contactOpt = new Sql<>(Contact)
.where(contact)
.connection(it)
.select()
}
SQL
SELECT id, firstName, lastName, birthday, updateCount, createdTime, updatedTime
FROM Contact
WHERE id=1
Java
List<Contact> contacts = new ArrayList<Contact>();
Transaction.execute(conn ->
new Sql<>(Contact.class)
.where("{lastName}={}", "Apple")
.connection(conn)
.select(contacts::add)
);
Groovy
List<Contact> contacts = []
Transaction.execute {
new Sql<>(Contact)
.where('{lastName}={}', 'Apple')
.connection(it)
.select({contacts << it})
}
SQL
SELECT id, firstName, lastName, birthday, updateCount, createdTime, updatedTime
FROM Contact
WHERE lastName='Apple'
Java
List<Contact> contacts = new ArrayList<Contact>();
Transaction.execute(conn ->
new Sql<>(Contact.class, "C")
.where("EXISTS",
new Sql<>(Phone.class, "P")
.where("{P.contactId}={C.id}")
)
.connection(conn)
.select(contacts::add)
);
Groovy
List<Contact> contacts = []
Transaction.execute {
new Sql<>(Contact, 'C')
.where('EXISTS',
new Sql<>(Phone, 'P')
.where('{P.contactId}={C.id}')
)
.connection(it)
.select({contacts << it})
}
SQL
SELECT C.id C_id, C.firstName C_firstName, C.lastName C_lastName, C.birthday C_birthday,
C.updateCount C_updateCount, C.createdTime C_createdTime, C.updatedTime C_updatedTime
FROM Contact C
WHERE EXISTS (SELECT * FROM Phone P WHERE P.contactId=C.id)
Java
List<Contact> contacts = new ArrayList<Contact>();
Transaction.execute(conn ->
new Sql<>(Contact.class)
.where("{lastName}={}", "Apple")
.and ("{firstName}={}", "Akane")
.connection(conn)
.select(contacts::add)
);
Groovy
List<Contact> contacts = []
Transaction.execute {
new Sql<>(Contact)
.where('{lastName}={}', 'Apple')
.and ('{firstName}={}', 'Akane')
.connection(it)
.select({contacts << it})
}
SQL
SELECT id, firstName, lastName, birthday, updateCount, createdTime, updatedTime
FROM Contact
WHERE lastName='Apple' AND firstName='Akane'
Java
List<Contact> contacts = new ArrayList<Contact>();
Transaction.execute(conn ->
new Sql<>(Contact.class)
.where("{lastName}={}", "Apple")
.or ("{lastName}={}", "Orange")
.connection(conn)
.select(contacts::add)
);
Groovy
List<Contact> contacts = []
Transaction.execute {
new Sql<>(Contact)
.where('{lastName}={}', 'Apple')
.or ('{lastName}={}', 'Orange')
.connection(it)
.select({contacts << it})
}
SQL
SELECT id, firstName, lastName, birthday, updateCount, createdTime, updatedTime
FROM Contact
WHERE lastName='Apple' OR lastName='Orange'
Java
List<Contact> contacts = new ArrayList<Contact>();
Transaction.execute(conn ->
new Sql<>(Contact.class)
.where(Condition
.of ("{lastName}={}", "Apple")
.and("{firstName}={}", "Akane")
)
.or(Condition
.of ("{lastName}={}", "Orange")
.and("{firstName}={}", "Setoka")
)
.connection(conn)
.select(contacts::add)
);
Groovy
List<Contact> contacts = []
Transaction.execute(conn ->
new Sql<>(Contact)
.where(Condition
.of ('{lastName}={}', 'Apple')
.and('{firstName}={}', 'Akane')
)
.or(Condition
.of ('{lastName}={}', 'Orange')
.and('{firstName}={}', 'Setoka')
)
.connection(it)
.select({contacts << it})
);
SQL
SELECT id, firstName, lastName, birthday, updateCount, createdTime, updatedTime
FROM Contact
WHERE lastName='Apple' AND firstName='Akane'
OR lastName='Orange' AND firstName='Setoka'
Java
List<Contact> contacts = new ArrayList<Contact>();
Transaction.execute(conn ->
new Sql<>(Contact.class)
.where("{lastName}={}", "Apple")
.columns("lastName", "firstName")
.connection(conn)
.select(contacts::add)
);
Groovy
List<Contact> contacts = []
Transaction.execute {
new Sql<>(Contact)
.where('{lastName}={}', 'Apple')
.columns('lastName', 'firstName')
.connection(it)
.select({contacts << it})
}
SQL
SELECT firstName, lastName FROM Contact WHERE lastName='Apple'
3-1-9. SELECT GROUP BY, HAVING
Java
List<Contact> contacts = new ArrayList<Contact>();
Transaction.execute(conn ->
new Sql<>(Contact.class, "C")
.columns("lastName")
.groupBy("{lastName}")
.having("COUNT({lastName})>=2")
.connection(conn)
.select(contacts::add)
);
Groovy
List<Contact> contacts = []
Transaction.execute {
new Sql<>(Contact, 'C')
.columns('lastName')
.groupBy('{lastName}')
.having('COUNT({lastName})>=2')
.connection(it)
.select({contacts << it})
}
SQL
SELECT MIN(C.lastName) C_lastName
FROM Contact C
GROUP BY C.lastName
HAVING COUNT(C.lastName)>=2
3-1-10. SELECT ORDER BY, OFFSET, LIMIT
Java
List<Contact> contacts = new ArrayList<Contact>();
Transaction.execute(conn ->
new Sql<>(Contact.class)
.orderBy("{lastName}")
.orderBy("{firstName}")
.orderBy("{id}")
.offset(10).limit(5)
.connection(conn)
.select(contacts::add)
);
Groovy
List<Contact> contacts = []
Transaction.execute {
new Sql<>(Contact)
.orderBy('{lastName}')
.orderBy('{firstName}')
.orderBy('{id}')
.offset(10).limit(5)
.connection(it)
.select({contacts << it})
}
SQL
-- DB2, MariaDB, MySQL, PostgreSQL, SQLite
SELECT id, firstName, lastName, birthday, updateCount, createdTime, updatedTime
FROM Contact
ORDER BY lastName ASC, firstName ASC, id ASC
LIMIT 5 OFFSET 10
SQL
-- Oracle, SQLServer(Évitez les lignes lors de la récupération)
SELECT id, firstName, lastName, birthday, updateCount, createdTime, updatedTime
FROM Contact
ORDER BY lastName ASC, firstName ASC, id ASC
3-1-11. SELECT FOR UPDATE
Java
Transaction.execute(conn -> {
Optional<Contact> contactOpt = new Sql<>(Contact.class)
.where("{id}={}", 1)
.forUpdate()
.connection(conn)
.select();
});
Groovy
Transaction.execute {
def contactOpt = new Sql<>(Contact)
.where('{id}={}', 1)
.forUpdate()
.connection(it)
.select()
}
SQL
-- DB2
SELECT id, firstName, lastName, birthday, updateCount, createdTime, updatedTime
FROM Contact
WHERE id=1
FOR UPDATE WITH RS
SQL
-- MariaDB, MySQL, Oracle, PostgreSQL, SQLite
SELECT id, firstName, lastName, birthday, updateCount, createdTime, updatedTime
FROM Contact
WHERE id=1
FOR UPDATE
SQL
-- SQLite
--SQLite ne prend pas en charge FOR UPDATE, donc une exception UnsupportedOperationException est levée.
SQL
-- SQLServer
SELECT id, firstName, lastName, birthday, updateCount, createdTime, updatedTime
FROM Contact
WITH (ROWLOCK,UPDLOCK)
WHERE id=1
Java
List<Contact> contacts = new ArrayList<>();
List<Phone> phones = new ArrayList<>();
Transaction.execute(conn ->
new Sql<>(Contact.class, "C")
.innerJoin(Phone.class, "P", "{P.contactId}={C.id}")
.where("{C.id}={}", 1)
.connection(conn)
.<Phone>select(contacts::add, phones::add)
);
Groovy
List<Contact> contacts = []
List<Phone> phones = []
Transaction.execute {
new Sql<>(Contact, 'C')
.innerJoin(Phone, 'P', '{P.contactId}={C.id}')
.where('{C.id}={}', 1)
.connection(it)
.select({contacts << it}, {phones << it})
}
SQL
SELECT C.id C_id, C.lastName C_lastName, C.firstName C_firstName, C.birthday C_birthday,
C.updateCount C_updateCount, C.createdTime C_createdTime, C.updatedTime C_updatedTime,
P.contactId P_contactId, P.childIndex P_childIndex, P.label P_label, P.content P_content
FROM Contact C
INNER JOIN Phone P ON P.contactId=C.id WHERE C.id=1
Java
List<Contact> contacts = new ArrayList<>();
List<Phone> phones = new ArrayList<>();
Transaction.execute(conn ->
new Sql<>(Contact.class, "C")
.leftJoin(Phone.class, "P", "{P.contactId}={C.id}")
.where("{C.lastName}={}", "Apple")
.connection(conn)
.<Phone>select(contacts::add, phones::add)
);
Groovy
List<Contact> contacts = []
List<Phone> phones = []
Transaction.execute {
new Sql<>(Contact, 'C')
.leftJoin(Phone, 'P', '{P.contactId}={C.id}')
.where('{C.lastName}={}', 'Apple')
.connection(it)
.select({contacts << it}, {phones << it})
}
SQL
SELECT C.id C_id, C.lastName C_lastName, C.firstName C_firstName, C.birthday C_birthday,
C.updateCount C_updateCount, C.createdTime C_createdTime, C.updatedTime C_updatedTime,
P.contactId P_contactId, P.childIndex P_childIndex, P.label P_label, P.content P_content
FROM Contact C
LEFT OUTER JOIN Phone P ON P.contactId=C.id
WHERE C.lastName='Apple'
Java
List<Contact> contacts = new ArrayList<>();
List<Phone> phones = new ArrayList<>();
Transaction.execute(conn ->
new Sql<>(Contact.class, "C")
.rightJoin(Phone.class, "P", "{P.contactId}={C.id}")
.where("{P.label}={}", "Main")
.connection(conn)
.<Phone>select(contacts::add, phones::add)
);
Groovy
List<Contact> contacts = []
List<Phone> phones = []
Transaction.execute {
new Sql<>(Contact, 'C')
.rightJoin(Phone, 'P', '{P.contactId}={C.id}')
.where('{P.label}={}', 'Main')
.connection(it)
.select({contacts << it}, {phones << it})
}
SQL
--SQLite lève une exception car RIGHT OUTER JOIN n'est pas pris en charge.
SELECT C.id C_id, C.lastName C_lastName, C.firstName C_firstName, C.birthday C_birthday,
C.updateCount C_updateCount, C.createdTime C_createdTime, C.updatedTime C_updatedTime,
P.contactId P_contactId, P.childIndex P_childIndex, P.label P_label, P.content P_content
FROM Contact C
RIGHT OUTER JOIN Phone P ON P.contactId=C.id
WHERE P.label='Main'
3-1-15. SELECT COUNT(*)
Java
int[] rowCount = new int[1];
Transaction.execute(conn ->
count[0] = new Sql<>(Contact.class)
.where("lastName={}", "Apple")
.connection(conn)
.selectCount()
);
Groovy
def rowCount = 0
Transaction.execute {
count = new Sql<>(Contact)
.where('lastName={}', 'Apple')
.connection(it)
.selectCount()
}
SQL
SELECT COUNT(*) FROM Contact WHERE lastName='Apple'
3-2. INSERT
Java
Transaction.execute(conn ->
new Sql<>(Contact.class)
.connection(conn)
.insert(new Contact(1, "Akane", "Apple", 2001, 1, 1))
Groovy
Transaction.execute {
new Sql<>(Contact)
.connection(it)
.insert(new Contact(1, "Akane", "Apple", 2001, 1, 1))
}
SQL
-- DB2, MariaDB, MySQL, Oracle, PostgreSQL
INSERT INTO Contact
(id, firstName, lastName, birthday, updateCount, createdTime, updatedTime)
VALUES
(1, 'Apple', 'Akane', DATE'2001-01-01', 0, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)
SQL
-- SQLite
INSERT INTO Contact
(id, firstName, lastName, birthday, updateCount, createdTime, updatedTime)
VALUES
(1, 'Apple', 'Akane', '2001-01-01', 0, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)
SQL
-- SQLServer
INSERT INTO Contact
(id, firstName, lastName, birthday, updateCount, createdTime, updatedTime)
VALUES
(1, 'Apple', 'Akane', CAST('2001-01-01' AS DATE), 0, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)
Java
Transaction.execute(conn ->
new Sql<>(Contact.class)
.connection(conn)
.insert(Arrays.asList(
new Contact(2, "Yukari", "Apple", 2001, 1, 2),
new Contact(3, "Azusa", "Apple", 2001, 1, 3)
))
Groovy
Transaction.execute {
new Sql<>(Contact)
.connection(it)
.insert([
new Contact(2, "Yukari", "Apple", 2001, 1, 2),
new Contact(3, "Azusa", "Apple", 2001, 1, 3)
])
}
SQL
-- DB2, MariaDB, MySQL, Oracle, PostgreSQL
INSERT INTO Contact
(id, firstName, lastName, birthday, updateCount, createdTime, updatedTime)
VALUES
(2, 'Apple', 'Yukari', DATE'2001-01-02', 0, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)
INSERT INTO Contact
(id, firstName, lastName, birthday, updateCount, createdTime, updatedTime)
VALUES
(3, 'Apple', 'Azusa', DATE'2001-01-03', 0, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)
SQL
-- SQLite
INSERT INTO Contact (id, firstName, lastName, birthday, updateCount, createdTime, updatedTime)
VALUES
(2, 'Apple', 'Yukari', '2001-01-02', 0, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)
INSERT INTO Contact (id, firstName, lastName, birthday, updateCount, createdTime, updatedTime)
VALUES
(3, 'Apple', 'Azusa', '2001-01-03', 0, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)
SQL
-- SQLServer
INSERT INTO Contact
(id, firstName, lastName, birthday, updateCount, createdTime, updatedTime)
VALUES
(2, 'Apple', 'Yukari', CAST('2001-01-02' AS DATE), 0, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)
INSERT INTO Contact
(id, firstName, lastName, birthday, updateCount, createdTime, updatedTime)
VALUES
(3, 'Apple', 'Azusa', CAST('2001-01-03' AS DATE), 0, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)
3-3. UPDATE
Java
Transaction.execute(conn ->
new Sql<>(Contact.class)
.where("{id}={}", 1)
.connection(conn)
.select()
.ifPresent(contact -> {
contact.firstName = "Akiyo";
new Sql<>(Contact.class)
.connection(conn)
.update(contact);
})
);
Groovy
Transaction.execute {
new Sql<>(Contact)
.where('{id}={}', 1)
.connection(it)
.select()
.ifPresent {Contact contact ->
contact.firstName = 'Akiyo'
new Sql<>(Contact)
.connection(it)
.update(contact)
}
}
SQL
-- DB2, MariaDB, MySQL, Oracle, PostgreSQL
SELECT id, firstName, lastName, birthday, updateCount, createdTime, updatedTime
FROM Contact WHERE id=1
UPDATE Contact SET
lastName='Apple', firstName='Akiyo', birthday=DATE'2001-01-01',
updateCount=updateCount+1, updatedTime=CURRENT_TIMESTAMP
WHERE id=1
SQL
-- SQLite
SELECT id, firstName, lastName, birthday, updateCount, createdTime, updatedTime
FROM Contact WHERE id=1
UPDATE Contact SET
lastName='Apple', firstName='Akiyo', birthday='2001-01-01',
updateCount=updateCount+1, updatedTime=CURRENT_TIMESTAMP
WHERE id=1
SQL
-- SQLServer
SELECT id, firstName, lastName, birthday, updateCount, createdTime, updatedTime
FROM Contact WHERE id=1
UPDATE Contact SET
lastName='Apple', firstName='Akiyo', birthday=CAST('2001-01-01' AS DATE),
updateCount=updateCount+1, updatedTime=CURRENT_TIMESTAMP
WHERE id=1
Java
Transaction.execute(conn -> {
List<Contact> contacts = new ArrayList<>();
new Sql<>(Contact.class)
.where("{lastName}={}", "Apple")
.connection(conn)
.select(contact -> {
contact.lastName = "Apfel";
contacts.add(contact);
});
new Sql<>(Contact.class)
.connection(conn)
.update(contacts);
});
Groovy
Transaction.execute {
List<Contact> contacts = []
new Sql<>(Contact)
.where('{lastName}={}', 'Apple')
.connection(it)
.select({Contact contact ->
contact.lastName = 'Apfel'
contacts << contact
})
new Sql<>(Contact)
.connection(it)
.update(contacts)
}
SQL
-- DB2, MariaDB, MySQL, Oracle, PostgreSQL
SELECT id, firstName, lastName, birthday, updateCount, createdTime, updatedTime
FROM Contact WHERE lastName='Apple'
UPDATE Contact SET
firstName='Akiyo', lastName='Apfel', birthday=DATE'2001-01-01',
updateCount=updateCount+1, updatedTime=CURRENT_TIMESTAMP
WHERE id=1
UPDATE Contact SET
firstName='Yukari', lastName='Apfel', birthday=DATE'2001-01-02',
updateCount=updateCount+1, updatedTime=CURRENT_TIMESTAMP
WHERE id=2
UPDATE Contact SET
firstName='Azusa', lastName='Apfel', birthday=DATE'2001-01-03',
updateCount=updateCount+1, updatedTime=CURRENT_TIMESTAMP
WHERE id=3
SQL
-- SQLite
SELECT id, firstName, lastName, birthday, updateCount, createdTime, updatedTime
FROM Contact WHERE lastName='Apple'
UPDATE Contact SET
firstName='Akiyo', lastName='Apfel', birthday='2001-01-01',
updateCount=updateCount+1, updatedTime=CURRENT_TIMESTAMP
WHERE id=1
UPDATE Contact SET
firstName='Yukari', lastName='Apfel', birthday='2001-01-02',
updateCount=updateCount+1, updatedTime=CURRENT_TIMESTAMP
WHERE id=2
UPDATE Contact SET
firstName='Azusa', lastName='Apfel', birthday='2001-01-03',
updateCount=updateCount+1, updatedTime=CURRENT_TIMESTAMP
WHERE id=3
SQL
-- SQLServer
SELECT id, firstName, lastName, birthday, updateCount, createdTime, updatedTime
FROM Contact WHERE lastName='Apple'
UPDATE Contact SET
firstName='Akiyo', lastName='Apfel', birthday=CAST('2001-01-01' AS DATE),
updateCount=updateCount+1, updatedTime=CURRENT_TIMESTAMP
WHERE id=1
UPDATE Contact SET
firstName='Yukari', lastName='Apfel', birthday=CAST('2001-01-02' AS DATE),
updateCount=updateCount+1, updatedTime=CURRENT_TIMESTAMP
WHERE id=2
UPDATE Contact SET
firstName='Azusa', lastName='Apfel', birthday=CAST('2001-01-03' AS DATE),
updateCount=updateCount+1, updatedTime=CURRENT_TIMESTAMP
WHERE id=3
Java
Contact contact = new Contact();
contact.lastName = "Pomme";
Transaction.execute(conn ->
new Sql<>(Contact.class)
.where("{lastName}={}", "Apfel")
.columns("lastName")
.connection(conn)
.update(contact)
);
Groovy
def contact = new Contact()
contact.lastName = 'Pomme'
Transaction.execute {
new Sql<>(Contact)
.where('{lastName}={}', 'Apfel')
.columns('lastName')
.connection(it)
.update(contact)
}
SQL
UPDATE Contact SET lastName='Pomme' WHERE lastName='Apfel'
Java
Contact contact = new Contact();
Transaction.execute(conn ->
new Sql<>(Contact.class)
.where(Condition.ALL)
.columns("birthday")
.connection(conn)
.update(contact)
);
Groovy
def contact = new Contact()
Transaction.execute {
new Sql<>(Contact)
.where(Condition.ALL)
.columns('birthday')
.connection(it)
.update(contact)
}
SQL
UPDATE Contact SET birthday=NULL
3-4. DELETE
Java
Transaction.execute(conn ->
new Sql<>(Contact.class)
.where("{id}={}", 1)
.connection(conn)
.select()
.ifPresent(contact ->
new Sql<>(Contact.class)
.connection(conn)
.delete(contact))
);
Groovy
Transaction.execute {
new Sql<>(Contact)
.where('{id}={}', 1)
.connection(it)
.select()
.ifPresent {contact ->
new Sql<>(Contact)
.connection(it)
.delete(contact)
}
}
SQL
SELECT id, firstName, lastName, birthday, updateCount, createdTime, updatedTime
FROM Contact WHERE id=1
DELETE FROM Contact WHERE id=1
Java
Transaction.execute(conn -> {
List<Contact> contacts = new ArrayList<>();
new Sql<>(Contact.class)
.where("{lastName}={}", "Pomme")
.connection(conn)
.select(contacts::add);
new Sql<>(Contact.class)
.connection(conn)
.delete(contacts);
});
Groovy
Transaction.execute {
List<Contact> contacts = []
new Sql<>(Contact)
.where('{lastName}={}', 'Pomme')
.connection(it)
.select({contacts << it})
new Sql<>(Contact)
.connection(it)
.delete(contacts)
}
SQL
SELECT id, firstName, lastName, birthday, updateCount, createdTime, updatedTime
FROM Contact WHERE lastName='Pomme'
DELETE FROM Contact WHERE id=2
DELETE FROM Contact WHERE id=3
Java
Transaction.execute(conn ->
new Sql<>(Contact.class)
.where("{lastName}={}", "Orange")
.connection(conn)
.delete()
);
Groovy
Transaction.execute {
new Sql<>(Contact)
.where('{lastName}={}', 'Orange')
.connection(it)
.delete()
}
SQL
DELETE FROM Contact WHERE lastName='Orange'
Java
Transaction.execute(conn ->
new Sql<>(Phone.class)
.where(Condition.ALL)
.connection(conn)
.delete()
);
Groovy
Transaction.execute {
new Sql<>(Phone)
.where(Condition.ALL)
.connection(it)
.delete()
}
SQL
DELETE FROM Phone
Recommended Posts