Je voulais comparer l'implémentation de Mybatis et Hibernate (uniquement le traitement CRUD de base), alors je l'ai essayé un peu. J'utilise Spring Boot pour le FW de base.
Ajout des dépendances requises dans le projet Spring Starter. C'est vraiment facile car il suffit de le vérifier avec l'interface graphique STS.
DB J'ai utilisé Postgres. Ci-dessous, de la création de la base de données aux données de test INSERT.
invite de commande
postgres=# create database test01;← test01 Créer une base de données
postgres=# \l
Liste de base de données
Nom|propriétaire|codage|Collation| Ctype(Opérateur de conversion) |Droit d'accès
-------------+----------+------------------+--------------------+--------------------+-----------------------
postgres | postgres | UTF8 | Japanese_Japan.932 | Japanese_Japan.932 |
test01 | postgres | UTF8 | Japanese_Japan.932 | Japanese_Japan.932 |
(Omis ci-dessous)
postgres=# \c test01 ← Sélectionnez la base de données test01
Base de données"test01"À l'utilisateur"postgres"Connecté en tant que.
test01=# create table emp (id integer,department character varying(10), name character varying(30));
CREATE TABLE
test01=# \d emp
table"public.emp"
Colonne|Moule|Modificateur
------------+-----------------------+--------
id | integer |
department | character varying(10) |
name | character varying(30) |
test01=# insert into emp values(101,'Département des Ressources Humaines','Nico');
INSERT 0 1
(~ Omis ~)
test01=# select * from emp;
id | department | name
-----+------------+------------
101 |Département des Ressources Humaines|Nico
102 |Département de développement|Dante
103 |Département de développement|Néron
104 |Département des affaires générales|Trish
105 |Département de développement|Virgile
(5 lignes)
test01=# ALTER TABLE emp ADD PRIMARY KEY(id);
ALTER TABLE
test01=#
POM Seules les dépendances sont extraites.
pom.xml
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-batch</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.batch</groupId>
<artifactId>spring-batch-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
Dans le cas de Mybatis, il s'agissait uniquement de propriétés liées aux informations de connexion.
application.properties
spring.datasource.driver-class-name=org.postgresql.Driver
spring.datasource.url=jdbc:postgresql://localhost:5432/test01
spring.datasource.username=postgres
spring.datasource.password=postgres
#Journal SQL de sortie
logging.level.jp.demo.mapper.EmpMapper=DEBUG
SpringBootApplication
MybatisApplication.java
package jp.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
@SpringBootApplication
public class MybatisApplication {
public static void main(String[] args) {
try(ConfigurableApplicationContext ctx = SpringApplication.run(MybatisApplication.class, args)){
DemoService app = ctx.getBean(DemoService.class);
app.execute(args);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Service
DemoService.java
package jp.demo;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import jp.demo.domain.Emp;
import jp.demo.mapper.EmpMapper;
@Service
public class DemoService {
@Autowired
private EmpMapper mapper;
public void execute(String[] args) {
// select all
System.out.println("### select all ###");
List<Emp> list = mapper.selectAll();
list.forEach(System.out::println);
// insert
System.out.println("### insert ###");
Emp insEmp = new Emp(106, "Département des Ressources Humaines", "Dame");
mapper.insert(insEmp);
System.out.println(mapper.select(106));
// update
System.out.println("### update ###");
Emp updEmp = new Emp(106, "Service de la comptabilité", null);
mapper.update(updEmp);
System.out.println(mapper.select(106));
// delete
System.out.println("### delete ###");
mapper.delete(106);
System.out.println(mapper.select(106));
}
}
Mapper Il est lié à l'ID SQL défini dans le mappeur XML décrit plus loin. Cependant, s'il s'agit de SQL simple, vous pouvez remplir l'annotation sans préparer XML. Dans cet exemple, SQL est défini par une annotation pour selectAll.
EmpMapper.java
package jp.demo.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import jp.demo.domain.Emp;
@Mapper
public interface EmpMapper {
@Select("select id,department,name from emp")
List<Emp> selectAll();
Emp select(int id);
void insert(Emp emp);
void update(Emp emp);
void delete(int id);
}
Entity Les annotations suivantes sont toutes Lombok, donc dans le cas de Mybatis, aucune annotation n'est requise pour la classe Entity.
EmpMapper.java
package jp.demo.domain;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Emp {
private int id;
private String department;
private String name;
}
Mapper.xml Il est lié au nom de la méthode et à l'ID de l'interface du mappeur.
EmpMapper.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">
<mapper namespace="jp.demo.mapper.EmpMapper">
<resultMap id="empResultMap" type="jp.demo.domain.Emp">
<result property="id" column="id" />
<result property="department" column="department" />
<result property="name" column="name" />
</resultMap>
<select id="select" resultMap="empResultMap">
select id,department,name from emp
where id=#{id};
</select>
<update id="update" parameterType="jp.demo.domain.Emp">
update emp
set department=#{department}
where id=#{id};
</update>
<insert id="insert" parameterType="jp.demo.domain.Emp">
insert into emp
values (#{id},#{department},#{name});
</insert>
<delete id="delete">
delete from emp where id=#{id};
</delete>
</mapper>
Étant donné que le journal SQL est défini dans les propriétés, SQL et les paramètres sont également générés.
console
### select all ###
2019-08-08 02:22:04.214 INFO 12776 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting...
2019-08-08 02:22:04.539 INFO 12776 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed.
2019-08-08 02:22:04.553 DEBUG 12776 --- [ main] jp.demo.mapper.EmpMapper.selectAll : ==> Preparing: select id,department,name from emp
2019-08-08 02:22:04.585 DEBUG 12776 --- [ main] jp.demo.mapper.EmpMapper.selectAll : ==> Parameters:
2019-08-08 02:22:04.628 DEBUG 12776 --- [ main] jp.demo.mapper.EmpMapper.selectAll : <== Total: 5
Emp(id=101, department=Département des Ressources Humaines, name=Nico)
Emp(id=102, department=Département de développement, name=Dante)
Emp(id=103, department=Département de développement, name=Néron)
Emp(id=104, department=Département des affaires générales, name=Trish)
Emp(id=105, department=Département de développement, name=Virgile)
### insert ###
2019-08-08 02:22:04.645 DEBUG 12776 --- [ main] jp.demo.mapper.EmpMapper.insert : ==> Preparing: insert into emp values (?,?,?);
2019-08-08 02:22:04.648 DEBUG 12776 --- [ main] jp.demo.mapper.EmpMapper.insert : ==> Parameters: 106(Integer),Département des Ressources Humaines(String),Dame(String)
2019-08-08 02:22:04.686 DEBUG 12776 --- [ main] jp.demo.mapper.EmpMapper.insert : <== Updates: 1
2019-08-08 02:22:04.687 DEBUG 12776 --- [ main] jp.demo.mapper.EmpMapper.select : ==> Preparing: select id,department,name from emp where id=?;
2019-08-08 02:22:04.688 DEBUG 12776 --- [ main] jp.demo.mapper.EmpMapper.select : ==> Parameters: 106(Integer)
2019-08-08 02:22:04.690 DEBUG 12776 --- [ main] jp.demo.mapper.EmpMapper.select : <== Total: 1
Emp(id=106, department=Département des Ressources Humaines, name=Dame)
### update ###
2019-08-08 02:22:04.691 DEBUG 12776 --- [ main] jp.demo.mapper.EmpMapper.update : ==> Preparing: update emp set department=? where id=?;
2019-08-08 02:22:04.691 DEBUG 12776 --- [ main] jp.demo.mapper.EmpMapper.update : ==> Parameters:Service de la comptabilité(String), 106(Integer)
2019-08-08 02:22:04.701 DEBUG 12776 --- [ main] jp.demo.mapper.EmpMapper.update : <== Updates: 1
2019-08-08 02:22:04.702 DEBUG 12776 --- [ main] jp.demo.mapper.EmpMapper.select : ==> Preparing: select id,department,name from emp where id=?;
2019-08-08 02:22:04.702 DEBUG 12776 --- [ main] jp.demo.mapper.EmpMapper.select : ==> Parameters: 106(Integer)
2019-08-08 02:22:04.704 DEBUG 12776 --- [ main] jp.demo.mapper.EmpMapper.select : <== Total: 1
Emp(id=106, department=Service de la comptabilité, name=Dame)
### delete ###
2019-08-08 02:22:04.705 DEBUG 12776 --- [ main] jp.demo.mapper.EmpMapper.delete : ==> Preparing: delete from emp where id=?;
2019-08-08 02:22:04.706 DEBUG 12776 --- [ main] jp.demo.mapper.EmpMapper.delete : ==> Parameters: 106(Integer)
2019-08-08 02:22:04.708 DEBUG 12776 --- [ main] jp.demo.mapper.EmpMapper.delete : <== Updates: 1
2019-08-08 02:22:04.708 DEBUG 12776 --- [ main] jp.demo.mapper.EmpMapper.select : ==> Preparing: select id,department,name from emp where id=?;
2019-08-08 02:22:04.709 DEBUG 12776 --- [ main] jp.demo.mapper.EmpMapper.select : ==> Parameters: 106(Integer)
2019-08-08 02:22:04.710 DEBUG 12776 --- [ main] jp.demo.mapper.EmpMapper.select : <== Total: 0
null
POM Seules les dépendances sont extraites. La seule différence avec Mybatis ci-dessus est la dépendance "mybatis-spring-boot-starter".
pom.xml
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-batch</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.0</version>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.batch</groupId>
<artifactId>spring-batch-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
application.properties
spring.datasource.driver-class-name=org.postgresql.Driver
spring.datasource.url=jdbc:postgresql://localhost:5432/test01
spring.datasource.username=postgres
spring.datasource.password=postgres
#Journal SQL de sortie
logging.level.org.hibernate.SQL=debug
logging.level.org.hibernate.type.descriptor.sql.BasicBinder=trace
logging.level.org.hibernate.EnumType=trace
Dans le cas d'Hibernate, il semble préférable d'ajouter hibernate.properties pour éviter que des journaux inutiles ne soient générés en plus des informations de connexion.
hibernate.properties
hibernate.jdbc.lob.non_contextual_creation=true
Si vous ne définissez pas hibernate.properties ci-dessus, l'erreur suivante sera enregistrée lorsque vous démarrez l'application Spring Boot. (Peut être exécuté)
console
java.lang.reflect.InvocationTargetException: null
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_25]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_25]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_25]
at java.lang.reflect.Method.invoke(Method.java:483) ~[na:1.8.0_25]
~~ Omis ~~
at jp.demo.HibernateApplication.main(HibernateApplication.java:11) [classes/:na]
Caused by: java.sql.SQLFeatureNotSupportedException: org.postgresql.jdbc.PgConnection.createClob()La méthode n'a pas encore été mise en œuvre.
at org.postgresql.Driver.notImplemented(Driver.java:688) ~[postgresql-42.2.5.jar:42.2.5]
at org.postgresql.jdbc.PgConnection.createClob(PgConnection.java:1269) ~[postgresql-42.2.5.jar:42.2.5]
... 44 common frames omitted
SpringBootApplication
HibernateApplication.java
package jp.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
@SpringBootApplication
public class HibernateApplication {
public static void main(String[] args) {
try(ConfigurableApplicationContext ctx = SpringApplication.run(HibernateApplication.class, args)){
DemoService app = ctx.getBean(DemoService.class);
app.execute(args);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Service
DemoService.java
package jp.demo;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import jp.demo.domain.Emp;
import jp.demo.domain.EmpRepository;
@Service
public class DemoService {
@Autowired
EmpRepository repository;
public void execute(String[] args) {
// select all
System.out.println("### select all ###");
List<Emp> list = repository.findAll();
list.forEach(System.out::println);
// insert
System.out.println("### insert ###");
Emp insEmp = new Emp(106, "Département des Ressources Humaines", "Dame");
repository.save(insEmp);
System.out.println(repository.findById(106).get());
// update
System.out.println("### update ###");
Emp updEmp = repository.findById(106).get();
repository.save(updEmp);
System.out.println(repository.findById(106).get());
// delete
System.out.println("### delete ###");
repository.deleteById(106);
System.out.println(repository.findById(106).isPresent());
}
}
INSERT et UPDATE semblent être regroupés dans CrudRepository.save (). Quant à la façon de la séparer, avant la mise à jour, il semble que l'extraction des données soit d'abord effectuée avec l'attribut auquel l'annotation d'ID est donnée dans la classe d'entité décrite plus loin, UPDATE si elle existe et INSERT si elle n'existe pas. Ainsi, l'utilisation de CrudRepository.save () vous donne les avantages suivants au lieu d'avoir à écrire votre propre SQL.
Étant donné que tous les attributs doivent être mis à jour, il est nécessaire de SELECTIONNER l'enregistrement actuel, puis de transmettre l'entité avec les colonnes requises réécrites à la méthode de sauvegarde.
SELECT est automatiquement exécuté à l'avance pour séparer INSERT et UPDATE.
peut être impuissant, mais 2. semble être en mesure de contrôler de ne pas émettre SELECT en définissant? Ou plutôt, je veux que vous puissiez le faire. ..
Repository Aucune définition de méthode requise. C'est incroyable car il ne nécessite pas SQL. Cependant, il semble que le degré de liberté soit considérablement réduit si vous utilisez simplement JpaRepository comme décrit dans le service ci-dessus.
EmpRepository.java
package jp.demo.domain;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface EmpRepository extends JpaRepository<Emp, Integer> {
}
Entity Dans le cas de Mybatis, aucune annotation n'était requise, mais comme Hibernate utilise JPA, Diverses annotations JPA sont ajoutées.
Emp.java
package jp.demo.domain;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(name="emp")
public class Emp {
@Id
@Column(name="id")
private int id;
@Column(name="department")
private String department;
@Column(name="name")
private String name;
}
Ceci est également enregistré. Comme écrit dans Service, dans le cas de INSERT, pré-SELECT pour juger s'il s'agit de INSERT ou UPDATE, Dans le cas de UPDATE, en plus du SELECT pour le jugement, un SELECT pour acquérir des colonnes autres que la colonne de mise à jour est émis.
console
### select all ###
2019-08-08 01:13:02.862 INFO 10828 --- [ main] o.h.h.i.QueryTranslatorFactoryInitiator : HHH000397: Using ASTQueryTranslatorFactory
2019-08-08 01:13:03.146 DEBUG 10828 --- [ main] org.hibernate.SQL : select emp0_.id as id1_0_, emp0_.department as departme2_0_, emp0_.name as name3_0_ from emp emp0_
Emp(id=101, department=Département des Ressources Humaines, name=Nico)
Emp(id=102, department=Département de développement, name=Dante)
Emp(id=103, department=Département de développement, name=Néron)
Emp(id=104, department=Département des affaires générales, name=Trish)
Emp(id=105, department=Département de développement, name=Virgile)
### insert ###
2019-08-08 01:13:03.206 DEBUG 10828 --- [ main] org.hibernate.SQL : select emp0_.id as id1_0_0_, emp0_.department as departme2_0_0_, emp0_.name as name3_0_0_ from emp emp0_ where emp0_.id=?
2019-08-08 01:13:03.225 TRACE 10828 --- [ main] o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [INTEGER] - [106]
2019-08-08 01:13:03.285 DEBUG 10828 --- [ main] org.hibernate.SQL : insert into emp (department, name, id) values (?, ?, ?)
2019-08-08 01:13:03.286 TRACE 10828 --- [ main] o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [VARCHAR] - [Département des Ressources Humaines]
2019-08-08 01:13:03.286 TRACE 10828 --- [ main] o.h.type.descriptor.sql.BasicBinder : binding parameter [2] as [VARCHAR] - [Dame]
2019-08-08 01:13:03.287 TRACE 10828 --- [ main] o.h.type.descriptor.sql.BasicBinder : binding parameter [3] as [INTEGER] - [106]
2019-08-08 01:13:03.314 DEBUG 10828 --- [ main] org.hibernate.SQL : select emp0_.id as id1_0_0_, emp0_.department as departme2_0_0_, emp0_.name as name3_0_0_ from emp emp0_ where emp0_.id=?
2019-08-08 01:13:03.315 TRACE 10828 --- [ main] o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [INTEGER] - [106]
Emp(id=106, department=Département des Ressources Humaines, name=Dame)
### update ###
2019-08-08 01:13:03.338 DEBUG 10828 --- [ main] org.hibernate.SQL : select emp0_.id as id1_0_0_, emp0_.department as departme2_0_0_, emp0_.name as name3_0_0_ from emp emp0_ where emp0_.id=?
2019-08-08 01:13:03.339 TRACE 10828 --- [ main] o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [INTEGER] - [106]
2019-08-08 01:13:03.343 DEBUG 10828 --- [ main] org.hibernate.SQL : select emp0_.id as id1_0_0_, emp0_.department as departme2_0_0_, emp0_.name as name3_0_0_ from emp emp0_ where emp0_.id=?
2019-08-08 01:13:03.344 TRACE 10828 --- [ main] o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [INTEGER] - [106]
2019-08-08 01:13:03.348 DEBUG 10828 --- [ main] org.hibernate.SQL : update emp set department=?, name=? where id=?
2019-08-08 01:13:03.348 TRACE 10828 --- [ main] o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [VARCHAR] - [Service de la comptabilité]
2019-08-08 01:13:03.349 TRACE 10828 --- [ main] o.h.type.descriptor.sql.BasicBinder : binding parameter [2] as [VARCHAR] - [Dame]
2019-08-08 01:13:03.349 TRACE 10828 --- [ main] o.h.type.descriptor.sql.BasicBinder : binding parameter [3] as [INTEGER] - [106]
2019-08-08 01:13:03.354 DEBUG 10828 --- [ main] org.hibernate.SQL : select emp0_.id as id1_0_0_, emp0_.department as departme2_0_0_, emp0_.name as name3_0_0_ from emp emp0_ where emp0_.id=?
2019-08-08 01:13:03.354 TRACE 10828 --- [ main] o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [INTEGER] - [106]
Emp(id=106, department=Service de la comptabilité, name=Dame)
### delete ###
2019-08-08 01:13:03.359 DEBUG 10828 --- [ main] org.hibernate.SQL : select emp0_.id as id1_0_0_, emp0_.department as departme2_0_0_, emp0_.name as name3_0_0_ from emp emp0_ where emp0_.id=?
2019-08-08 01:13:03.359 TRACE 10828 --- [ main] o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [INTEGER] - [106]
2019-08-08 01:13:03.371 DEBUG 10828 --- [ main] org.hibernate.SQL : delete from emp where id=?
2019-08-08 01:13:03.371 TRACE 10828 --- [ main] o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [INTEGER] - [106]
2019-08-08 01:13:03.376 DEBUG 10828 --- [ main] org.hibernate.SQL : select emp0_.id as id1_0_0_, emp0_.department as departme2_0_0_, emp0_.name as name3_0_0_ from emp emp0_ where emp0_.id=?
2019-08-08 01:13:03.376 TRACE 10828 --- [ main] o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [INTEGER] - [106]
false
** ManyToOne ** Je peux comprendre la grandeur (terriblesse) d'Hibernate en préparant une combinaison. .. Alors la prochaine fois, je vais l'essayer dans le cas de la reliure. Je dois aussi essayer HQL. .. Au fait, ce que je pensais à ce stade ↓
Mybatis
--Parce qu'il est nécessaire d'implémenter SQL, il est clair ce qui est extrait / mis à jour —— Etudier également SQL
Hibernate
--Beaucoup de paramètres et compliqués --Je ne peux pas étudier SQL
Recommended Posts