最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Mybatis與Jpa的區(qū)別和性能對(duì)比總結(jié)

 更新時(shí)間:2021年06月23日 09:52:07   作者:Kakki  
mybatis和jpa兩個(gè)持久層框架,從底層到用法都不同,但是實(shí)現(xiàn)的功能是一樣的,所以說一直以來頗有爭議,所以下面這篇文章主要給大家介紹了關(guān)于Mybatis與Jpa的區(qū)別和性能對(duì)比的相關(guān)資料,需要的朋友可以參考下

前言

這幾天聽朋友說JPA很好用,根本不用寫sql。我在想一個(gè)程序員不寫sql還能叫程序員?而且越高級(jí)的工具封裝越多的工具,可拓展性和效率就非常的低,況且我本身非常不喜歡過于封裝的東西,平時(shí)喜歡手寫sql,所以一直都是用mybatis去寫業(yè)務(wù)。然后發(fā)現(xiàn)jpa的saveAll()批量插入批量更新速度太慢了,導(dǎo)致一些用excel導(dǎo)入的一些東西非常慢,弄得原本同步可以解決的事情每次導(dǎo)入都要開啟一個(gè)異步,個(gè)人感覺這種做法非常不好。因?yàn)楫惒狡鋵?shí)就是對(duì)當(dāng)前的業(yè)務(wù)不影響去另外的時(shí)間段去做,例如跑定時(shí)任務(wù),異步更新增量信息等。代碼里非常多異步包異步的東西,也就是說excel導(dǎo)入是異步,然后jpa又慢,異步里面又包涵異步,整個(gè)鏈路非常長,可能發(fā)生問題都要排查半天。

安裝jpa和mybatis

<dependency>
	<groupId>org.mybatis.spring.boot</groupId>
	<artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>
<dependency>
	<groupId>mysql</groupId>
	<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

這些東西只要引入一個(gè)springboot的xml作為父類就行

創(chuàng)建一個(gè)類

@Data
public class TestMybatis {
    private Long id;
    /**
     * 域賬號(hào)
     */
    private String userId;
    /**
     * 主度量
     */
    private String mainMetric;
    /**
     * 子度量
     */
    private String subMetric;
    /**
     * 度量條目
     */
    private String metricItem;
}
@SuppressWarnings("serial")
@javax.persistence.Entity
@javax.persistence.Table(name = "test")
@lombok.Data
public class TestJpa {
    @javax.persistence.Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    /**
     * 域賬號(hào)
     */
    private String userId;
    /**
     * 主度量
     */
    private String mainMetric;
    /**
     * 子度量
     */
    private String subMetric;
    /**
     * 度量條目
     */
    private String metricItem;
}
/**
 * @author Kakki
 * @version 1.0
 * @create 2021-06-17 17:39
 * 這個(gè)是用來Jpa跟Mapper差不多
 */
@Repository
public interface TestRee extends JpaRepository<TestRe, String> {

}

這是mybatis的xml

<insert id="insertList">
    insert into test(user_id,main_metric, sub_metric, metric_item) values
    <foreach collection="param" item="item" separator=",">
            (#{item.userId}, #{item.mainMetric}, #{item.subMetric}, #{item.metricItem})
    </foreach>
</insert>

下面我們來看看速度

@Slf4j
@RunWith(SpringRunner.class)
@SpringBootTest(classes = {ColaDemoApplication.class})
class ColaDemoApplicationTests {
    @Autowired
    private TestRee testRee;
    @Autowired
    private MetricMapper metricMapper;

    @Test
    void contextLoads() {
        List<TestJpa> jpaList = new ArrayList<>(1000);
        List<com.kakki.colademo.gatewayimpl.database.dataobject.TestMybatis> mybatisList = new ArrayList<>(1000);
        for (int i = 0; i < 1000; i++) {
            TestJpa testJpa = new TestJpa();
            testJpa.setMainMetric(String.format("mainMetric%d", i));
            testJpa.setSubMetric(String.format("subMetric%d", i));
            testJpa.setUserId(String.format("userId%d", i));
            testJpa.setMetricItem(String.format("metricItem%d", i));
            jpaList.add(testRe);
            com.kakki.colademo.gatewayimpl.database.dataobject.TestMybatis testMybatis = new com.kakki.colademo.gatewayimpl.database.dataobject.TestMybatis();
            testMybatis.setMainMetric(String.format("mainMetric%d", i));
            testMybatis.setSubMetric(String.format("subMetric%d", i));
            testMybatis.setUserId(String.format("userId%d", i));
            testMybatis.setMetricItem(String.format("metricItem%d", i));
            mybatisList.add(testR);
        }
        StopWatch jpa = new StopWatch();
        jpa.start();
        testRee.saveAll(jpaList);
        jpa.stop();
        log.info("[jpa]{}ms", jpa.getTotalTimeMillis());

        StopWatch m = new StopWatch();
        m.start();
        metricMapper.insertList(mybatisList);
        m.stop();
        log.info("[m]{}ms", m.getTotalTimeMillis());

    }

}

22:35:10.708 [main] INFO  c.e.c.ColaDemoApplicationTests - [jpa]10576ms
22:35:31.366 [main] INFO  c.e.c.ColaDemoApplicationTests - [m]138ms

可以說相差差不多10倍了吧?這僅僅只是1000條數(shù)據(jù)。讓我們試試10000條

22:36:48.505 [main] INFO  c.e.c.ColaDemoApplicationTests - [jpa]8081ms
22:37:05.005 [main] INFO  c.e.c.ColaDemoApplicationTests - [m]613ms
# 再試試10w條
22:38:49.085 [main] INFO  c.e.c.ColaDemoApplicationTests - [jpa]65710ms
22:39:09.844 [main] INFO  c.e.c.ColaDemoApplicationTests - [m]9448ms

那么這樣能看出來很大的差距了吧?為什么會(huì)差距這么大呢?我們看看saveAll()源碼

    @Transactional
	@Override
	public <S extends T> List<S> saveAll(Iterable<S> entities) {

		Assert.notNull(entities, "Entities must not be null!");

		List<S> result = new ArrayList<S>();

		for (S entity : entities) {
			result.add(save(entity));
		}

		return result;
	}
    @Transactional
	@Override
	public <S extends T> S save(S entity) {

		if (entityInformation.isNew(entity)) {
			em.persist(entity);
			return entity;
		} else {
			return em.merge(entity);
		}
	}

從上面可以看出來是一條條save進(jìn)去的并且save里面還會(huì)去判斷這個(gè)主鍵是否為空也就是說n條循環(huán)n條if判斷,那樣性能肯定是衰減得非常多的拉

結(jié)論

我在網(wǎng)上看到加入以下這些參數(shù)可以變成批量的,但是筆者試過根本沒用,可能想要解決這個(gè)問題,需要重寫他的saveAll()方法然后分片去插入或者更新這樣性能會(huì)好很多。

spring.jpa.properties.hibernate.jdbc.batch_size=10000
spring.jpa.properties.hibernate.jdbc.batch_versioned_data=true
spring.jpa.properties.hibernate.order_inserts=true
spring.jpa.properties.hibernate.order_updates=true

當(dāng)然今天我僅僅是用jpa的性能跟mybatis比較,但是作為一個(gè)碼農(nóng)深知,技術(shù)是為業(yè)務(wù)服務(wù)的。Jpa當(dāng)然也有他的好處,例如創(chuàng)建一些方法findAllByIdIn(List ids)就可以直接獲取到以這個(gè)條件查詢的列表,還有findAllByOrderIdAndOrderType(String orderId, String orderType)這種一樣也可以,可以說非常的方便,也不需要再去寫sql,他會(huì)全自動(dòng)的完成你的查詢操作。

小結(jié)

開發(fā)一個(gè)小型項(xiàng)目,Jpa效率肯定是比Mybatis高的,但是因?yàn)闃I(yè)務(wù)需求迭代更新越來越快,Jpa明顯是滿足不了很多東西,而且維護(hù)起來看Sql也是比MyBatis難。所以我更偏向于Mybatis,寫的Sql也更加簡潔更容易維護(hù)。

到此這篇關(guān)于Mybatis與Jpa的區(qū)別和性能對(duì)比的文章就介紹到這了,更多相關(guān)Mybatis與Jpa區(qū)別和性能內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論

阿巴嘎旗| 贡山| 东明县| 泰安市| 长岛县| 庄河市| 彰化县| 永城市| 吴江市| 五指山市| 宁晋县| 保靖县| 绥德县| 郯城县| 余干县| 大同县| 固镇县| 陆良县| 同心县| 古浪县| 遂平县| 定陶县| 庆安县| 菏泽市| 辰溪县| 全南县| 剑阁县| 商都县| 平罗县| 土默特左旗| 浦东新区| 绥中县| 沙湾县| 江油市| 高淳县| 乐东| 新和县| 苗栗市| 大名县| 长治县| 青阳县|