这是我参与11月更文挑战的第7天,活动详情查看:2021最后一次更文挑战
基于单表的SQL操作
单表SQL操作-使用关键字拼凑
- 相关查询题目
-
查询出年龄小于等于20岁的人
-
查询出年龄在20-22岁并且性别是男的人
-
查询出已结婚且性别是女的人
- 注意事项
- 实体类属性名不要出现isXxx、getXxx的名称,会导致关键字拼凑出错
- 实体类属性名中间只要出现了大写字母,就会导致数据库的字段名有下划线隔开,比如你使用isMarried属性名,那么实体类的字段名就会变成is_married ,而数据库中列名是ismarried ,这样容易导致找不到值
- 属性名类型是boolean类型的在某些数据库中会变成bit(1)类型,其中0为false,1为true
application和pom贴了好多次了,以前的文章都有,没有变化这次就不贴了哈 。 没有建表sql是因为application做了配置,调用初始化数据方法的时候会自动的去创建数据表的结构。
entity
@Data //lomobok插件
@Entity
@AllArgsConstructor //有参构造器
@NoArgsConstructor //无参构造器
@Builder //部分参数构造器
public class Person {
@Id
@GenericGenerator(name="myuuid",strategy = "uuid")
@GeneratedValue(generator = "myuuid")
private String pid;
@Column(unique = true)
private String pname;
@Column
private String psex;
@Column
private Integer page;
@Column
private Boolean getmarried;
}
repository
public interface PersonReposity extends JpaRepository<Person,Integer> {
//查询出年龄小于等于20岁的人
List<Person> findAllByPageLessThanEqual(Integer age);
//查询出年龄在20-22岁并且性别是男的人
List<Person> findAllByPageBetweenAndPsexEquals(Integer lowage,Integer highage,String sex);
//查询出已结婚且性别是女的人
List<Person> findAllByGetmarriedIsTrueAndPsexEquals(String sex);
}
test 初始化一些数据
@SpringBootTest
class JpaApplicationTests {
@Resource
private PersonReposity personReposity;
@Test
void contextLoads() {
//抽象成一个方法快捷键 Ctrl + Alt + M
initPerson();
}
private void initPerson() {
List<Person> list = new ArrayList<>();
Collections.addAll(
list,Person.builder().pname("zhangsan").psex("男").page(22).getmarried(false).build(),
Person.builder().pname("lisi").psex("女").page(21).getmarried(true).build(),
Person.builder().pname("wangwu").psex("男").page(20).getmarried(false).build(),
Person.builder().pname("zhaoliu").psex("女").page(23).getmarried(true).build(),
Person.builder().pname("sunqi").psex("男").page(25).getmarried(true).build()
);
personReposity.saveAll(list);
}
}
查询出年龄小于等于20岁的人
void contextLoads() {
System.out.print(personReposity.findAllByPageLessThanEqual(20));
}
Hibernate: select person0_.pid as pid1_0_, person0_.getmarried as getmarri2_0_, person0_.page as page3_0_, person0_.pname as pname4_0_, person0_.psex as psex5_0_ from person person0_ where person0_.page<=?
[Person(pid=402894cb7cfebcf8017cfebd038c0002, pname=wangwu, psex=男, page=20, getmarried=false)]
查询出年龄在20-22岁并且性别是男的人
void contextLoads() {
System.out.print(personReposity.findAllByPageBetweenAndPsexEquals(20,22,"男"));
}
Hibernate: select person0_.pid as pid1_0_, person0_.getmarried as getmarri2_0_, person0_.page as page3_0_, person0_.pname as pname4_0_, person0_.psex as psex5_0_ from person person0_ where (person0_.page between ? and ?) and person0_.psex=?
[Person(pid=402894cb7cfebcf8017cfebd03740000, pname=zhangsan, psex=男, page=22, getmarried=false), Person(pid=402894cb7cfebcf8017cfebd038c0002, pname=wangwu, psex=男, page=20, getmarried=false)]
查询出已结婚且性别是女的人
void contextLoads() {
System.out.print(personReposity.findAllByGetmarriedIsTrueAndPsexEquals("女"));
}
Hibernate: select person0_.pid as pid1_0_, person0_.getmarried as getmarri2_0_, person0_.page as page3_0_, person0_.pname as pname4_0_, person0_.psex as psex5_0_ from person person0_ where person0_.getmarried=1 and person0_.psex=?
[Person(pid=402894cb7cfebcf8017cfebd038c0001, pname=lisi, psex=女, page=21, getmarried=true), Person(pid=402894cb7cfebcf8017cfebd038c0003, pname=zhaoliu, psex=女, page=23, getmarried=true)]
单表SQL操作-使用关键字拼凑无法解决的问题
- 实体类的属性名与表的字段名无法映射,导致关键字找不到
- CRUD操作方式比较另类或者是你不想用关键字的写法
- 涉及到了多表操作
单表SQL操作-使用注解手写SQL语句
- 使用SQL语句来书写SQL 相关查询或使用HQL语句来书写SQL 相关查询(根据使用习惯进行选择)
- 相关操作
- 按照pname来模糊删除
- 查询出年龄是20-22岁的并且性别是女的人
- 使用spel表达式来演示用户的登录
- 注意事项
- 如果是删改操作,需要加@Modifying和@Transactional注解
- 若果是SQL语句,请在@Query注解加上NativeQuery = true的属性
- 传参的方式有两种
使用 ? + 数字的方式,数字从1开始,代表第几个参数
使用 : + 参数名的方式,这种方式最好配合@Param注解一起使用 (推荐这种方式直观)
实现按照pname来模糊删除
//方式一
@Transactional
@Modifying
@Query(value="delete from Person where pname like %?1%")
void deleteByPname(String pname);
//方式二@Transactional
@Modifying
@Query(value="delete from Person where pname like %:pname%")
void deleteByPname(@Param("pname") String pname);
注意 @Transactional @Modifying不加的时候会出现报错,错误信息如下
使用SQL或者HQL来书写一个查询语句,查询出年龄在20-22岁,性别是女的人
@Query(value = "select * from person where page between 20 and 22 and psex = '女' ",nativeQuery = true)
List<Person> findAllSQL();
@Query(value = "select p from Person p where p.page between 20 and 22 and p.psex = '女' ")
List<Person> findAllHQL();
spel表达式完成Person的修改操作
@Transactional
@Modifying
@Query(value="update person set pname = :#{#person.pname} ,psex = :#{#person.psex} ,page = :#{#person.page} " +
"where pid = :#{#person.pid}",nativeQuery = true)
void updatePerson(@Param("person") Person person);
//调用
personReposity.updatePerson(Person.builder().pid("402894cb7cfebcf8017cfebd03740000").pname("zs").psex("男").page(26).build());
JPA 逆向工程及多表SQL操作
使用数据接口
构建一个数据接口,里面的抽象方法就是SQL语句的查询结果的字段对应的getXXX的抽象方法
使用集合(推荐)
直接使用List/Map等集合嵌套的方式来获取到接收数据
使用VO(View Object)
单独构建一个跟页面展示数据对应的VO实体类来接受数据
- 相关查询题目
- 通过书籍名来查询拥有者信息
- 通过person的id来查询两张表的所有信息
- 注意事项
- 使用数据接口的方式来接受查询的字段时要注意,必须要为要查询的字段起别名,否则会无法取到
- 操作
-
idea使用jpa逆向生成实体类 ,操作步骤参考juejin.cn/editor/draf…
@Query(value = "select p.pid as pid,p.pname as pname,p.psex as psex,p.getmarried as getmarried," + "b.bid as bid,b.bname as bname,b.bprice as bprice from Person p inner join Book b on p.pid=b.pid " + "where p.pid=:pid") List<PersonInfo> findAllInfo(@Param("pid") String pid); @Query(value = "select p.pid as pid,p.pname as pname,p.psex as psex,p.getmarried as getmarried," + "b.bid as bid,b.bname as bname,b.bprice as bprice from Person p inner join Book b on p.pid=b.pid " + "where p.pid=:pid") List<Object> findAllInfo1(@Param("pid") String pid); @Query(value = "select p.pid as pid,p.pname as pname,p.psex as psex,p.getmarried as getmarried," + "b.bid as bid,b.bname as bname,b.bprice as bprice from Person p inner join Book b on p.pid=b.pid " + "where p.pid=:pid") List<Map<String,Object>> findAllInfo2(@Param("pid") String pid);
QueryDSL的简单介绍
QueryDSL仅仅是一个通用的查询框架,专注于通过javaAPI构建类型安全的Sql查询,也可以说QueryDSL是基于各种ORM框架以及Sql之上的一个通用的查询框架,QueryDSL的查询,类似于SQL查询,很全面只不过一个是用SQL一个是用代码来代替SQL 。
- 建议
单表乃至简单的多表操作,都不推荐使用QueryDSL,使用JPA自带API简洁又效率,但是涉及太复杂的查询,推荐使用QueryDSL。参考资料。www.querydsl.com/static/quer…