Ich wollte die Implementierung von Mybatis und Hibernate (nur grundlegende CRUD-Verarbeitung) vergleichen, also habe ich es ein wenig versucht. Ich benutze Spring Boot für die Basis FW.
Wir fügen die erforderlichen Abhängigkeiten im Spring-Starter-Projekt hinzu. Es ist wirklich einfach, weil Sie es einfach mit der STS-GUI überprüfen.
DB Ich habe Postgres benutzt. Unten von der DB-Erstellung bis zum Testen der Daten INSERT.
Eingabeaufforderung
postgres=# create database test01;← test01 Datenbank erstellen
postgres=# \l
Datenbankliste
Name|Inhaber|Codierung|Kollation| Ctype(Konvertierungsoperator) |Zugriffsrecht
-------------+----------+------------------+--------------------+--------------------+-----------------------
postgres | postgres | UTF8 | Japanese_Japan.932 | Japanese_Japan.932 |
test01 | postgres | UTF8 | Japanese_Japan.932 | Japanese_Japan.932 |
(Unten weggelassen)
postgres=# \c test01 ← Wählen Sie die Datenbank test01 aus
Datenbank"test01"An den Benutzer"postgres"Verbunden als.
test01=# create table emp (id integer,department character varying(10), name character varying(30));
CREATE TABLE
test01=# \d emp
Tabelle"public.emp"
Säule|Schimmel|Modifikator
------------+-----------------------+--------
id | integer |
department | character varying(10) |
name | character varying(30) |
test01=# insert into emp values(101,'Personalabteilung','Nico');
INSERT 0 1
(~ Ausgelassen ~)
test01=# select * from emp;
id | department | name
-----+------------+------------
101 |Personalabteilung|Nico
102 |Entwicklungsabteilung|Dante
103 |Entwicklungsabteilung|Nero
104 |Abteilung Allgemeine Angelegenheiten|Trish
105 |Entwicklungsabteilung|Vergil
(5 Zeilen)
test01=# ALTER TABLE emp ADD PRIMARY KEY(id);
ALTER TABLE
test01=#
POM Es werden nur Abhängigkeiten extrahiert.
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>
Bei Mybatis handelte es sich nur um Eigenschaften, die sich auf Verbindungsinformationen beziehen.
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
#SQL-Protokoll ausgeben
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, "Personalabteilung", "Dame");
mapper.insert(insEmp);
System.out.println(mapper.select(106));
// update
System.out.println("### update ###");
Emp updEmp = new Emp(106, "Buchhaltung", 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 Es ist mit der SQL-ID verknüpft, die in der später beschriebenen Mapper-XML definiert ist. Wenn es sich jedoch um einfaches SQL handelt, können Sie die Anmerkung ausfüllen, ohne XML vorzubereiten. In diesem Beispiel wird SQL durch eine Anmerkung für selectAll definiert.
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 Die folgenden Anmerkungen sind alle Lombok, sodass im Fall von Mybatis keine Anmerkungen für die Entitätsklasse erforderlich sind.
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 Es ist mit dem Methodennamen und der ID der Mapper-Schnittstelle verknüpft.
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>
Da das SQL-Protokoll in den Eigenschaften festgelegt ist, werden auch SQL und Parameter ausgegeben.
Konsole
### 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=Personalabteilung, name=Nico)
Emp(id=102, department=Entwicklungsabteilung, name=Dante)
Emp(id=103, department=Entwicklungsabteilung, name=Nero)
Emp(id=104, department=Abteilung Allgemeine Angelegenheiten, name=Trish)
Emp(id=105, department=Entwicklungsabteilung, name=Vergil)
### 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),Personalabteilung(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=Personalabteilung, 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:Buchhaltung(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=Buchhaltung, 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 Es werden nur Abhängigkeiten extrahiert. Der einzige Unterschied zu den oben genannten Mybatis ist die Abhängigkeit "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
#SQL-Protokoll ausgeben
logging.level.org.hibernate.SQL=debug
logging.level.org.hibernate.type.descriptor.sql.BasicBinder=trace
logging.level.org.hibernate.EnumType=trace
Im Ruhezustand ist es besser, hibernate.properties hinzuzufügen, um zu verhindern, dass zusätzlich zu den Verbindungsinformationen unnötige Protokolle ausgegeben werden.
hibernate.properties
hibernate.jdbc.lob.non_contextual_creation=true
Wenn Sie hibernate.properties oben nicht festlegen, wird der folgende Fehler protokolliert, wenn Sie die Spring-Boot-App starten. (Kann ausgeführt werden)
Konsole
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]
~~ weggelassen ~~
at jp.demo.HibernateApplication.main(HibernateApplication.java:11) [classes/:na]
Caused by: java.sql.SQLFeatureNotSupportedException: org.postgresql.jdbc.PgConnection.createClob()Die Methode wurde noch nicht implementiert.
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, "Personalabteilung", "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 und UPDATE scheinen in CrudRepository.save () gruppiert zu sein. Was das Trennen betrifft, so scheint es, dass die Datenextraktion vor dem Aktualisieren zuerst mit dem Attribut durchgeführt wird, für das die ID-Annotation in der später beschriebenen Entitätsklasse angegeben ist, UPDATE, falls vorhanden, und INSERT, wenn sie nicht vorhanden ist. Die Verwendung von CrudRepository.save () bietet Ihnen die folgenden Vorteile, anstatt dass Sie Ihr eigenes SQL schreiben müssen.
Es gibt möglicherweise keine Hilfe für 1., aber es scheint, dass 2. so gesteuert werden kann, dass SELECT nicht durch Einstellung ausgegeben wird. Oder besser gesagt, ich möchte, dass Sie dazu in der Lage sind. ..
Repository Keine Methodendefinition erforderlich. Es ist erstaunlich, weil es kein SQL erfordert. Wie ich im obigen Service geschrieben habe, scheint die Verwendung von JpaRepository den Freiheitsgrad jedoch erheblich zu verringern.
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 Im Fall von Mybatis war keine Anmerkung erforderlich, aber da Hibernate JPA verwendet, Verschiedene JPA-Anmerkungen werden hinzugefügt.
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;
}
Dies wird ebenfalls protokolliert. Wie in Service geschrieben, wählen Sie im Fall von INSERT vorab aus, um zu beurteilen, ob es sich um INSERT oder UPDATE handelt. Im Fall von UPDATE wird zusätzlich zu SELECT zur Beurteilung ein SELECT zum Erfassen anderer Spalten als der Aktualisierungsspalte ausgegeben.
Konsole
### 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=Personalabteilung, name=Nico)
Emp(id=102, department=Entwicklungsabteilung, name=Dante)
Emp(id=103, department=Entwicklungsabteilung, name=Nero)
Emp(id=104, department=Abteilung Allgemeine Angelegenheiten, name=Trish)
Emp(id=105, department=Entwicklungsabteilung, name=Vergil)
### 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] - [Personalabteilung]
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=Personalabteilung, 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] - [Buchhaltung]
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=Buchhaltung, 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 ** Ich kann die Größe (Schrecklichkeit) des Ruhezustands verstehen, indem ich eine Kombination vorbereite. .. Also werde ich es beim nächsten Mal in dem Fall mit Bindung versuchen. Ich muss auch HQL ausprobieren. .. Übrigens, was ich an dieser Stelle gedacht habe ↓
Mybatis
Hibernate