拷贝demo-web1 另存为demo-jpa
学习参考:
https://blog.csdn.net/wujiaqi0921/article/details/78789087
https://blog.csdn.net/trntaken/article/details/77870803
注意:
DemoApplication所在的包要能访问到其他类,包括实体、service、dao
目标
- jpa实现简单crud
- 分页和排序
- 查询规范
- 复杂查询支持原生sql
step 1:添加依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.41</version>
</dependency>
step 2 配置mysql数据源以及JPA
配置数据源,依次为地址、用户名、密码、驱动、最大连接数
spring.datasource.driverClassName = com.mysql.jdbc.Driver
spring.datasource.url = jdbc:mysql://localhost:3306/mysql?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC
spring.datasource.username = root
spring.datasource.password = mysql
spring.datasource.tomcat.max-active=20
配置JPA
从上往下依次数据源mysql、显示ddl语句、自动执行ddl语句(更新、创建或者销毁、创建)
最后两句表示自动在数据库创建实体的表
spring.jpa.database=mysql
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=update
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL55Dialect
spring.jpa.hibernate.naming.physical-
strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
配置说明
ddl-auto:create----每次运行该程序,没有表格会新建表格,表内有数据会清空
ddl-auto:create-drop----每次程序结束的时候会清空表
ddl-auto:update----每次运行程序,没有表格会新建表格,表内有数据不会清空,只会更新
ddl-auto:validate----运行程序会校验数据与数据库的字段类型是否相同,不同会报错
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL55Dialect
修改引擎为innodb
spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl 实体类的属性名与表字段名相同
step 3编写实体
1)主键为自增长类型
package com.example.demo.domain;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
/**
* 类对应数据库表
* 属性对应数据库里的字段
* @author t460p
*
*/
@Entity
@Table(name="t_person")
public class Person {
//id应该是主键
//@Id标明该字段是主键
//GenerationType.IDENTITY标明他是自增长类型,用int类型来接
@Id
@Column(name = "id")
@GeneratedValue(strategy=GenerationType.IDENTITY)
private int id;
@Column(name="name",length=32,nullable=false)
private String name;
@Column(name="age")
private int age;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
2)主键为32位的uuid
@GenericGenerator注解配合@GeneratedValue一起使用,@GeneratedValue注解中的"generator"属性要与@GenericGenerator注解中name属性一致,strategy属性表示hibernate的主键生成策略
package com.neuedu.demo.domain;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import org.hibernate.annotations.GenericGenerator;
@Entity
@Table(name="t_person")
@GenericGenerator(name = "jpa-uuid", strategy = "uuid")
public class Person {
@Id
@GeneratedValue(generator = "jpa-uuid")
@Column(length = 32)
private String id;
@Column(name = "name", nullable = true, length = 20)
private String name;
@Column(name = "age", nullable = true, length = 4)
private int age;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
step 4 创建接口
package com.neuedu.demo.dao;
import org.springframework.data.jpa.repository.JpaRepository;
import com.neuedu.demo.domain.Person;
public interface PersonRepository extends JpaRepository<Person, String> {
}
step 5然后写一个rest接口以供测试使用。##
package com.neuedu.demo.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.neuedu.demo.dao.PersonRepository;
import com.neuedu.demo.domain.Person;
@RestController
@RequestMapping(value = "/person")
public class PerconController {
@Autowired
private PersonRepository personRepository;
@RequestMapping(path = "/addPerson")
public String addPerson(Person person) {
personRepository.save(person);
return "success";
}
@RequestMapping(path = "/deletePerson")
public String deletePerson(String id) {
personRepository.deleteById(id);
return "success";
}
}
运行:
http://localhost/haha/person/addPerson?name=test1&age=18
http://localhost/haha/person/deletePerson?id=4028a681682607d40168260a45ae0000
自动建表,插入删除成功。
修改和查询所有##
修改和添加的区别是修改的请求参数里带有主键id.
PersonRepository personRepository;
public void add(Person p) {
Person dbp=personRepository.getOne(p.getId);
System.out.println(dbp.getId);
personRepository.save(dbp);
List<Person> plist=personRepository.findAll();
for(Person item:plist){
System.out.println(item.getName());
}
System.out.println("--------------->"+p.getId());
}
分页排序
不带排序的
PageRequest.of(currentPage-1, pageSize)
带排序的
Sort sort=Sort.by(Sort.Direction.ASC, "age");
Pageable page=PageRequest.of(currentPage-1, pageSize, sort);
package com.neuedu.demo.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.neuedu.demo.dao.PersonRepository;
import com.neuedu.demo.domain.Person;
public Page<Person2> findAllPages(int currentPage,int pageSize){
Pageable page=PageRequest.of(currentPage-1, pageSize);
Page<Person2> pageData=dao.findAll(page);
return pageData;
}
@RequestMapping("findAllSort")
public Page<Person2> findAllSort(int currentPage,int pageSize){
Sort sort=Sort.by(Sort.Direction.ASC, "age");
Pageable page=PageRequest.of(currentPage-1, pageSize, sort);
Page<Person2> pageData=dao.findAll(page);
return pageData;
}
页面打印结果:###
{"content":[{"id":"402880ed771dc3c501771dc4355b0000","name":"zhangzq","age":19},{"id":"402880ed771dc3c501771dc4355b0001","name":"wangqj","age":29}],"pageable":{"sort":{"sorted":true,"unsorted":false,"empty":false},"offset":0,"pageNumber":0,"pageSize":2,"paged":true,"unpaged":false},"totalPages":1,"totalElements":2,"last":true,"number":0,"size":2,"sort":{"sorted":true,"unsorted":false,"empty":false},"numberOfElements":2,"first":true,"empty":false}
查询规范
默认方法如果不能满足,可以通过扩展接口里的方法实现特定查询。接口中名如果满足以下规范,只需要写接口,无须写实现类。这种是约定编程
https://blog.csdn.net/weixin_40344177/article/details/78469815
如service中调用如下方法:
List<Person> plist=personRepository.findByNameLike("%wa%");
for(Person item:plist){
System.out.println(item.getName());
}
接口中增加如下方法定义
public interface PersonRepository extends JpaRepository<Person, String> {
List<Person> findByNameLike(String string);
}
掌握上面技术已经可以满足大部分查询。复杂查询如何解决?
复杂查询@Query
https://blog.csdn.net/u010775025/article/details/80510596
例子:
controller
@RequestMapping("/query.do")
public String findQuery(String name) {
List<Object> users=personService.query(name);
for(Object u:users){
System.out.println(u);
}
return "Hello World";
}
PersonService.java
public List<Object> query(String name) {
return personRepository.findUserAndRole("%"+name+"%");
}
PersonRepository.java
@Query(value="select a.userid,a.username,a.userpwd,a.email,b.rolename from t_user a,t_roles b"+
" where a.roleid=b.roleid "+
" and a.username like ?1 ",nativeQuery=true)
List<Object> findUserAndRole(@Param("username") String username);
jquery测试页面
<script type="text/javascript" src="<%=request.getContextPath()%>/js/jquery-1.11.2.min.js"></script>
<script>
$(function(){
alert("jquery调用 ");
$.ajax({
url: "<%=request.getContextPath()%>/query.do",
//data: "name=w",
data: {name:"w"},
dataType: "json",
cache: false,
success: function(data){
$.each(data, function (i) {
alert(data[i][1]);
});
}
});
})
</script>
复杂表关系,关联映射
请学习hibernate实体类映射知识
如果@Query注解加上nativeQuery=true 则查询语句使用原生sql,不加则使用HQL
https://blog.csdn.net/shuixiou1/article/details/80086013
作业
添加用户,添加角色,为用户赋权限,查询用户及权限