springboot jpa 使用标准的动态 sql

本文介绍SpringBoot JPA中实现动态SQL的方法,包括通过EntityManagerFactory和EntityManager进行数据库查询的不同方式,并展示了如何获取特定的数据结果。
部署运行你感兴趣的模型镜像

springboot jpa 使用标准的动态 sql

 

第一种写法。在 service 层使用 @PersistenceUnit 注解,注入一个 EntityManagerFactory
    @PersistenceUnit
    private EntityManagerFactory emFactory; 

    @RequestMapping(value = "/sqltest", method = RequestMethod.POST) 
    public List<Car> sqltest(@RequestBody String brand){

        EntityManager em = emFactory.createEntityManager();  // 获得 EntityManager

        String sql = "select * from car where brand = :brand";

        List<Car> re = (List<Car>) em.createNativeQuery(sql, Car.class)
                .setParameter("brand", brand).getResultList();

        // 操作完数据库,需要显式关闭 entityManager,否则 entityManager 会一直保持这个数据库连接

        em.close();

        return re;

    }

 

查询结果集为包含 Map 的 List 的写法:

String sql = "select * from car where brand = :brand";

EntityManager em = emFactory.createEntityManager();

Query query = em.createNativeQuery(sql);    // import javax.persistence.Query;

query.unwrap(SQLQuery.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);

List<Map<String, Object>> re = query.setParameter("brand", brand).getResultList();

 

注意,这种写法如果不关闭entityManager,em.close(); ,项目运行时间长了就会报错。

因为 entityManager 会一直保持数据库连接,不断开。

随着项目不断运行,mysql 的连接数(Threads_connected)会一直上涨:

javax.persistence.PersistenceException: org.hibernate.exception.GenericJDBCException: Unable to acquire JDBC Connection

Caused by: org.apache.tomcat.jdbc.pool.PoolExhaustedException: [pool-9-thread-1] Timeout: Pool empty. Unable to fetch a connection in 30 seconds, none available[size:100; busy:100; idle:0; lastwait:30000].

Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: Data source rejected establishment of connection,  message from server: "Too many connections"

---------------------------------------------------

第二种写法。在 service 层使用 @PersistenceContext 注解注入 EntityManager:

这种写法,不需要操作完数据库显式的用 em.close() 关闭 entityManager推荐使用这种写法。

    @PersistenceContext
    private EntityManager em;

    @RequestMapping(value = "/sqltest", method = RequestMethod.POST)
    public List<Car> sqltest(@RequestBody String brand){
        String sql = "select * from car where brand = :brand";

        List<Car> re = (List<Car>) em.createNativeQuery(sql, Car.class)
                .setParameter("brand", brand).getResultList();

        return re;
    }

---------------------------------------------------

第三种写法。在 dao 层使用 @Query 注解,不过这种方法只能获得 List<Object[]>

@Query( value = "SELECT p.shop_id, sum(p.price) FROM product p GROUP BY p.shop_id", nativeQuery=true)
List<Object[]> getSumPriceGroupByShopId();

 

您可能感兴趣的与本文相关的镜像

Llama Factory

Llama Factory

模型微调
LLama-Factory

LLaMA Factory 是一个简单易用且高效的大型语言模型(Large Language Model)训练与微调平台。通过 LLaMA Factory,可以在无需编写任何代码的前提下,在本地完成上百种预训练模型的微调

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值