Présentation de Lightsleep, une bibliothèque de mappage O / R qui fonctionne uniquement avec les pilotes Java Runtime et JDBC

Lightsleep est une bibliothèque de mappage O / R (Object-Relational) légère disponible dans Java 8 et supérieur.

Journal des modifications

--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)

Fonctionnalité

--API utilisant des fonctionnalités ajoutées dans Java 8 (interface fonctionnelle, classe facultative).

Lien

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
}

comment utiliser

1. Création d'une classe d'entité

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.

2. Définition de lightsleep.properties

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.

Exemple de définition (Std $ Out $ Info / DB2 / Jdbc):

lightsleep.properties


Logger    = Std$Out$Info
#Database =DB2 * version 2.1.Aboli à 0
ConnectionSupplier = Jdbc
url       = jdbc:db2://db2:50000/example

Exemple de définition (Jdk / MySQL / C3p0):

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.

Exemple de définition (Log4j / Oracle / Dbcp):

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
   ...

Exemple de définition (Log4j2 / PostgreSQL / HikariCP):

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
   ...

Exemple de définition (SLF4J / SQLServer / TomcatCP):

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
   ...

Exemple de définition (Log4j / MySQL / Jndi):

lightsleep.properties


Logger             = Log4j
#Database           =MySQL * version 2.1.Aboli à 0
ConnectionSupplier = Jndi
dataSource         = jdbc/example

Exemple de définition de plusieurs URL JDBC 1

** (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

Exemple de définition de plusieurs URL JDBC 2

** (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

Exemple de définition de plusieurs URL JDBC 3

** (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

Exemple de définition de plusieurs sources de données 4

** (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

3. Accès à la base de données

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

3-1-1. SELECT 1 ligne / condition d'expression

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

3-1-2. SELECT 1 ligne / condition d'entité

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

3-1-3. SELECT plusieurs lignes / conditions d'expression

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'

3-1-4. Condition de sous-requête SELECT

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)

3-1-5. SELECT condition d'expression / AND

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'

3-1-6. SELECT condition d'expression / OU

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'

3-1-7. SELECT condition d'expression / (A ET B) OU (C ET D)

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'

3-1-8. Sélection de colonne SELECT

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

3-1-12. SELECT jointure interne

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

3-1-13. SELECT jointure externe gauche

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'

3-1-14. SELECT jointure externe droite

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

3-2-1. INSÉRER 1 ligne

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)

3-2-2. INSÉRER plusieurs lignes

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

3-3-1. UPDATE 1 ligne

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

3-3-2. MISE À JOUR Plusieurs lignes

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

3-3-3. Condition de spécification UPDATE, sélection de colonne

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'

3-3-4. UPDATE Toutes les lignes

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

3-4-1. SUPPRIMER 1 ligne

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

3-4-2. SUPPRIMER Plusieurs lignes

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

3-4-3. Condition de spécification DELETE

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'

3-4-4. SUPPRIMER toutes les lignes

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

Présentation de Lightsleep, une bibliothèque de mappage O / R qui fonctionne uniquement avec les pilotes Java Runtime et JDBC
Mécanisme de conversion de type de données flexible de la bibliothèque de mappage O / R Lightsleep pour Java 8
Utilisez JDBC avec Java et Scala.
[À propos de JDBC qui connecte Java et SQL]
Problèmes et solutions de contournement qui créent un runtime anormalement volumineux avec jlink dans openjdk