配置文件-数据库配置XML
需要使用到的包框架
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/data/jpa
http://www.springframework.org/schema/data/jpa/spring-jpa.xsd">
<!-- 扫描spring service注解 repostory注解-->
<context:component-scan base-package="cn.itsource.aisell"></context:component-scan>
<!--jdbc.properties dataSource EntityManagerFactory Transaction-->
<!-- 加载配置jdbc.properties-->
<context:property-placeholder location="classpath:jdbc.properties"/>
<!-- 配置连接池dataSource bean生命周期方法 销毁方法close 用来连接之后 还给链接池-->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${jdbc.driverClassName}"></property>
<property name="url" value="${jdbc.url}"></property>
<property name="username" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean>
<!-- 得到EntityManagerFactory 方言 链接池-->
<!-- 得到EntityManagerFactory-->
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<!-- 配置属性 setDataSource-->
<property name="dataSource" ref="dataSource"></property>
<!-- 扫描实体类的配置 entity-->
<property name="packagesToScan" value="cn.itsource.aisell.domain"></property>
<property name="jpaVendorAdapter" >
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<!-- 是否显示sql-->
<property name="showSql" value="true"></property>
<!-- 是否创建表-->
<property name="generateDdl" value="true"></property>
<!--数据库方言-->
<property name="databasePlatform" value="org.hibernate.dialect.MySQLDialect"></property>
</bean>
</property>
</bean>
<!-- 事务管理器-->
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"></property>
</bean>
<!-- 开启事务 扫描@Transaction这种注解-->
<tx:annotation-driven/>
<!-- springdatajpa配置 引入事务和实体管理工厂-->
<jpa:repositories base-package="cn.itsource.aisell.repository"
transaction-manager-ref="transactionManager"
entity-manager-factory-ref="entityManagerFactory"
factory-class="cn.itsource.aisell.repository.impl.BaseRepositoryFactoryBean">
</jpa:repositories>
<bean id="myBean" class="cn.itsource.aisell.bean.Mybean"></bean>
</beans>```
<?xml version="1.0" encoding="UTF-8"?>
<mvc:default-servlet-handler />
<context:component-scan base-package=“cn.itsource.aisell.web.controller” />
mvc:annotation-driven
mvc:message-converters
application/json; charset=UTF-8
application/x-www-form-urlencoded; charset=UTF-8
</mvc:message-converters>
</mvc:annotation-driven>
<!-- ViewResolver 视图解析器 (struts2视图类型类似) -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 设置视图路径的前后缀,该配置可以让我们写视图路径的时候更简单。 -->
<!-- 希望跳转jsp是[/WEB-INF/views/前缀][xxx变量][.jsp后缀] -->
<!-- * @see #setPrefix -->
<property name="prefix" value="/WEB-INF/views/" />
<!-- * @see #setSuffix -->
<property name="suffix" value=".jsp" />
</bean>
<!-- 错误:提示告诉开发者你没有配置文件上传解析器。 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 设置上传文件的最大尺寸为1MB -->
<property name="maxUploadSize">
<value>1048576</value>
</property>
</bean>
``` 数据库连接
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql:///aisell
jdbc.username=root
jdbc.password=123456
bean层
package cn.itsource.aisell.bean;
import org.springframework.beans.factory.InitializingBean;
public class Mybean implements InitializingBean {
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("-----------------------");
}
}
common层
package cn.itsource.aisell.common;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
public class CustomMapper extends ObjectMapper {
public CustomMapper() {
this.setSerializationInclusion(JsonInclude.Include.NON_NULL);
// 设置 SerializationFeature.FAIL_ON_EMPTY_BEANS 为 false 对null的bean 不做序列化
this.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
//return new ObjectMapper().disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
}
}
——————————————————————————————————————————————————
package cn.itsource.aisell.common;
import org.springframework.data.domain.Page;
import java.util.List;
/**
* 分页对象
* total
* rows
*/
public class UiPage {
//总数
private Long total;
//每页数据
private List rows;
public UiPage(){}
public UiPage(Page page) {
//
this.total = page.getTotalElements();
this.rows = page.getContent();
}
public Long getTotal() {
return total;
}
public void setTotal(Long total) {
this.total = total;
}
public List getRows() {
return rows;
}
public void setRows(List rows) {
this.rows = rows;
}
}
domain层
package cn.itsource.aisell.domain;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.MappedSuperclass;
/**
* 公共的domain
*
*/
@MappedSuperclass //JPA它不会在数据库创建表 不持久化到数据库里面
public class BaseDomain {
@Id
@GeneratedValue
public Long id;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
}
————————————————————————————————————————————————————
package cn.itsource.aisell.domain;
import javax.persistence.Entity;
@Entity
public class Department extends BaseDomain {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
————————————————————————————————————————
package cn.itsource.aisell.domain;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
@Entity
public class Employee extends BaseDomain {
private String username;
private String password;
private String email;
private Integer age;
//头像
private String headImage;
public String getHeadImage() {
return headImage;
}
public void setHeadImage(String headImage) {
this.headImage = headImage;
}
//员工和部门 多对一关系
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name="department_id")
// @JsonIgnoreProperties(value={"hibernateLazyInitializer","handler","fieldHandler"})
private Department department;
public Department getDepartment() {
return department;
}
public void setDepartment(Department department) {
this.department = department;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "Employee{" +
"username='" + username + '\'' +
", password='" + password + '\'' +
", email='" + email + '\'' +
", age=" + age +
", id=" + id +
"} ";
}
}
query层网页配置
package cn.itsource.aisell.query;
import cn.itsource.aisell.domain.Employee;
import com.github.wenhao.jpa.Specifications;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
/**
* BaseQuery: 公共查询对象(完成分页查询和排序)
* currentPage pageSize
*
* 排序字段 按照字段Age 排序类型 ASC /DESC
*
*/
public abstract class BaseQuery {
private Integer currentPage=1;//当前页
private Integer pageSize=10;//每页条数
private String orderByName;//排序字段
private String orderByType="DESC";//排序类型
public Integer getCurrentPage() {
return currentPage;
}
//在查询里面使用
public Integer getJpaPage(){
return currentPage -1;
}
public void setCurrentPage(Integer currentPage) {
this.currentPage = currentPage;
}
public Integer getPageSize() {
return pageSize;
}
public void setPageSize(Integer pageSize) {
this.pageSize = pageSize;
}
public String getOrderByName() {
return orderByName;
}
public void setOrderByName(String orderByName) {
this.orderByName = orderByName;
}
public String getOrderByType() {
return orderByType;
}
public void setOrderByType(String orderByType) {
this.orderByType = orderByType;
}
//排序方法 如果设置排序的字段 才进行排序 否则就不排序
public Sort createSort(){
Sort sort = null;
//排序字段
if(orderByName!= null){
/* Sort.Direction direction = null;
if(orderByType.equals("DESC")){
direction = Sort.Direction.DESC;
}else{
direction = Sort.Direction.ASC;
}*/
Sort.Direction type = "ASC".equals(orderByType.toUpperCase())? Sort.Direction.ASC:Sort.Direction.DESC;
//组装Sort
sort =new Sort(type,orderByName);
}
return sort;
}
//组装条件(拼装条件的方法) -- 让子类都必须覆写 --高级查询
//该方法定义成抽象的目的,让子类都必须覆写该方法
public abstract Specification createSpecification();
//添加两个方法 接收数据
public void setPage(Integer page){
this.currentPage = page;
}
//接收每页条数
public void setRows(Integer rows){
this.pageSize = rows;
}
}
——————————————————————————————————————
package cn.itsource.aisell.query;
import org.springframework.data.jpa.domain.Specification;
public class DepartmentQuery extends BaseQuery {
@Override
public Specification createSpecification() {
return null;
}
}
————————————————————————————————————————
package cn.itsource.aisell.query;
import cn.itsource.aisell.domain.Employee;
import com.github.wenhao.jpa.Specifications;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.jpa.domain.Specification;
/**
* 单独的查询对象
* EmployeeQuery
* DepartmentQuery
*
* EmployeeController search(EmployeeQuery query)
*
*
*/
public class EmployeeQuery extends BaseQuery{
/**
* username admin
* email xx@qq.com
* departmentId 1
*/
//自身条件
private String username;
private String email;
private Integer age;
private Integer departmentId;
public Integer getDepartmentId() {
return departmentId;
}
public void setDepartmentId(Integer departmentId) {
this.departmentId = departmentId;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
//抽取查询
@Override
public Specification createSpecification() {
Specification<Employee> spe = Specifications.<Employee>and().
like(StringUtils.isNotBlank(username), "username", "%" + username + "%")
.like(StringUtils.isNotBlank(email), "email", "%" + email + "%")
.eq(departmentId!=null,"department.id",departmentId)
.gt(age != null, "age", age)
.build();
return spe;
}
}
repository分配数据
package cn.itsource.aisell.repository;
import cn.itsource.aisell.query.BaseQuery;
import org.springframework.data.domain.Page;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.repository.NoRepositoryBean;
import java.io.Serializable;
import java.util.List;
/**
* 自定义公共的接口
* NoRepositoryBean 防止底层去找SimpleJpaRepository的实现类 ,我们需要找自己的实现类
*
*/
@NoRepositoryBean
public interface BaseRepository<T,ID extends Serializable> extends JpaRepository<T,ID>, JpaSpecificationExecutor<T> {
//根据Query拿到分页对象(分页)
Page findPageByQuery(BaseQuery baseQuery);
//根据Query拿到对应的所有数据(不分页)
List<T> findByQuery(BaseQuery baseQuery);
//根据jpql与对应的参数拿到数据
List findByJpql(String jpql,Object... values);
}
————————————————————————————————————
package cn.itsource.aisell.repository;
import cn.itsource.aisell.domain.Department;
public interface DepartmentRepository extends BaseRepository<Department,Long> {
}
————————————————————————————————————————
package cn.itsource.aisell.repository;
import cn.itsource.aisell.domain.Employee;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import java.util.List;
/**
* SpringDataJpa提供的接口JpaRepository
*
* T:实体的类型
* ID:实体里面主键的类型
*
*
*/
public interface EmployeeRepository extends JpaRepository<Employee,Long> {
/**
* 单表查询OK --比较方便
* 多表查询 -- @Query注解查询
*
*/
//想通过员工的名称来查询员工 -- 如果按照一定的规范来写 底层就会解析完成
List<Employee> findEmployeeByUsername(String username);
//LIKE查询
List<Employee> findEmployeeByUsernameLike(String username);
//查询数据--Query注解查询
@Query("select o from Employee o where o.username like ?1 ")
List<Employee> findEmpByUsername(String username);
//根据顺序查询
@Query("select o from Employee o where o.username like ?1 and o.email like ?2")
List<Employee> query02(String username1,String email1);
//根据名称来查询
@Query("select o from Employee o where o.username like :username and o.email like :email")
List<Employee> query03(@Param("username") String username1, @Param("email")String email1);
//对原生sql语句
@Query(value="select count(*) from employee ",nativeQuery=true)
Long query04();
}
——————————————————————————————————————
package cn.itsource.aisell.repository;
import cn.itsource.aisell.domain.Employee;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import java.util.List;
/**
* SpringDataJpa提供的接口JpaRepository
*
* T:实体的类型
* ID:实体里面主键的类型
*
*
*/
public interface EmployeeRepository1 extends JpaRepository<Employee,Long>,
JpaSpecificationExecutor<Employee> {
}
___________________________________________________________________
package cn.itsource.aisell.repository;
import cn.itsource.aisell.domain.Employee;
public interface EmployeeRepository2 extends BaseRepository<Employee,Long> {
}
repository.impl
package cn.itsource.aisell.repository.impl;
import org.springframework.data.jpa.repository.support.JpaRepositoryFactory;
import org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean;
import org.springframework.data.repository.Repository;
import org.springframework.data.repository.core.RepositoryInformation;
import org.springframework.data.repository.core.RepositoryMetadata;
import org.springframework.data.repository.core.support.RepositoryFactorySupport;
import javax.persistence.EntityManager;
import java.io.Serializable;
/**
* BaseRepositoryFactoryBean --FactoryBean
* JpaRepositoryFactoryBean --提供的FactoryBean
* 写一个类去继承 JpaRepositoryFactoryBean --Spring就会自动调用createRepositoryFactory
*
*/
public class BaseRepositoryFactoryBean<T extends Repository<S, ID>, S, ID extends Serializable>
extends JpaRepositoryFactoryBean<T,S,ID> {
@Override
protected RepositoryFactorySupport createRepositoryFactory(EntityManager entityManager) {
return new MyRepositoryFactory<T,ID>(entityManager); //注:这里创建是我们的自定义类
}
//继承JpaRepositoryFactory后,把返回的对象修改成我们自己的实现
private static class MyRepositoryFactory<T,ID extends Serializable> extends JpaRepositoryFactory {
private final EntityManager entityManager;
/**
* Creates a new {@link JpaRepositoryFactory}.
*
* @param entityManager must not be {@literal null}
*/
public MyRepositoryFactory(EntityManager entityManager) {
super(entityManager);
this.entityManager = entityManager;
}
//这里返回最后的功能对象 --最终Spring调用方法返回的对象 -->得到对最终的对象
//factoryBean 默认调用getObject -- 现在调用getTargetRepository
@Override
protected Object getTargetRepository(RepositoryInformation information) {
return new BaseRepositoryImpl<T,ID>((Class<T>)information.getDomainType(),entityManager);
}
//确定功能对象的类型
@Override
protected Class<?> getRepositoryBaseClass(RepositoryMetadata metadata) {
return BaseRepositoryImpl.class;
}
}
}
————————————————————————————————————————
package cn.itsource.aisell.repository.impl;
import cn.itsource.aisell.query.BaseQuery;
import cn.itsource.aisell.repository.BaseRepository;
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.data.jpa.domain.Specification;
import org.springframework.data.jpa.repository.support.JpaEntityInformation;
import org.springframework.data.jpa.repository.support.SimpleJpaRepository;
import javax.persistence.EntityManager;
import javax.persistence.Query;
import java.io.Serializable;
import java.util.List;
/**
* 泛型的上限 ID
* Serializable 序列化 用来网络传输
* extends SimpleJpaRepository -- 不会覆写springdatajpa本身的方法
* implements BaseRepository 实现自身的方法
*
* 底层springdatajpa找SimpleJpaRepository 但是现在需要让JPA找BaseRepositoryImpl
* --FactoryBean
*
*/
public class BaseRepositoryImpl<T,ID extends Serializable> extends SimpleJpaRepository<T,ID>
implements BaseRepository<T,ID> {
//让spring把entityManager给我注入过来 --factoryBean
private final EntityManager entityManager;
//必需要实现父类的这个构造器
public BaseRepositoryImpl(Class<T> domainClass, EntityManager em) {
super(domainClass, em);
this.entityManager = em;
}
//分页查询的方法
@Override
public Page findPageByQuery(BaseQuery baseQuery) {
//得到Sort
Sort sort = baseQuery.createSort();
//条件
Specification spec = baseQuery.createSpecification();
//分页
Pageable pageable = new PageRequest(baseQuery.getJpaPage(),baseQuery.getPageSize() , sort);
//查询
Page<T> page = super.findAll(spec,pageable);
return page;
}
//不分页
@Override
public List<T> findByQuery(BaseQuery baseQuery) {
Sort sort = baseQuery.createSort();
Specification specs = baseQuery.createSpecification();
//条件和排序
List<T> list = super.findAll(specs,sort);
return list;
}
@Override
public List findByJpql(String jpql, Object... values) {
//得到query对象
Query query = entityManager.createQuery(jpql);
//设值
for (int i = 0; i < values.length; i++) {
query.setParameter(i+1,values[i] );
}
return query.getResultList();
}
}
在这里插入代码片