1.SpringDataJpa的扩展 — 抽取

创建一个BaseRepository接口然后去继承JpaRepository和JpaSpecificationExecutor

然后在里面写我们自己想要的方法

在接口上边加上注解@NoRepositoryBean 这是为了防止底层去找SimpleJpaRepository的实现类 我们需要找我们自己的实现类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
* @NoRepositoryBean
* 防止底层去找SimpleJpaRepository的实现类 我们需要找我们自己的实现类
* */ public interface <T,ID extends Serializable> extends JpaRepository<T, ID>,
JpaSpecificationExecutor<T> { //根据BaseQuery拿到分页对象
Page findPageByQuery(BaseQuery baseQuery); //根据BaseQuery拿到对应的数据 不分页
List<T> findByQuery(BaseQuery baseQuery); //根据jpql与对应的参数拿到数据
List findByJpql(String jpql,Object...value); }

然后再创建一个实现类 实现我们刚写的BaseRepository接口

再继承 SimpleJpaRepository

这样就不用覆写SpringDataJpa本身的方法了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
* Serializable  序列化  用来网络传输
* extends SimpleJpaRepository 不会覆写SpringDataJpa本身的方法
* implements BaseRepository 实现自身的方法
*
*
* */
public class BaseRepositoryImpl<T,ID extends Serializable> extends SimpleJpaRepository<T,ID> implements <T,ID> {
//让Spring把entityManager注入进来
private EntityManager entityManager; //继承了SimpleJpaRepository中没有无参构造 必须覆写里面的有参构造
public BaseRepositoryImpl(Class<T> domainClass, EntityManager em) {
super(domainClass, em);
this.entityManager = em;
}
//分页查询方法
@Override
public Page findPageByQuery(BaseQuery baseQuery) {
//排序
Sort sort = baseQuery.createSort();
//条件
Specification specs = baseQuery.createSpecifications();
//分页
Pageable pageable = new PageRequest(baseQuery.getCurrentPage(), baseQuery.getPageSize(), sort);
//查询
Page page = super.findAll(specs, pageable);
return page;
} @Override
public List<T> findByQuery(BaseQuery baseQuery) {
Sort sort = baseQuery.createSort();
Specification spec = baseQuery.createSpecifications();
//条件加排序查询
List<T> list = super.findAll(spec, sort);
return list;
} @Override
public List findByJpql(String jpql, Object... value) {
Query query = entityManager.createQuery(jpql);
for (int i = 0; i < value.length; i++) {
query.setParameter(i+1, value[i]);
}
return query.getResultList();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
/**
* 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;
}
//这里返回最后的功能对象
@Override
protected Object getTargetRepository(RepositoryInformation information) {
return new BaseRepositoryImpl<T,ID>((Class<T>)information.getDomainType(),entityManager);
}
//这里返回最后的功能对象 --最终Spring调用方法返回的对象 -->得到对最终的对象
//factoryBean 默认调用getObject -- 现在调用getTargetRepository
@Override
protected Class<?> getRepositoryBaseClass(RepositoryMetadata metadata) {
return BaseRepositoryImpl.class;
}
}
}

​ 让Spring启动的时候,找BaseRepositoryImpl的实现 —>BaseRepositoryFactoryBean可以让spring去找

BaseRepositoryImpl这个实现

在applicationContext中增加

1
2
3
4
5
6
7
<!-- SpringDataJpa配置 -->
<jpa:repositories base-package="cn.itsource.repository"
transaction-manager-ref="transactionManager"
entity-manager-factory-ref="entityManagerFactory"
<!-- 加这一一个属性 -->
factory-class="cn.itsource.repository.impl.BaseRepositoryFactoryBean"
/>

2.抽取Service层

创建一个公共接口 IBaseService –> 完成CRUD以及三个公共方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public interface IBaseService<T,ID extends Serializable> {
//增加 修改
void save(T t);
//删除
void del(ID id);
//查询单个
T findOne(ID id);
//查询全部
List<T> findAll();
//分页排序查询
Page findPageByQuery(BaseQuery baseQuery);
//排序查询
List<T> findByQuery(BaseQuery baseQuery);
//jpql语句查询
List jpqlByQuery(String jpql,Object...value);
}

创建一个实现类BaseServiceImpl —> 实现IBaseService —> 实现所有方法 完成所有方法 加上事务管理注解

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
@Transactional(propagation = Propagation.SUPPORTS,readOnly = true)
public class BaseServiceImpl<T,ID extends Serializable> implements IBaseService<T, ID> { @Autowired
private BaseRepository<T,ID> baseRepository; @Override
@Transactional
public void save(T t) {
baseRepository.save(t);
} @Override
@Transactional
public void del(ID id) {
baseRepository.delete(id);
} @Override
@Transactional
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 jpqlByQuery(String jpql, Object... value) {
return baseRepository.findByJpql(jpql, value);
}
}

​ 再创建IEmployeeService和EmployeeServiceImpl 分别继承接口和实现类 —> 继承之后就具备了CRUD以及公共的查询方法了

3.集成SpringMVC

(1) 导包

(2) 创建applicationContext-mvc配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<!-- 对静态资源进行放行 -->
<mvc:default-servlet-handler />
<!-- 扫描controller部分的包 -->
<!-- @Component组件, @Repository持久层, @Service业务逻辑层, and @Controller控制器 -->
<context:component-scan base-package="cn.itsource.web" />
<!-- 添加mvc对@RequestMapping等注解的支持 -->
<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>

创建web.xml 进行配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
<!-- 读取SpringMVC -->
<context-param>
<param-name>contextConfigLocation</param-name>
大专栏  SpringDataJpa2"> <param-value>classpath:applicationContext.xml</param-value>
</context-param>
<!-- 启动Spring的监听器 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener> <!-- 配置解决中文乱码的问题 -->
<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> <!-- 配置核心控制器-->
<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>

后面需要自己配置tomcat

4.加入Easyui

把easyui的文件复制到web下边

然后创建一个head.jsp 这个是专门方easyui引入的配置的

因为很多页面需要用到 所以单独抽取出来

1
2
3
4
5
6
7
8
9
10
<%@ page contentType="text/html;charset=UTF-8" language="java" %>

<link rel="stylesheet" type="text/css" href="/easyui/themes/default/easyui.css">
<link rel="stylesheet" type="text/css" href="/easyui/themes/icon.css"> <script type="text/javascript" src="/easyui/jquery.min.js"></script>
<script type="text/javascript" src="/easyui/jquery.easyui.min.js"></script>
<script type="text/javascript" src="/easyui/locale/easyui-lang-zh_CN.js"></script>
<script type="text/javascript" src="/easyui/plugin/jquery.jdirk.js"></script>
<script type="text/javascript" src="/js/common.js"></script>
1
2
3
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%-- 需要用到easyui引入 就加上这行代码 --%>
<%@include file="/WEB-INF/views/head.jsp"%>

然后就加入页面

树形菜单

1
2
3
4
5
6
7
8
9
10
//获取左边树状菜单栏
$("#menuTree").tree({
//获取json中的数据
url:"/json/menu.json",
//点击事件
onClick:function(node){
//增加页签 把名字和地址传过去
addTabs(node.text,node.url);
}
})

就是上边树形菜单点击事件触发之后调用下面的函数增加页签

tabs选项卡增加

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function addTabs(text,url) {
if(url){
if(!$("#dataTab").tabs("exists",text)){
var content = '<iframe scrolling="auto" frameborder="0" src="'+url+'" style="width:100%;height:100%;"></iframe>';
$("#dataTab").tabs("add",{
title:text,
content:content,
closable:true
});
}else{
$("#dataTab").tabs("select",text);
}
}
}

5.分页

因为json中分页需要total row

所以我们创建一个公共类

类里面有这两个字段 rows是显示在页面的 数据 所以用List

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class UIPage {
//总条数
private Long total;
//每页显示数据
private List rows; public UIPage() {} public UIPage(Page page) {
this.total = page.getTotalElements();
this.rows = page.getContent();
}
//下面有get/set方法
}

在controller中 把分页查询出来的数据放到UIPage中去

1
2
3
4
5
6
7
@RequestMapping("/page")
@ResponseBody
public UIPage page(EmployeeQuery employeeQuery){
Page page = employeeService.findPageByQuery(employeeQuery);
UIPage uiPage = new UIPage(page);
return uiPage;
}

​ 前台加载数据的时候 接受的参数用EmployeeQuery 但是需要在BaseQuery中设置set方法 把前台加载的页数和页面展示条数传到BaseQuery

1
2
3
4
5
6
7
8
//因为前台传入的参数是page和rows
public void setPage(Integer page){
System.out.println(page);
this.currentPage = page;
}
public void setRows(Integer rows){
this.pageSize = rows;
}

前台传的参数

6.头像和部门

在头像和部门的标签里加上 formatter (单元格formatter(格式化器)函数)

1
2
<th width="20"  field="headImage" formatter="headImage" >头像</th>
<th width="20" field="department" formatter="department" >部门</th>

然后创建在js文件夹中创建一个model文件夹 里面创建一个employee的js文件

1
2
3
4
5
6
7
8
9
10
function department(value) {
if(value){
return value.name;
}
}
function headImage(value) {
if(value){
return "<img src='"+value+"' />";
}
}

7.解决懒加载问题

在wei.xml里面加

1
2
3
4
5
6
7
8
9
<!-- 加上OpenEntityManager -->
<filter>
<filter-name>openEntity</filter-name>
<filter-class>org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>openEntity</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

方法一:在实体类建立关系的上面加上注解

1
2
3
4
@ManyToOne
@JoinColumn(name = "department_id")
@JsonIgnoreProperties(value={"hibernateLazyInitializer","handler","fieldHandler"})
private Department department;

方法二:因为方法一只能对单个有效 有很多类都需要的时候 很麻烦

​ (1) 创建一个新的类(重写com.fasterxml.jackson.databind.ObjectMapper)

1
2
3
4
5
6
7
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);
}
}

(2) 在applicationContext-mvc.xml中配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<!-- 添加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="cn.itsource.common.CustomMapper"></bean>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>

8.高级查询

页面准备好之后 需要回显部门下拉框

先去repositroy去写一个IDepartmentRepository接口

再去service把IDepartmentService接口和实现类写好

再创建一个UtilController

1
2
3
4
5
6
7
8
9
10
11
12
13
@Controller
@RequestMapping("/util")
public class UtilController {
@Autowired
private IDepartmentService departmentService; @RequestMapping("/departmentList")
@ResponseBody
public List<Department> departmentList(){
List<Department> list = departmentService.findAll();
return list;
}
}

页面准备for表单 点击搜索的时候 加载数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$(function () {
var searchForm = $("#searchForm");
var employeeGrid = $("#employeeGrid"); //获取带有data-method属性的a标签 然后绑定事件
$("a[data-method]").on("click",function () {
var methodName = $(this).data("method");
itsource[methodName]();
}) var itsource = {
search:function () {
var parme = searchForm.serializeObject();
employeeGrid.datagrid("load",parme);
}
}
})

在EmployeeQuery增加几个属性和条件

1
2
3
4
5
6
7
8
public Specification createSpecifications() {
Specification<Employee> specification = Specifications.<Employee>and()
.like(StringUtils.isNotBlank(this.username), "username", "%" + this.username + "%")
.like(StringUtils.isNotBlank(this.email), "email", "%" + this.email + "%")
.eq(this.departmentId != null,"department.id",this.departmentId)
.build();
return specification;
}

SpringDataJpa2的更多相关文章

  1. Error creating bean

    问题原因 Caused by: org.hibernate.hql.internal.ast.QuerySyntaxException: bookinfo is not mapped,sql语句中的表 ...

  2. Springboot异常:org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'userController'

    今天本菜鸟编写程序时,遇到了一个异常. org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating ...

  3. 042 spring boot在启动之后,自动关闭

    在学校数据源的时候,还没有开始使用数据源,项目就关闭了. 为了学习数据源,就只能使用测试类. 但是,最近需要使用restful进行测试的时候,项目是关闭的,就很糟糕,不好进行测试. 1.日志如下: D ...

  4. Validation failed for query for method

    问题原因 sql语法,使用@Query("select id, username, usersex, userphone from User where User.usersex = ?1& ...

  5. 【hibernate postgresql】注解@TypeDef/@Enumerated/数据库字段gender为枚举类型,从前台接受到实体后进行保存报错:org.postgresql.util.PSQLException: ERROR: column "gender" is of type gender but expression is of type character varying

    数据库字段gender为枚举类型,从前台接受到实体后进行保存报错:org.postgresql.util.PSQLException: ERROR: column "gender" ...

  6. springboot整合dubbo的简单案例

    使用框架: jdk 1.8 springboot-2.1.3 dubbo-2.6 spring-data-jpa-2.1.5 一.开发dubbo服务接口: 按照Dubbo官方开发建议,创建一个接口项目 ...

  7. springboot 使用 freemarker 无法正常跳转的问题?

    1.springboot 使用 freemarker 无法正常跳转的问题? 参考:https://blog.csdn.net/Lin_xiaofeng/article/details/79122053 ...

  8. Caused by: java.lang.ClassNotFoundException: org.springframework.data.repository.config.BootstrapMode

    1.起因,启动SpringBoot2.0的时候报了这个错误.说找不到类,咱也是刚学SpringBoot2.0,咱也不懂,咱也不知道问谁,研究一翻,找不到原因就百度了. 参考链接:https://blo ...

  9. SpringBoot2版本Caused by: java.sql.SQLSyntaxErrorException: Table 'dinner.hibernate_sequenc

    1.SpringBoot2版本Caused by: java.sql.SQLSyntaxErrorException: Table 'dinner.hibernate_sequenc报错. -java ...

随机推荐

  1. ZJNU 1125 - A == B ?——中级

    处理后再判断即可,处理过程注意考虑全面. /* Written By. StelaYuri */ #include<iostream> #include<string> usi ...

  2. 【转载】解决Cannot download "https://github.com/sass/node-sass/releases/download...问题

    因很早做了一个小demo,并且在其他成熟的电脑上(node配置好的)下载依赖包没什么问题,最近就在新的电脑上配置好所有东西后,去下载这个demo的依赖包,就出现了node-sass无法正常解析的问题, ...

  3. Window Redis安装

    1.下载redis 下载地址:https://github.com/MicrosoftArchive/redis/releases ​ 2. 安装redis 把下载的Redis-x64-3.2.100 ...

  4. JavaScript学习笔记 - 进阶篇(6)- JavaScript内置对象

    什么是对象 JavaScript 中的所有事物都是对象,如:字符串.数值.数组.函数等,每个对象带有属性和方法. 对象的属性:反映该对象某些特定的性质的,如:字符串的长度.图像的长宽等: 对象的方法: ...

  5. 判断1/N是否为无限小数

    给定一个正整数N,请判断1/N是否为无限小数,若是输出YES,若不是请输出NO. 思路: 只要被除数n可以转换成2的次幂或者2与5的组合即为有限小数,否则为无线小数 代码如下: #include &l ...

  6. 解决UITextView无法滚到底部

    程序中有一个UITextView控件 @property (weak, nonatomic) IBOutlet UITextView *textView; 一般情况下,以下代码可实现UITextVie ...

  7. 【Python杂货铺】速学python基础

    "人生苦短,我学python"是编程届的名言.用python写小脚本的便捷性,让很多其他语言的学习者把python当作辅助语言.拥有了某一个语言的功底,再来学习另外一种语言应该是十 ...

  8. AdminWebSessionManager AdminAuthorizingRealm ShiroConfig ShiroExceptionHandler

    package org.linlinjava.litemall.admin.shiro; import com.alibaba.druid.util.StringUtils; import org.a ...

  9. scala slick mysql utf8mb4 支持

    语言  scala sql包  slick 3.2.0 数据库  mysql https://stackoverflow.com/questions/36741141/scala-slick-jdbc ...

  10. JQuery实现复制数据到剪贴板之各种麻花与右键点击弹出选择菜单

    1.如果小伙伴们只是想实现点击某个按钮(通过click事件)实现复制功能. 那小哥哥我在这里推荐大家使用2个非常好用的插件 (1)clipboard.js:纯js插件,无需flash,相对来说更轻量级 ...