Spring Boot----SpringData
简介
Spring Data 项目的目的是为了简化构建基于Spring 框架应用的数据访问技术,包括非关系数据库、Map-Reduce 框架、云数据服务等等;另外也包含对关系数据库的访问支持。
SpringData特点
SpringData为我们提供使用统一的APl来对数据访问层进行操作;这主要是Spring Data Commons项目来实现的。Spring Data Commons让我们在使用关系型或者非关系型数据访问技术时都基于Spring提供的
统一标准,标准包含了CRUD(创建、获取、更新、删除)、查询、排序和分页的相关操作。
统一的Repository接口
Repository<T,ID extends Serializable>:统一接口
RevisionRepository<T,ID extends Serializable,N extends Number&Comparable<N>>:基于乐观锁机制
CrudRepository<T,ID extends Serializable>:基本CRUD操作
PagingAndSortingRepository<T,ID extends Serializable>:基本CRUD及分页
springBoot整合spring Date JPA:
Spring Date Jpa项目创建
1、创建项目
pom
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency>
application
server: port: 8888 servlet: context-path: / spring: datasource: url: jdbc:mysql://localhost:3306/xc_user?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true&useSSL=false username: root password: 123456 jpa: database: MySQL database-platform: org.hibernate.dialect.MySQL5InnoDBDialect #控制台显示show语句 show-sql: true #自动创建数据表结构或者更新 hibernate: ddl-auto: update
编写实体类
- spring jpa会自动帮我们在数据库创建表
@Entity //告诉jpa这是一个实体类(和数据表映射的类) @Table(name = "t_user") //指定和那个数据表对应,在数据库创建表的名字 public class User { @Id //主键 @GeneratedValue(strategy = GenerationType.IDENTITY) //自增主键 private Integer id; @Column(name = "username",length = 32) //如果数据库中定义的列名是userName,我们就可以使用@Column,@column(name="userName") private String username; }
编写dao
/*User:对应的实体类,Integer:id字段对应的属性*/ public interface UserDao extends JpaRepository<User,Integer> { }
运行
- 如果数据表不存在,就会自动创建
测试
@Autowired UserDao userDao; @Test public void test() { Optional<User> byId = userDao.findById(4); System.out.println(byId.get()); //User one = userDao.getOne(4); }
高级使用
注意:如果实体类不在本项目工程下(微服务)
需要在spring启动类上,用EntityScan到本项目中
@EntityScan(value="com.ihrm.domain.project")
实体类
@Entity @Table(name = "bs_user") @Getter @Setter @NoArgsConstructor public class User implements Serializable { private static final long serialVersionUID = 4297464181093070302L; /** * ID */ @Id private String id; /** * 手机号码 */ @ExcelAttribute(sort = 2) private String mobile; /** * 密码 */ private String password; /** * 创建时间 */ private Date createTime; /** * JsonIgnore * : 忽略json转化 * Role实体类中有User对象,如果不忽略,就会死循环,进行字段序列化 */ @JsonIgnore @ManyToMany @JoinTable(name="pe_user_role",joinColumns={@JoinColumn(name="user_id",referencedColumnName="id")}, inverseJoinColumns={@JoinColumn(name="role_id",referencedColumnName="id")} ) private Set<Role> roles = new HashSet<Role>();//用户与角色 多对多 }
JpaSpecificationExecutor使用
1、继承
public interface UserDao extends JpaRepository<User,String>, JpaSpecificationExecutor<User> { User findByMobile(String mobile); }
2、使用
/** * 查询全部用户列表 */ public Page<User> findAll(Map<String,Object> map, int page, int size){ //查询条件 Specification<User> spec = new Specification<User>() { /** * @param root :可以理解是数据库中的每一行数据 * @param query * @param cb * @return */ @Override public Predicate toPredicate(Root<User> root, CriteriaQuery<?> query, CriteriaBuilder cb) { List<Predicate> list = new ArrayList<>(); //比较companyId if (!StringUtils.isEmpty(map.get("companyId"))){ list.add(cb.equal(root.get("companyId").as(String.class) , (String)map.get("companyId"))); } if (!StringUtils.isEmpty(map.get("departmentId"))){ list.add(cb.equal(root.get("departmentId").as(String.class) , (String)map.get("departmentId"))); } if (!StringUtils.isEmpty(map.get("hasDept"))){ if ("0".equals((String) map.get("hasDept"))) { list.add(cb.isNull(root.get("departmentId")));//查找departmentId是空的 }else{ list.add(cb.isNotNull(root.get("departmentId")));//查找departmentId不是空的 } } return cb.and(list.toArray(new Predicate[list.size()])); } }; //分页 Page<User> pageUser = userDao.findAll(spec, new PageRequest(page-1, size)); return pageUser; }
spring date MongoDb:
spring Data MongoDB
基本配置使用
实体类
- 使用@Document注解
@Data @ToString @Document(collection = "cms_page") public class CmsPage { //站点ID private String siteId; //页面ID @Id private String pageId; }
dao接口
- 我们可以点进去MongoRespository,查看自带操作数据库的方法
public interface CmsPageRepository extends MongoRepository<CmsPage,String> { //根据页面名称查询 CmsPage findByPageName(String pageName); }
test
@SpringBootTest @RunWith(SpringRunner.class) public class CmsPageRepositoryTest { @Autowired CmsPageRepository cmsPageRepository; @Test public void test() { MongoClientURI connectionString = new MongoClientURI("mongodb://root:123@localhost:27017"); MongoClient mongoClient = new MongoClient(connectionString); MongoDatabase database = mongoClient.getDatabase("xc_cms"); MongoCollection<Document> collection = database.getCollection("cms_page(1)"); Document myDoc = collection.find().first(); String json = myDoc.toJson(); System.out.println(json); } @Test public void testFindAll() { List<CmsPage> all = cmsPageRepository.findAll(); System.out.println(all); } //分页查询 @Test public void testFindPage() { //分页参数 int page = 1;//从0开始 int size = 10; Pageable pageable = PageRequest.of(page, size); Page<CmsPage> all = cmsPageRepository.findAll(pageable); List<CmsPage> content = all.getContent(); System.out.println(content); } //修改 @Test public void testUpdate() { //查询对象 //Optional对象是jdk1.8出来的,目的是保障程序尽量能避免空指针的问题存在,和我们手动判断cmsPage!=null作用是一样的.(标准化) Optional<CmsPage> optional = cmsPageRepository.findById("5b4b1d8bf73c6623b03f8cec"); if (optional.isPresent()) { CmsPage cmsPage = optional.get(); //设置要修改值 cmsPage.setPageAliase("test01"); //... //修改 CmsPage save = cmsPageRepository.save(cmsPage); System.out.println(save); } } //根据页面名称查询 @Test public void testfindByPageName() { CmsPage cmsPage = cmsPageRepository.findByPageName("index_category.html"); System.out.println(cmsPage); } }
更多使用
自定义Dao方法
- 同Spring Data JPA一样Spring Data mongodb也提供自定义方法的规则,如下:
- 按照fndByXXX,findByXXXAndYYY、countByXXXAndYYY等规则定义方法,实现查询操作。
interface CmsPageRepository extends MongoRepository<CmsPage,String> { //根据页面名称查询 CmsPage findByPageName(String pageName); //根据页面名称和类型查询 CmsPage findByPageNameAndPageType(String pageName, String pageType); //根据站点和页面类型查询记录数 int countBySiteIdAndPageType(String siteId, String pageType); //根据站点和页面类型分页查询(Pageable是自带类) Page<CmsPage> findBySiteIdAndPageType(String siteId, String pageType, Pageable pageable); }
自定义条件查询测试
//自定义条件查询测试 @Test public void testFindAllByExample() { //分页参数 int page = 0;//从0开始 int size = 10; Pageable pageable = PageRequest.of(page,size); //条件值对象 CmsPage cmsPage= new CmsPage(); //要查询5a751fab6abb5044e0d19ea1站点的页面 // cmsPage.setSiteId("5b30b052f58b4411fc6cb1cf"); //设置模板id条件 // cmsPage.setTemplateId("5ad9a24d68db5239b8fef199"); //设置页面别名(默认是精确查询,我们在条件匹配器中定义了该字段设置为模糊查询了) cmsPage.setPageAliase("轮播"); //条件匹配器(设置页面别名) // ExampleMatcher exampleMatcher = ExampleMatcher.matching(); // exampleMatcher = exampleMatcher.withMatcher("pageAliase", ExampleMatcher.GenericPropertyMatchers.contains()); //ExampleMatcher.xxx:匹配规则 ExampleMatcher exampleMatcher = ExampleMatcher.matching() .withMatcher("pageAliase", ExampleMatcher.GenericPropertyMatchers.contains()); //ExampleMatcher.GenericPropertyMatchers.contains() 包含关键字(模糊匹配) // ExampleMatcher.GenericPropertyMatchers.startsWith()//前缀匹配(模糊匹配) //定义Example Example<CmsPage> example = Example.of(cmsPage,exampleMatcher); Page<CmsPage> all = cmsPageRepository.findAll(example, pageable); List<CmsPage> content = all.getContent(); System.out.println(content); }
JPA自定义Sql语句
public interface XcTaskRepository extends JpaRepository<XcTask,String> { //查询某个时间之间的前n条任务 Page<XcTask> findByUpdateTimeBefore(Pageable pageable, Date updateTime); //更新updateTime @Modifying @Query("update XcTask t set t.updateTime = :updateTime where t.id = :id") //XcTask 是类名,updateTime是类里面的字段名 public int updateTaskTime(@Param(value = "id") String id,@Param(value = "updateTime") Date updateTime); @Modifying @Query("update XcTask t set t.version = :version+1 where t.id = :id and t.version = :version") public int updateTaskVersion(@Param(value = "id") String id,@Param(value = "version") int version); }
自定义sql
// 自定义sql StringBuffer querySql = new StringBuffer("select * from biyelunwen_banji where name=:name "); // 生成Query Query query = entityManager.createNativeQuery(querySql.toString(),Banji.class); // 这种写法,返回的类,只能是@entity注解的类(sql中查询的表对应的类)。不能自定义返回自己需要的类 // 设置参数 query.setParameter("name","生物工程1班级"); // 对应 拼接的sql中的 参数名称 // 查询结果 List<Banji> list = query.getResultList();// 自定义sql StringBuffer querySql = new StringBuffer("select * from biyelunwen_banji where name=:name "); // 生成Query Query query = entityManager.createNativeQuery(querySql.toString(),Banji.class); // 这种写法,返回的类,只能是@entity注解的类(sql中查询的表对应的类)。不能自定义返回自己需要的类 // 设置参数 query.setParameter("name","生物工程1班级"); // 对应 拼接的sql中的 参数名称 // 查询结果 List<Banji> list = query.getResultList();
参考手册
https://docs.spring.io/spring-data/data-jpa/docs/current/reference/html/#reference