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; }
Error creating bean
问题原因 Caused by: org.hibernate.hql.internal.ast.QuerySyntaxException: bookinfo is not mapped,sql语句中的表 ...
Springboot异常:org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'userController'
今天本菜鸟编写程序时,遇到了一个异常. org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating ...
042 spring boot在启动之后,自动关闭
在学校数据源的时候,还没有开始使用数据源,项目就关闭了. 为了学习数据源,就只能使用测试类. 但是,最近需要使用restful进行测试的时候,项目是关闭的,就很糟糕,不好进行测试. 1.日志如下: D ...
Validation failed for query for method
问题原因 sql语法,使用@Query("select id, username, usersex, userphone from User where User.usersex = ?1& ...
【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" ...
springboot整合dubbo的简单案例
使用框架: jdk 1.8 springboot-2.1.3 dubbo-2.6 spring-data-jpa-2.1.5 一.开发dubbo服务接口: 按照Dubbo官方开发建议,创建一个接口项目 ...
springboot 使用 freemarker 无法正常跳转的问题?
1.springboot 使用 freemarker 无法正常跳转的问题? 参考:https://blog.csdn.net/Lin_xiaofeng/article/details/79122053 ...
Caused by: java.lang.ClassNotFoundException: org.springframework.data.repository.config.BootstrapMode
1.起因,启动SpringBoot2.0的时候报了这个错误.说找不到类,咱也是刚学SpringBoot2.0,咱也不懂,咱也不知道问谁,研究一翻,找不到原因就百度了. 参考链接:https://blo ...
SpringBoot2版本Caused by: java.sql.SQLSyntaxErrorException: Table 'dinner.hibernate_sequenc
1.SpringBoot2版本Caused by: java.sql.SQLSyntaxErrorException: Table 'dinner.hibernate_sequenc报错. -java ...
随机推荐
ZJNU 1125 - A == B ?——中级
处理后再判断即可,处理过程注意考虑全面. /* Written By. StelaYuri */ #include<iostream> #include<string> usi ...
【转载】解决Cannot download "https://github.com/sass/node-sass/releases/download...问题
因很早做了一个小demo,并且在其他成熟的电脑上(node配置好的)下载依赖包没什么问题,最近就在新的电脑上配置好所有东西后,去下载这个demo的依赖包,就出现了node-sass无法正常解析的问题, ...
Window Redis安装
1.下载redis 下载地址:https://github.com/MicrosoftArchive/redis/releases 2. 安装redis 把下载的Redis-x64-3.2.100 ...
JavaScript学习笔记 - 进阶篇(6)- JavaScript内置对象
什么是对象 JavaScript 中的所有事物都是对象,如:字符串.数值.数组.函数等,每个对象带有属性和方法. 对象的属性:反映该对象某些特定的性质的,如:字符串的长度.图像的长宽等: 对象的方法: ...
判断1/N是否为无限小数
给定一个正整数N,请判断1/N是否为无限小数,若是输出YES,若不是请输出NO. 思路: 只要被除数n可以转换成2的次幂或者2与5的组合即为有限小数,否则为无线小数 代码如下: #include &l ...
解决UITextView无法滚到底部
程序中有一个UITextView控件 @property (weak, nonatomic) IBOutlet UITextView *textView; 一般情况下,以下代码可实现UITextVie ...
【Python杂货铺】速学python基础
"人生苦短,我学python"是编程届的名言.用python写小脚本的便捷性,让很多其他语言的学习者把python当作辅助语言.拥有了某一个语言的功底,再来学习另外一种语言应该是十 ...
AdminWebSessionManager AdminAuthorizingRealm ShiroConfig ShiroExceptionHandler
package org.linlinjava.litemall.admin.shiro; import com.alibaba.druid.util.StringUtils; import org.a ...
scala slick mysql utf8mb4 支持
语言 scala sql包 slick 3.2.0 数据库 mysql https://stackoverflow.com/questions/36741141/scala-slick-jdbc ...
JQuery实现复制数据到剪贴板之各种麻花与右键点击弹出选择菜单
1.如果小伙伴们只是想实现点击某个按钮(通过click事件)实现复制功能. 那小哥哥我在这里推荐大家使用2个非常好用的插件 (1)clipboard.js:纯js插件,无需flash,相对来说更轻量级 ...