智能商贸java代码实现——学习笔记day02

结构图

Pepository层

自定义一个Repository, 它是JpaRepository的功能基础上继承增强

自定义接口

如自定义接口 BaseRepository 继承JpaRepository,增加自己想要的功能
然后在接口BaseRepository上加@NoRepositoryBean注解
这样Spring Data Jpa在启动时就不会去实例化(去实现)BaseRepository这个接口,而由自己写BaseRepositoryImpl去实现

自定义接口代码:

package com.wwy.repository;

import com.wangweiyu.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;
/**
 * 自定义一个Repository,     它是JpaRepository的功能基础上继承增强
 *
 * 在上面添加@NoRepositoryBean标注
 *                  这样Spring Data Jpa在启动时就不会去实例化BaseRepository这个接口
 *
 */
/*不能确定类型 所以写的泛型 <T,ID>*/
@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);
}

BaseRepositoryImpl功能实现

定义好自定义的方法后,我们现在通过一个基本的Repository类来实现该方法:
首先添加BaseRepositoryImpl类,继承SimpleJpaRepository类,使其拥有Jpa Repository的基本方法。
我们发现Repository有两个构造函数:
1 SimpleJpaRepository(JpaEntityInformation entityInformation, EntityManager entityManager)
2 SimpleJpaRepository(Class domainClass, EntityManager em)
这里我们实现第二个构造函数,拿到domainClass和EntityManager两个对象。

BaseRepositoryImpl代码

package com.wangweiyu.repository;

import com.wangweiyu.query.BaseQuery;
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.SimpleJpaRepository;

import javax.persistence.EntityManager;
import javax.persistence.Query;
import java.io.Serializable;
import java.util.List;

public class BaseRepositoryImpl<T,ID extends Serializable> extends SimpleJpaRepository<T,ID> implements BaseRepository<T,ID> {

    private final EntityManager entityManager;

    //必需要实现父类的这个构造器
    public BaseRepositoryImpl(Class<T> domainClass, EntityManager em) {
        super(domainClass, em);
        this.entityManager = em;
    }

    @Override
    public Page findPageByQuery(BaseQuery baseQuery) {
        //第一步:拿到所有高级查询条件
        Specification spec = baseQuery.createSpec();
        //第二步:拿到排序的值
        Sort sort = baseQuery.createSort();
        //第三步:根据条件查询分页数据并且返回
        Pageable pageable = new PageRequest(baseQuery.getCurrentPage_2(), baseQuery.getPageSize(),sort);
        Page<T> page = super.findAll(spec, pageable);
        return page;
    }

    @Override
    public List<T> findByQuery(BaseQuery baseQuery) {
        //第一步:拿到所有高级查询条件
        Specification spec = baseQuery.createSpec();
        //第二步:拿到排序的值
        Sort sort = baseQuery.createSort();
        //第三步:拿到数据返回
        return findAll(spec, sort);
    }

    @Override
    public List findByJpql(String jpql, Object... values) {
        //第一步:创建Query对象
        Query query = entityManager.createQuery(jpql);
        //第二步:把值设置到Query对象中去
        if (values!=null) {
            for (int i = 0; i < values.length; i++) {
                query.setParameter(i + 1, values[i]);
            }
        }
        //第三步:返回数据
        return query.getResultList();

    }
}

创建自定义创建自定义RepositoryFactoryBean

接下来创建一个自定义的RepositoryFactoryBean来代替默认的RepositoryFactoryBean

RepositoryFactoryBean负责返回一个RepositoryFactory,Spring Data Jpa 将使用RepositoryFactory来创建Repository具体实现,这里我们***用BaseRepositoryImpl代替SimpleJpaRepository作为Repository接口的实现***。这样我们就能够达到为所有Repository添加自定义方法的目的。
我们需要覆写创建RepositoryFactory的方法:createRepositoryFactory

package com.wangweiyu.repository;

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;

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;
        }
        //这里返回最后的功能对象
        @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;
        }
    }

}

然后配置applicationContext.xml

在xml配置文件加上 factory-class="com.wangweiyu.repository.BaseRepositoryFactoryBean"
这样就会自动去查找BaseRepositoryImpl实现层

  <jpa:repositories base-package="com.wangweiyu.repository"
                      entity-manager-factory-ref="entityManagerFactory"
                      transaction-manager-ref="transactionManager"
                      factory-class="com.wangweiyu.repository.BaseRepositoryFactoryBean"
    />

进行测试:看是否加入了增强功能

1 测试 PageByQuerry功能

/*
*测试BaseRepository 增加的功能
* */
    
        @Test
        public void test_Find() throws Exception{
            EmployeeQuery query = new EmployeeQuery();
            query.setUsername("1");

            Page<Employee> pageByQuery = employeeRepository.findPageByQuery(query);
            pageByQuery.forEach(employee -> System.out.println(employee));
        }

Query对象在之后的学习中会前台传过来,会简化此处代码

2 测试 findByQuery功能
同上,自行测试
3 测试 findByJpql功能
同上,自行测试

Service层

创建BaseService接口层——作为公共的Service抽取

BaseService代码

import org.springframework.data.domain.Page;
import java.io.Serializable;
import java.util.List;

public interface IBaseService<T,ID> extends Serializable {
    //添加与修改数据
    void save(T t);
    void delete(ID id);
    //查询数据
    T findOne(ID id);
    List<T> findAll();
    //根据Query拿到分页对象(分页)
    Page findPageByQuery(BaseQuery baseQuery);
    //根据Query拿到对应的所有数据(不分页)
    List<T> findByQuery(BaseQuery baseQuery);
    //根据jpql与对应的参数拿到数据
    List findByJpql(String jpql,Object... values);
}

BaseServiceImpl实现层代码

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.transaction.annotation.Transactional;
import java.io.Serializable;
import java.util.List;
import static org.springframework.transaction.annotation.Propagation.SUPPORTS;

@Transactional(readOnly = true,propagation = SUPPORTS)
public abstract class BaseServiceImpl<T,ID  extends Serializable> implements IBaseService<T,ID> {
    /**
     * BaseRepository接口会有很多实现
     *          EmployeeRepository<Employee,Long>,DepartmentRepository<Department,Long>,RoleRepository<Role,Long>
     *          EmployeeService extends BaseServiceImpl<Employee,Long>
     */
//注意  注入要写泛型
//:Spring 4.x 中可以为子类注入子类对应的泛型类型的成员变量的引用
    @Autowired
    private BaseRepository<T,ID> baseRepository;

    @Override
    @Transactional
    public void save(T t) {
        baseRepository.save(t);
    }

    @Override
    @Transactional
    public void delete(ID id) {
        baseRepository.delete(id);
    }

    @Override
    public T findOne(ID id) {
        return baseRepository.findOne(id);
    }

    @Override
    public List<T> findAll() {
        return baseRepository.findAll();
    }

    @Override
    public Page findPageByQuery(BaseQuery baseQuery) {
        return baseRepository.findPageByQuery(baseQuery);
    }

    @Override
    public List<T> findByQuery(BaseQuery baseQuery) {
        return baseRepository.findByQuery(baseQuery);
    }

    @Override
    public List findByJpql(String jpql, Object... values) {
        return baseRepository.findByJpql(jpql, values);
    }
}

IEmployeeService层——继承IBaseService接口

IEmployeeService

//这里做最简单的CRUD,在开发中,业务后期是有很多功能的。此处层需要以后再添加功能
public interface IEmployeeService extends IBaseService<Employee,Long> {
		//如,在第二天将添加CheckName功能: Boolean checkUsername(String username);
}

EmployeeServiceImpl实现层代码

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class EmployeeServiceImpl extends BaseServiceImpl<Employee,Long> implements IEmployeeService {

//    @Override
//    public Boolean checkUsername(String username) {
//        return null;
//    }
    @Autowired
    private EmployeeRepository employeeRepository;

    /**
     * 判断返回得到有相同名字得数量,大于等于1则不能改咯
     */
    @Override
    public Boolean checkUsername(String username) {
        return  !(employeeRepository.getCountByUsername(username)>0);
    }
}

集成SpringMVC

引入相应jar包

<!-- 引入web前端的支持 -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-web</artifactId>
    <version>${org.springframework.version}</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>${org.springframework.version}</version>
</dependency>

配置applicationContext-mvc.xml

为SpringMVC单独配置一个xml,把它与核心的applicationContext.xml分开。使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:mvc="http://www.springframework.org/schema/mvc"
       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/mvc
         http://www.springframework.org/schema/mvc/spring-mvc.xsd
    ">
    <!-- 对静态资源进行放行 -->
    <mvc:default-servlet-handler />
    <!-- 扫描controller部分的包 -->
    <!-- @Component组件, @Repository持久层, @Service业务逻辑层, and @Controller控制器 -->
    <context:component-scan base-package="com.wangweiyu.web" />
    <!-- 添加mvc对@RequestMapping等注解的支持 -->
    <mvc:annotation-driven >
        <mvc:message-converters>
            <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
                <property name="supportedMediaTypes">
                    <list>
                        <value>application/json; charset=UTF-8</value>
                        <value>application/x-www-form-urlencoded; charset=UTF-8</value>
                    </list>
                </property>
                <!-- No serializer:配置 objectMapper 为我们自定义扩展后的 CustomMapper,解决了返回对象有关系对象的报错问题 -->
                <property name="objectMapper">
                    <bean class="com.wangweiyu.common.CustomMapper"></bean>
                </property>
            </bean>
        </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>

    <!-- 错误:提示告诉开发者你没有配置文件上传解析器。  必须叫 multipartResolver 不能改 -->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <!-- 设置上传文件的最大尺寸为1MB 即 1048576KB-->
        <property name="maxUploadSize">
            <value>1048576</value>
        </property>
    </bean>
</beans>

配置web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         id="WebApp_ID" version="3.1">

  <!-- 读取Spring的配置文件 -->
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:applicationContext.xml</param-value>
  </context-param>
  <!-- 启动Spring的监听器 -->
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>

  <!--控制控制器-->
  <!-- 配置核心控制器-->
  <servlet>
    <servlet-name>dispatcher</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
      <!-- 告诉SpringMVC到哪里去找配置文件 -->
      <param-name>contextConfigLocation</param-name>
      <!-- 注意:这里只读取springmvc的xml -->
      <param-value>classpath:applicationContext-mvc.xml</param-value>
    </init-param>
    <!-- Servlet默认在每一次访问的时候创建 -->
      <!--顺序别写错-->
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>dispatcher</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>


<!--配置过滤器
        目的:让EntityManager对象在我的jso页面显示完毕之后再关闭
-->
    <filter>
        <filter-name>openEM</filter-name>
        <filter-class>org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>openEM</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

  <!--  配置解决中文乱码的问题 -->
  <filter>
    <filter-name>characterEncodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
      <param-name>encoding</param-name>
      <param-value>UTF-8</param-value>
    </init-param>
    <init-param>
      <param-name>forceEncoding</param-name>
      <param-value>true</param-value>
    </init-param>
  </filter>
  <filter-mapping>
    <filter-name>characterEncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
</web-app>

创建Controller与页面

EmployeeController

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
@RequestMapping("/employee")
public class EmoloyeeController extends BaseController{

    @Autowired
    private IEmployeeService employeeService;

    @RequestMapping("/index")
    public String index(){
        return "employee/employee";
    }

    @RequestMapping("/page")
    @ResponseBody
    public UiPage<Employee> page(EmployeeQuery querry){
        Page page = employeeService.findPageByQuery(querry);
        return new UiPage(page);
    }

    /**
     *ModelAttribute:路径访问Controller的每个方法,都会先执行它里面的代码
     */
    @ModelAttribute("editEmployee")
    public Employee beforeEdit(Long id,String cmd){
        if(id!=null && "_update".equals(cmd)){
            //修改才执行这个代码
            Employee dbEmployee = employeeService.findOne(id);
            //解决n-to-n的问题,把关联对象设置为null
            dbEmployee.setDepartment(null);
            return  dbEmployee;
        }
        return null;
    }

    //添加
    @RequestMapping("/save")
    @ResponseBody
    public JsonResult save(Employee employee){
        try {
            employeeService.save(employee);
            return new JsonResult();
        } catch (Exception e) {
            e.printStackTrace();
            return new JsonResult(false,e.getMessage());
        }
    }
    //修改
    @RequestMapping("/update")7
    @ResponseBody
    public JsonResult update(@ModelAttribute("editEmployee")Employee employee){
        try {
            employeeService.save(employee);
            return new JsonResult();
        } catch (Exception e) {
            e.printStackTrace();
            return new JsonResult(false,e.getMessage());
        }
    }
    /**
     * 删除功能,前台要求返回{success:true/false,msg:xxx}
     * @return
     */
    @RequestMapping("/delete")
    @ResponseBody
    public JsonResult delete(Long id){
        try {
            employeeService.delete(id);
            return new JsonResult();
        } catch (Exception e) {
            e.printStackTrace();
            return new JsonResult(false,e.getMessage());
        }
    }

    @RequestMapping("/checkUsername")
    @ResponseBody
    public Boolean checkUsername(Long id,String username){
        //1.判断id是否存在
        if(id!=null){
            //2.根据id查询对象
            Employee dbEmp = employeeService.findOne(id);
            //3.判断名称是否相等
            if(username.equals(dbEmp.getUsername())){
                //4.如果相等,直接返回true
                return true;
            }
        }
        return employeeService.checkUsername(username);
    }

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值