springboot jpa自定义查询

springboot jpa自定义查询,第1张

jpa系列:

springboot jpa使用

springboot jpa 关系注解和mappedBy

springboot jpa自定义查询

以下语句均为hql

使用@Query来指定hql语句,则方法名随意,jpa将根据该注解进行查询;你也可使用sql语句,只需注解中添加参数 nativeQuery = true 即可,但不建议这样做,容易导致对象封装出错,也不利于跨平台。

关于hql,其语法基本雷同sql。不同之处基本在于:

1hql中使用 类名 取代 表名 ,用 类名类成员名 取代 表名列名 。

如 from User 中的 User ,这里不是指表名,而是类名。也可加上包名如 comexampleUser 。

2hql类名建议不要省略。

自己测试时,hql直接用类成员 username 会报错,改为 userusername 就可以,与其它教程的似乎有出入,这里作建议。

3hql没有

上面例子等价于sql: select t from user as t ,也就是hql中全选所有列的 不用写也不能写。注意hql和sql中 as 都是可省略的,不要忽略这点。

1更新/删除 *** 作只需增加注解 @Modifying

2使用形参,有两种方式:

法1:

1 和 2 分别代指形参 username 和 id

法2:

形参加注解@Param,hql中用 :ids 指代。值得一提,当参数是数组时仍然可用,如例子。

例子1:

例子为选择username列的所有数据。注意泛型问题,这里相当于 List<Object> 。你也可使用 String[] 作返回类型,但实际可视作jpa调用 ListtoArray(new String[Listsize()]) ,仍然有可能出现类型转换错误。

例子2:

选择两列的所有数据。注意泛型问题,这里相当于 List<Object[2]> 。

问题:只想简单执行hql语句,不想去改动DAO层中接口的方法。

答:使用orghibernate包的Session类和Query类。 链接

JPA全称Java Persistence APIJPA通过JDK 50注解或XML描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中。\x0d\JPA的总体思想和现有Hibernate、TopLink,JDO等ORM框架大体一致。总的来说,JPA包括以下3方面的技术:\x0d\ORM映射元数据\x0d\JPA支持XML和JDK 50注解两种元数据的形式,元数据描述对象和表之间的映射关系,框架据此将实体对象持久化到数据库表中;\x0d\JPA 的API\x0d\用来 *** 作实体对象,执行CRUD *** 作,框架在后台替我们完成所有的事情,开发者从繁琐的JDBC和SQL代码中解脱出来。\x0d\查询语言\x0d\这是持久化 *** 作中很重要的一个方面,通过面向对象而非面向数据库的查询语言查询数据,避免程序的SQL语句紧密耦合。

修改查询

@Modifying

@Query("update User u set ufirstname = 1 where ulastname = 2")

int setFixedFirstnameFor(String firstname, String lastname);

使用 Sort 和 JpaSort

public interface UserRepository extends JpaRepository {

  @Query("select u from User u where ulastname like 1%")

  List findByAndSort(String lastname, Sort sort);

  @Query("select uid, LENGTH(ufirstname) as fn_len from User u where ulastname like 1%")

  List findByAsArrayAndSort(String lastname, Sort sort);

}

repofindByAndSort("lannister", new Sort("firstname"));           

repofindByAndSort("stark", new Sort("LENGTH(firstname)"));       

repofindByAndSort("targaryen", JpaSortunsafe("LENGTH(firstname)"));

repofindByAsArrayAndSort("bolton", new Sort("fn_len"));   

使用已命名参数

public interface UserRepository extends JpaRepository {

  @Query("select u from User u where ufirstname = :firstname or ulastname = :lastname")

  User findByLastnameOrFirstname(@Param("lastname") String lastname,

                                @Param("firstname") String firstname);

}   

原生SQL分页

public interface UserRepository extends JpaRepository {

  @Query(value = "SELECT FROM USERS WHERE LASTNAME = 1",

    countQuery = "SELECT count() FROM USERS WHERE LASTNAME = 1",

    nativeQuery = true)

  Page findByLastname(String lastname, Pageable pageable);

}

Sort sort =newSort(SortDirectionDESC,"createTime");//创建时间降序排序Pageable pageable =newPageRequest(pageNumber,pageSize,sort);

使用原生SQL

public interface UserRepository extends JpaRepository {

  @Query(value = "SELECT FROM USERS WHERE EMAIL_ADDRESS = 1", nativeQuery = true)

  User findByEmailAddress(String emailAddress);

}

为了消除不确定性,可以在方法名内使用下划线“_”手动定义隔断点。

List findByAddress_ZipCode(ZipCode zipCode);

查询方法建立

distinct flag

ignoring case

order by

public interface PersonRepository extends Repository {

  List findByEmailAddressAndLastname(EmailAddress emailAddress, String lastname);

  // Enables the distinct flag for the query  List findDistinctPeopleByLastnameOrFirstname(String lastname, String firstname);

  List findPeopleDistinctByLastnameOrFirstname(String lastname, String firstname);

  // Enabling ignoring case for an individual property  List findByLastnameIgnoreCase(String lastname);

  // Enabling ignoring case for all suitable properties  List findByLastnameAndFirstnameAllIgnoreCase(String lastname, String firstname);

  // Enabling static ORDER BY for a query  List findByLastnameOrderByFirstnameAsc(String lastname);

  List findByLastnameOrderByFirstnameDesc(String lastname);

}

异步查询结果

@Async

Future findByFirstname(String firstname);           

@Async

CompletableFuture findOneByFirstname(String firstname);

@Async

ListenableFuture findOneByLastname(String lastname);

Like模糊查询

@Query(value = "select name,author,price from Book b where bname like %:name%")

List findByNameMatch(@Param("name") String name);

In 查询

@Query(value = "select from trade$seek_purchase_offer where sp_id in (:spIds) and of_enuu = :enUu", nativeQuery = true)

    List getSeekPurchaseOfferList(@Param("spIds") List spIds, @Param("enUu") Long enUu);

MappedSuperClass:

映射为非实体父类,该实体父类不会生成对应的数据表

@OneToOne

@Entity

@Table(name = "costume_all_id")

public class AllId extends AbstractEntity {

    private static final long serialVersionUID = 1L;

    @OneToOne(cascade = CascadeTypeALL)

    @JoinColumn(name = "costume_member_fk")

    private Member member;// 用户表外键

}

@OneToMany和@ManyToOne

@Entity

@Table(name = "costume_organization")

public class Organization extends AbstractEntity {

    private static final long serialVersionUID = 1L;

    @Column(nullable = false, length = 50)

    private String name; // 组织名称

    @OneToMany(mappedBy = "organization")

    private Set departmentSet; // 部门集合

}

@Entity

@Table(name = "costume_department")

public class Department extends AbstractEntity {

    private static final long serialVersionUID = 1L;

    @Column(nullable = false, length = 50)

    private String name; // 部门名称

    @ManyToOne(optional = false)

    private Organization organization; // 组织外键

    @ManyToMany

    private Set memberSet; // 用户表外键

    public Organization getOrganization() {

        return organization;

    }

    @JsonBackReference

    public void setOrganization(Organization organization) {

        thisorganization = organization;

    }

}

@ManyToMany

Entity

@Table(name = "costume_member")

public class Member extends AbstractEntity {

    private static final long serialVersionUID = 1L;

    @Column(nullable = false, length = 20)

    private String name;

    @ManyToMany

    @JoinTable(joinColumns = { @JoinColumn(name = "member_id") }, inverseJoinColumns = {

            @JoinColumn(name = "department_id") }) //被控方表字段名

    private Set departmentSet; // 部门表外键

    public Set getDepartmentSet() {

        return departmentSet;

    }

    @JsonBackReference

    public void setDepartmentSet(Set departmentSet)

    {

        thisdepartmentSet = departmentSet;

    }

}

HQL通过旅店名称查询旅店以及城市的所有信息 直接返回实体类

/

关联查询

@return

/

@Query(value = "select new perszpwdomainCityHohel(t1name AS cityName,t2name AS hotelName) from  TCity t1 left  join THotel t2 on t1id=t2city where t2name =:name")

List findCityAndHotelByHQLResultObj(@Param("name") String name);

@Data

public class CityHohel {

        private String cityName;

        private String hotelName;

        public CityHohel(String cityName, String hotelName) {

            thiscityName = cityName;

            thishotelName = hotelName;

        }

}

实例2

@Entity 

@Table(name="orders") 

public class Order { 

    private String orderid; 

    private Float amount = 0f; 

    private Set items = new HashSet(); 

    @Id 

    @Column(length = 12) 

    public String getOrderid() { 

        return orderid; 

    } 

    public void setOrderid(String orderid) { 

        thisorderid = orderid; 

    } 

    @Column(nullable = false) 

    public Float getAmount() { 

        return amount; 

    } 

    public void setAmount(Float amount) { 

        thisamount = amount; 

    } 

@OneToMany(cascade = { CascadeTypeREFRESH, CascadeTypePERSIST,CascadeTypeMERGE, CascadeTypeREMOVE },mappedBy ="order") //这里配置关系,并且确定关系维护端和被维护端。mappBy表示关系被维护端,只有关系端有权去更新外键。这里还有注意OneToMany默认的加载方式是赖加载。当看到设置关系中最后一个单词是Many,那么该加载默认为懒加载 

    public Set getItems() { 

        return items; 

    } 

    public void setItems(Set items) { 

        thisitems = items; 

    } 

        / 

          该方法用于向order中加order项 

          / 

    public void addOrderItem(OrderItem orderItem){ 

        orderItemsetOrder(this);//用关系维护端来维护关系 

        thisitemsadd(orderItem); 

    } 

}

@Entity 

public class OrderItem { 

    private Integer id; 

    private String productName; 

    private Float sellPrice = 0f; 

    private Order order; 

    @Id 

    @GeneratedValue 

    public Integer getId() { 

        return id; 

    } 

    public void setId(Integer id) { 

        thisid = id; 

    } 

    @Column(length = 40, nullable = false) 

    public String getProductName() { 

        return productName; 

    } 

    public void setProductName(String productName) { 

        thisproductName = productName; 

    } 

    @Column(nullable = false) 

    public Float getSellPrice() { 

        return sellPrice; 

    } 

    public void setSellPrice(Float sellPrice) { 

        thissellPrice = sellPrice; 

    } 

    @ManyToOne(cascade = {CascadeTypeMERGE,CascadeTypeREFRESH }, optional = true) 

    @JoinColumn(name="order_id")//这里设置JoinColum设置了外键的名字,并且orderItem是关系维护端 

    public Order getOrder() { 

        return order; 

    } 

    public void setOrder(Order order) { 

        thisorder = order; 

    } 

缓存

  

    orgspringframeworkboot  

    spring-boot-starter-cache  

@Configuration  

@EnableCaching  

public class CacheConfig {  

}  

@Cacheable

Spring 在执行 @Cacheable 标注的方法前先查看缓存中是否有数据,如果有数据,则直接返回缓存数据;若没有数据,执行该方法并将方法返回值放进缓存。

参数: value缓存名、 key缓存键值、 condition满足缓存条件、unless否决缓存条件

@Cacheable(value = "user", key = "#id")  

public User findById(final Long id) {  

    Systemoutprintln("cache miss, invoke find by id, id:" + id);  

    for (User user : users) {  

        if (usergetId()equals(id)) {  

            return user;  

        }  

    }  

    return null;  

}  

@CachePut

和 @Cacheable 类似,但会把方法的返回值放入缓存中, 主要用于数据新增和修改方法。

@CachePut(value = "user", key = "#userid")  

public User save(User user) {  

    usersadd(user);  

    return user;  

@CacheEvict

方法执行成功后会从缓存中移除相应数据。

参数: value缓存名、 key缓存键值、 condition满足缓存条件、 unless否决缓存条件、 allEntries是否移除所有数据(设置为true时会移除所有缓存)

@CacheEvict(value = "user", key = "#userid") // 移除指定key的数据  

public User delete(User user) {  

    usersremove(user);  

    return user;  

}  

@CacheEvict(value = "user", allEntries = true) // 移除所有数据  

public void deleteAll() {  

    usersclear();  

}  

springcachetype=none 设置缓存无效化

集成EhCache

  

    netsfehcache  

    ehcache  

         xsi:noNamespaceSchemaLocation="ehcachexsd">  

      

src\main\resources/applicationproperties

springcacheehcacheconfig=classpath:ehcachexml

如果想自定义设置一些个性化参数时,通过Java Config形式配置。

@Configuration  

@EnableCaching  

public class CacheConfig {  

    @Bean  

    public CacheManager cacheManager() {  

        return new EhCacheCacheManager(ehCacheCacheManager()getObject());  

    }  

    @Bean  

    public EhCacheManagerFactoryBean ehCacheCacheManager() {  

        EhCacheManagerFactoryBean cmfb = new EhCacheManagerFactoryBean();  

        cmfbsetConfigLocation(new ClassPathResource("ehcachexml"));  

        cmfbsetShared(true);  

        return cmfb;  

    }  

}  

组合CacheManager

从多个CacheManager中轮询得到相应的Cache。

@Configuration  

@EnableCaching  

public class CacheConfig {  

    @Bean  

    public CacheManager compositeCacheManager(RedisTemplate redisTemplate) {  

        CompositeCacheManager cacheManager = new CompositeCacheManager(new ConcurrentMapCacheManager(), new SimpleCacheManager());  

        cacheManagersetFallbackToNoOpCache(false);  

        cacheManagerafterPropertiesSet();  

        return cacheManager;  

    }  

大约一年以前 我为了学习一些Hibernate专业知识 因此我参加了一个Hibernate项目 从那时起 我一直在使用Hibernate框架下的JPA(Java持久API)实现 使用的思想仍就是一样的 那个项目使用了一个数据库 这个数据库规模有些大 略显落后 并且还被许多的应用程序共用 为了尽快加入到项目中 我开始学习一些Hibernate知识 从书本上的例子开始学习 感觉很简单 学起来也很快 但是发现从零开始开发一个项目 并且控制它又是另外一回事了 试着在一个大型 复杂 被许多应用程序共用的数据库上使用Hibernate就又完全不同了 弄清楚了我可能遭遇到的技术难点 我开始想别的招了 要尽快从另外的方向开始 克服困难

在最终的学习和实践中 我发现我还是学到了许多重要的东西 虽然我们的项目还没有完全做完 但是我认为我们目前已经非常漂亮的应用了Hibernate/JPA的一些思想 现在我需要重新思考反省我所学到的东西 如下便是我学到的一些心得

)和数据库管理员成为朋友

目前存在一个趋势 就是一些Java开发者忽视数据库管理员的重要性 这便犯了一个很大的错误 对于要取得任何的ORM(对象关系映射)技术的成功 和数据库管理员保持一个良好的工作关系是至关重要的 有如下两个原因

单独数据库管理员虽然不能使Hibernate项目成功 但是他们通常可以让这些项目失败

数据库管理员对数据库本身具有很好的洞察力 很好的职业习惯 告诉你一些易犯的错误和 *** 作建议 我能记起这样的很多例子 一个数据库管理员的建议节约了我们很多的时间和提供给我们一个很好的解决方案

在大多数情况下 拥有好的数据库管理员 并且和他们保持良好的关系对你ORM(对象关系映射)工作至关重要

)从一开始使用(最好强制使用)好的命名标准

我们知道对命名标准的讨论将会有争议的 但是我们必须明确一件事情 我们的命名要让我们的数据模型有意义 这能让开发者使用起来简单 以免他们迷惑 所以 如何命名实体和属性是非常重要的 我有我喜欢命名标准 并且认为他们是最好的 但是在这里我不想把他们强加于你们 最重要的是你自己做出决定使用什么样的命名标准 并且让所有人使用它 实际上 不仅仅命名标准需要统一 其它的也需要(如 布尔型用 Y/N 或者 / 表示)

)不要试着映射所有的属性

我们总是设法使用工具 如Dali来映射所有的东西 然后形成一张表格(一些表格有上百列 !) 这最终会很麻烦 为什么?因为我们使用的是共用的 先前的数据库 有许多的字段是我们并不关心和从来不使用的 映射它们只会导致性能问题和造成混乱

)让数据库做自己擅长的工作

我们想有一个好的 清晰的数据模型 因此我们不惜任何代价写一些额外的查询语句来获取对象相关数据 要么使用存储过程 要么使用函数 这是做法是错误的 数据库优势在于存储 而不是保持Hibernate创建或读写的数据 举个例子 我们有一个对象 与之相关联的有一个状态 这个状态在整个应用程序中都要用到 因此 它毫无疑问是要执行的 但是 我们不想每次都要单独的写一个查询语句 这个问题在于 这个状态是从一些统计计算中派生出来的 并且这些统计计算需要用到一对多的关系 每次从加载的对象中读取数据的代价是非常高的 后来跟我们其中的一位数据库管理员交流了一下 发现一个我们可以使用的sql函数能够很快的获得该状态 我们使用@Formula来映射成一个状态属性 就能得到我们所需要的所有东西 这仍就是域模型的一部分 但是执行起来非常好 有时像这样的一个折衷的办法能够起到很大的效果

)分解数据库

在一开始 我就想在Hibernate中模型化整个数据库 结果发现这是不切实际的 原因如下 a)这是一项巨大的工程 并且要花费几周的时间 而用户根本看不到你做了什么实际的工作

b)我不可能在第一次就把它弄好 后继的开发者无论如何都会修改它们的

现在有一个趋势 就是希望在开始之前 将所有的事情都进行映射 但是 当时你开始这么做后 你不需在这上面花很多的时间 我后来发现一个好的办法 就是将数据库分解 工作的时候一块一块的进行 发现这很有帮助

)密切注意触发器

密切注意数据库触发器有如下两个原因

a)在后台触发器很隐蔽的执行了一些功能 让你很是疑惑 不知道发生了什么

b)当你在Hibernate端需要复制一些东西的时候 触发器会做一些手脚 之前我们好几次没有认识到这个教训 导致我们丢失了很多数据 这些都是由触发器引起的 这几乎让我们很是郁闷

)避免使用工具来自动生成你的模型

没错 这些工具的使用可以节约时间(虽然我们发现了Dali有一个很严重的bug 但是我们还是使用它) 但是最后你不得不重新做很多的事情 其实手动也花费不了你很多的时间 当你亲自做的时候 这可以让你有机会熟悉那些数据

) 尽量多的使用命名查询语句(NamedQueries)

虽然很容易写查询语句 但是在许多的情况下 使用NamedQueries会更好 这会有助于你完成两件事情

a)它能更加重用 因为被命名的查询语句通常在代码的重要地方

b)你的查询语句在开始的时候就是正确的 那么在查询语句中的错误更加容易发现

要习惯这样做需要花一些时间 但是这么做是值得的

)预期管理

对于任何一种框架 技术 甚至观念来说 这是非常重要的 要铭记在心 由于某些原因 人们倾向于专注某一个特征 这些特征实际上或许不存在 或许被夸大 有时它很小 很容易理解(举个例子 理解一些实际的工作 需要在Hibernate中映射) 有时我也不知道他们是如何管理实现一些概念(如Hibernate是如何管理计划修正的) 无论如何 找到预期目标是什么 然后管理它们是非常重要的 如果你的团队认为Hibernate会使得数据库管理员没有用处 把他们解雇 那么你将会有一个潜在的问题存在

)使用富域模型(rich domain modeling)

lishixinzhi/Article/program/Java/ky/201311/28274

1 JPA概念

Java persistence API的简称,中文名是Java持久层API,

是JDK50注解或XML描述对象-关系表的映射关系,

并将运行期的实体对象持久化到数据库中。

(对象持久化:是将内存中的对象保存到可永久保存的存储设备中的一种技术)

2 JPA出现的原因

1简化现有JavaEE和JavaSE应用的对象持久化的开发工作;

2Sun希望整合ORM技术,实现在持久化领域的统一应用;

3 JPA提供的技术

1ORM映射元数据

JPA支持XML和JDK50注解两种元数据的形式,元数据描述对象和表之间的映射关系框架据此将实体对象持久化到数据库表中;(元数据:是指用来描述数据的数据,就是描述代码间关系的数据,如:hibernate是用hbm文件。JDK50出来后,java语言中就有了四种类型(TYPE),即类(class)、枚举(enum)、接口(interface)和注解(@interface),它们是处在同一级别的。java就是通过注解来表示元数据的。)

2JPA的API

用来 *** 作实体对象,执行crud *** 作,框架在底层替我们完成所有的事情,开发者从繁琐的JDBC 和 SQL代码中解脱;

3查询语言

通过面向对象而非面向数据库的查询语言查询数据,避免程序的SQL语句紧密耦合;

打开你手机的root管理软件,选择root权限控制

找到腾讯手机管家,在是否允许获取root权限的选项中选择拒绝,就不会再d出了。

在新版腾讯手机管家,权限管理在手机管家首页下方,点击更多——找到一键root或净化大师,管理软件权限

JPA 20

entityManagergetTransaction()begin();

javasqlConnection connection = entityManagerunwrap(javasqlConnectionclass);

entityManagergetTransaction()commit();

====================================================================

JPA 10

entityManagergetTransaction()begin();

UnitOfWork unitOfWork = (UnitOfWork)((JpaEntityManager)entityManagergetDelegate())getActiveSession();

unitOfWorkbeginEarlyTransaction();

Accessor accessor = unitOfWorkgetAccessor();

accessorincrementCallCount(unitOfWorkgetParent());

accessordecrementCallCount();

javasqlConnection connection = accessorgetConnection();

entityManagergetTransaction()commit();

以上就是关于springboot jpa自定义查询全部的内容,包括:springboot jpa自定义查询、java中jpa什么意思、JPA实用手册,即看即用等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/9444709.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-28
下一篇 2023-04-28

发表评论

登录后才能评论

评论列表(0条)

保存