创建spring boot项目可以看(一)
1.我们先在springboot 项目的pom.xml 添加访问mysql所需要的包关联。
2.然后在 application.properties 写上 自己数据库信息
3.建立一个实体User
package com.example.entity;
import java.util.Date;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import org.hibernate.annotations.GenericGenerator;
@Entity
@Table(name = "user")
public class User {
@Id
@GeneratedValue(generator="system-uuid")
@GenericGenerator(name="system-uuid", strategy="uuid")
private String id;
private String name;
private int age;
@Temporal(TemporalType.DATE)
private Date birthday;
@Temporal(TemporalType.TIMESTAMP)
private Date sendtime; // 日期类型,格式:yyyy-MM-dd HH:mm:ss
private String workAddress;
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;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public Date getSendtime() {
return sendtime;
}
public void setSendtime(Date sendtime) {
this.sendtime = sendtime;
}
public String getWorkAddress() {
return workAddress;
}
public void setWorkAddress(String workAddress) {
this.workAddress = workAddress;
}
}
4.我们建立一个dao 继承jpa的JpaRepository
package com.example.dao.sys;
import org.springframework.data.jpa.repository.JpaRepository;
import com.example.entity.User;
public interface DemoDao extends JpaRepository{
}
我们打开 jpa的 JpaRepository,发现其实他已经封装好了大部分的常用的方法
package org.springframework.data.jpa.repository;
import java.util.List;
import javax.persistence.EntityManager;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Sort;
import org.springframework.data.repository.NoRepositoryBean;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.data.repository.query.QueryByExampleExecutor;
/**
* JPA specific extension of {@link org.springframework.data.repository.Repository}.
*
* @author Oliver Gierke
* @author Christoph Strobl
* @author Mark Paluch
*/
@NoRepositoryBean
public interface JpaRepository extends PagingAndSortingRepository, QueryByExampleExecutor {
List findAll();
List findAll(Sort sort);
List findAllById(Iterable ids);
List saveAll(Iterable entities);
void flush();
S saveAndFlush(S entity);
void deleteInBatch(Iterable entities);
void deleteAllInBatch();
T getOne(ID id);
@Override
List findAll(Example example);
@Override
List findAll(Example example, Sort sort);
}
我们可以直接就使用
package com.example;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import com.example.dao.CustomRepositoryFactoryBean;
import com.example.dao.sys.DemoDao;
import com.example.entity.User;
@Controller
@SpringBootApplication
public class SpringBootDemoApplication{
@Autowired
public DemoDao dao;
@RequestMapping("/home")
public String home() {
System.out.println("hello");
List findAll = dao.findAll();
for (User user : findAll) {
System.out.println(user.getName());
}
return "hello";
}
public static void main(String[] args) {
SpringApplication.run(SpringBootDemoApplication.class, args);
}
}
一,根据JpaRepository 规则扩展方法,
package com.example.dao.sys;
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import com.example.entity.User;
public interface DemoDao extends JpaRepository{
List findUserByName(String name);
@Query("select e from User e where name=?1")
List getUserList(String name);
@Query("select e from User e where name=:name")
List getUserList2(@Param("name") String name);
}
详细扩展规则 可以看别人的文章 https://www.cnblogs.com/baoyi/p/SpringBootData_JPA.html
我测试时发现 @Query 里面写的是hql,写sql会报错
二,自定义 JpaRepository 扩展,比如说 建立一个自己基础JpaRepository ,既有JpaRepository 自有的方法,也要有自己定义的共有方法,分页查询
自定义的page.java
package com.example.entity;
import java.util.Collections;
import java.util.List;
/**
* 分页查询参数
*/
public class Page {
/** 页码 */
protected int pageNo = 1;
/** 每页数据 */
protected int pageSize = 20;
/** 返回结果 */
protected List result = Collections.emptyList();
/** 数据总数 */
protected long totalCount = -1;
/**
* 获得当前页的页号,序号从1开始,默认为1.
*/
public int getPageNo() {
return pageNo;
}
/**
* 设置当前页的页号,序号从1开始,低于1时自动调整为1.
*/
public void setPageNo(final int pageNo) {
this.pageNo = pageNo;
if (pageNo < 1) {
this.pageNo = 1;
}
}
public Page pageNo(final int thePageNo) {
setPageNo(thePageNo);
return this;
}
/**
* 获得每页的记录数量
*/
public int getPageSize() {
return pageSize;
}
/**
* 设置每页的记录数量,低于1时一页显示全部记录.
*/
public void setPageSize(final int pageSize) {
this.pageSize = pageSize;
}
public Page pageSize(final int thePageSize) {
setPageSize(thePageSize);
return this;
}
public List getResult() {
return result;
}
public void setResult(List result) {
this.result = result;
}
public Page result(List result) {
setResult(result);
return this;
}
public long getTotalCount() {
return totalCount;
}
public void setTotalCount(long totalCount) {
this.totalCount = totalCount;
}
public Page totalCount(long totalCount) {
setTotalCount(totalCount);
return this;
}
/**
* 根据pageNo和pageSize计算当前页第一条记录在总结果集中的位置,序号从1开始.
*/
public int getFirst() {
return (this.totalCount == 0) ? 0 : ((pageNo - 1) * pageSize) + 1;
}
public long getTotalPages() {
if (totalCount < 0)
return 0;
long count = totalCount / pageSize;
if (totalCount % pageSize > 0) {
count++;
}
return count;
}
}
1.我们先建立一个基础CustomRepositor 接口,继承JpaRepository ,写上自定义的方法名
package com.example.dao;
import java.io.Serializable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.repository.NoRepositoryBean;
import com.example.entity.Page;
/**
* 基础数据库操作接口 ---自定义Repository方法接口
*
* @author Long 2018年3月19日 上午11:09:06@param 实体entity 2018年3月19日
* 上午11:09:06@param 实体ID类型
*/
@NoRepositoryBean
public interface CustomRepositor extends JpaRepository {
/**
* 执行ql语句,封装自定义 分页page
*
* @param page
* 自定义page
* @param hql
* qlString 基于jpa标准的ql语句
* @param countHql
* 额外查询获取总记录数,使用默认则填null
* @return
*/
public Page findPage(final Page page, final String hql, final String countHql);
}
2.建立实现类CustomRepositoryImpl
package com.example.dao;
import java.io.Serializable;
import javax.persistence.EntityManager;
import javax.persistence.Query;
import org.springframework.data.jpa.repository.support.SimpleJpaRepository;
import org.springframework.util.Assert;
import com.example.entity.Page;
public class CustomRepositoryImpl extends SimpleJpaRepository
implements CustomRepositor {
/**
* 持久化上下文
*/
private final EntityManager entityManager;
public CustomRepositoryImpl(Class domainClass, EntityManager em) {
super(domainClass, em);
this.entityManager = em;
}
public Page findPage(Page page, String hql, String countHql) {
Assert.notNull(hql, "findPage() hql must not be null!");
Assert.notNull(page, "findPage() page must not be null!");
Query query = entityManager.createQuery(hql);
Long totalCount = (long) -1;
if(countHql == null || countHql ==""){
totalCount = (long) query.getResultList().size();
}else{
Query countQuery = this.entityManager.createQuery(countHql,Long.class);
totalCount = (Long) countQuery.getSingleResult();
}
if (page != null) { // 分页
// firstResult的序号从0开始
query.setFirstResult(page.getFirst() - 1);
if (page.getPageSize() != -1)
query.setMaxResults(page.getPageSize());
}
page.setResult(query.getResultList());
page.setTotalCount(totalCount);
return page;
}
}
3.创建一个自定义的FactoryBean去替代默认的工厂类, 使其加载CustomRepositoryImpl
package com.example.dao;
import java.io.Serializable;
import javax.persistence.EntityManager;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.support.JpaRepositoryFactory;
import org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean;
import org.springframework.data.repository.core.RepositoryInformation;
import org.springframework.data.repository.core.RepositoryMetadata;
import org.springframework.data.repository.core.support.RepositoryFactorySupport;
/**
* 创建一个自定义的FactoryBean去替代默认的工厂类
*
* @author Long 2018年3月20日 下午2:07:02@param 2018年3月20日 下午2:07:02@param
* 2018年3月20日 下午2:07:02@param
*/
public class CustomRepositoryFactoryBean, T, I extends Serializable>
extends JpaRepositoryFactoryBean {
public CustomRepositoryFactoryBean(Class extends R> repositoryInterface) {
super(repositoryInterface);
// TODO Auto-generated constructor stub
}
@SuppressWarnings("rawtypes")
protected RepositoryFactorySupport createRepositoryFactory(EntityManager em) {
return new CustomRepositoryFactory(em);
}
// 创建一个内部类,该类不用在外部访问
private static class CustomRepositoryFactory extends JpaRepositoryFactory {
private final EntityManager em;
public CustomRepositoryFactory(EntityManager em) {
super(em);
this.em = em;
}
// 设置具体的实现类是BaseRepositoryImpl
@Override
protected Object getTargetRepository(RepositoryInformation information) {
return new CustomRepositoryImpl((Class) information.getDomainType(), em);
}
// 设置具体的实现类的class
protected Class> getRepositoryBaseClass(RepositoryMetadata metadata) {
return CustomRepositoryImpl.class;
}
}
}
4.我们的dao继承我们扩展后的Repositor
package com.example.dao.sys;
import java.util.List;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import com.example.dao.CustomRepositor;
import com.example.entity.User;
public interface DemoDao extends CustomRepositor{
List findUserByName(String name);
@Query("select e from User e where name=?1")
List getUserList(String name);
@Query("select e from User e where name=:name")
List getUserList2(@Param("name") String name);
}
最后在启动类上指定自己的工厂类,就可以运行了
注:如果报错找不到实现类,或者bean自动注入失败,留意一下配置类的包位置,应该和这些 dao类实现类等需spring注入类
同b包 或 上层包。比如我的@EnableJpaRepositories(repositoryFactoryBeanClass = CustomRepositoryFactoryBean.class) 写在启动类,位于最外层(默认扫描启动类同包及以下)。当然,也可以通过@ComponentScan(basePackages="")指定
也有人喜欢额外建立配置类,不写在启动类上,如
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.data.web.config.EnableSpringDataWebSupport;
@Configuration
@EnableJpaRepositories(repositoryFactoryBeanClass = CustomRepositoryFactoryBean.class)
@EnableSpringDataWebSupport
public class JpaDataConfig {
}
这时候就要把这个类放在dao包里面或外面