Spring Boot + Jpa(Hibernate) 架构基本配置详解
1、基于springboot-1.4.0.RELEASE版本测试
2、springBoot+hibernate+Druid+MySQL+servlet(jsp)
不废话,直接上代码
一、maven的pom文件
4.0.0 com.zsx demo war 0.0.1 zsxMavenWebapp http://maven.apache.org UTF-8 1.7 7.0.69 org.springframework.boot spring-boot-starter-parent 1.4.0.RELEASE org.apache.tomcat.embed tomcat-embed-jasper javax.servlet jstl org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-data-jpa mysql mysql-connector-java org.springframework.boot spring-boot-starter-tomcat provided org.springframework.boot spring-boot-devtools com.alibaba fastjson 1.2.16 com.alibaba druid 1.0.25 org.apache.poi poi 3.14 org.springframework.boot spring-boot-starter-test test io.springfox springfox-swagger2 2.6.0 io.springfox springfox-swagger-ui 2.6.0 / org.springframework.boot spring-boot-maven-plugin org.springframework springloaded 1.2.6.RELEASE ali aliRepository http://maven.aliyun.com/nexus/content/groups/public/ false
二、项目架构
想想还是介绍一下项目的目录结构,这样方便梳理整体的架构配置
src ├─main │├─java ││└─com ││└─zsx │││Application.java │││SpringBootStartApplication.java │││ ││├─common │││├─config ││││DruidDBConfig.java ││││MultipartConfig.java ││││ │││├─filter ││││DruidStatFilter.java ││││ │││├─interceptors ││││AuthInterceptor.java ││││WebAppConfigurer.java ││││ │││├─servlet ││││DruidStatViewServlet.java ││││ │││└─swagger │││Swagger2.java │││ ││├─controller ││││LoginController.java ││││TestController.java ││││UserController.java │││ ││├─dao ││││TUserDao.java ││││ │││└─impl ││├─entity ││││BaseEntity.java │││ ││├─model ││││Tree.java │││ ││├─service ││││UserService.java ││││ │││└─impl │││UserServiceImpl.java │││ ││└─util ││GeneratePageable.java ││ │├─resources │││application.properties │││logback-test.xml │││ ││└─static ││├─css ││├─img ││└─js ││ │└─webapp ││index.jsp ││ │└─WEB-INF ││web.xml ││ │└─view ││login.jsp ││ │├─error ││500.jsp │├─jsp │main.jsp │ └─test └─java UtilTest.java
标准的maven项目结构,其中Java下是dao、service、controller,还有实体类映射entity,其他配置config
三、resources下的应用配置文件application.properties
#server.port=9090 #数据库访问配置 #主数据源,默认的 spring.datasource.type=com.alibaba.druid.pool.DruidDataSource spring.datasource.url=jdbc:mysql://localhost:3306/test spring.datasource.username=root spring.datasource.password=root spring.datasource.driverClassName=com.mysql.jdbc.Driver #下面为连接池的补充设置,应用到上面所有数据源中 #初始化大小,最小,最大 spring.datasource.initialSize=5 spring.datasource.minIdle=5 spring.datasource.maxActive=20 #配置获取连接等待超时的时间 spring.datasource.maxWait=60000 #配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 spring.datasource.timeBetweenEvictionRunsMillis=60000 #配置一个连接在池中最小生存的时间,单位是毫秒 spring.datasource.minEvictableIdleTimeMillis=300000 spring.datasource.validationQuery=SELECT1FROMDUAL spring.datasource.testWhileIdle=true spring.datasource.testOnBorrow=false spring.datasource.testOnReturn=false #打开PSCache,并且指定每个连接上PSCache的大小 spring.datasource.poolPreparedStatements=true spring.datasource.maxPoolPreparedStatementPerConnectionSize=20 #配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙 spring.datasource.filters=stat,wall,log4j #通过connectProperties属性来打开mergeSql功能;慢SQL记录 spring.datasource.connectionProperties=druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000 #合并多个DruidDataSource的监控数据 spring.datasource.useGlobalDataSourceStat=true #JPAConfiguration: spring.jpa.database=MYSQL #Showornotlogforeachsqlquery spring.jpa.show-sql=false spring.jpa.generate-ddl=true #Hibernateddlauto(create,create-drop,update) spring.jpa.hibernate.ddl-auto=create #spring.jpa.database-platform=org.hibernate.dialect.MySQL5Dialect spring.jpa.hibernate.naming_strategy=org.hibernate.cfg.ImprovedNamingStrategy #spring.jpa.database=org.hibernate.dialect.MySQL5InnoDBDialect spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect spring.mvc.view.prefix=/WEB-INF/view/ spring.mvc.view.suffix=.jsp #spring.resources.static-locations=classpath:/resources/,classpath:/static/
四、启动应用主类文件Application.java
packagecom.zsx;
importorg.springframework.boot.SpringApplication;
importorg.springframework.boot.autoconfigure.SpringBootApplication;
importorg.springframework.boot.web.servlet.ServletComponentScan;
@SpringBootApplication
@ServletComponentScan//扫描使用注解方式的servlet
publicclassApplication{
publicstaticvoidmain(String[]args){
SpringApplication.run(Application.class,args);
}
}
若需要部署到外部的tomcat容器中,则添加下面类即可。
packagecom.zsx;
importorg.slf4j.Logger;
importorg.slf4j.LoggerFactory;
importorg.springframework.boot.SpringApplication;
importorg.springframework.boot.builder.SpringApplicationBuilder;
importorg.springframework.boot.context.web.SpringBootServletInitializer;
/**
*修改启动类,继承SpringBootServletInitializer并重写configure方法
*@authorZSX
*
*/
publicclassSpringBootStartApplicationextendsSpringBootServletInitializer{
privatestaticfinalLoggerlogger=LoggerFactory.getLogger(SpringBootStartApplication.class);
@Override
protectedSpringApplicationBuilderconfigure(SpringApplicationBuilderbuilder){
returnbuilder.sources(Application.class);
}
}
五、数据库连接池Druid的配置
packagecom.zsx.common.config;
importjava.sql.SQLException;
importjavax.sql.DataSource;
importorg.springframework.beans.factory.annotation.Value;
importorg.springframework.context.annotation.Bean;
importorg.springframework.context.annotation.Configuration;
importorg.springframework.context.annotation.Primary;
importcom.alibaba.druid.pool.DruidDataSource;
/**
*DruidDBConfig类被@Configuration标注,用作配置信息;
*DataSource对象被@Bean声明,为Spring容器所管理,
*@Primary表示这里定义的DataSource将覆盖其他来源的DataSource。
*@authorZSX
*jdbc.url=${jdbc.url}
*最新的支持方式如下:
*jdbc.url=@jdbc.url@
*/
@Configuration
publicclassDruidDBConfig{
//privateLoggerlogger=LoggerFactory.getLogger(DruidDBConfig.class);
@Value("${spring.datasource.url}")
privateStringdbUrl;
@Value("${spring.datasource.username}")
privateStringusername;
@Value("${spring.datasource.password}")
privateStringpassword;
@Value("${spring.datasource.driverClassName}")
privateStringdriverClassName;
@Value("${spring.datasource.initialSize}")
privateintinitialSize;
@Value("${spring.datasource.minIdle}")
privateintminIdle;
@Value("${spring.datasource.maxActive}")
privateintmaxActive;
@Value("${spring.datasource.maxWait}")
privateintmaxWait;
@Value("${spring.datasource.timeBetweenEvictionRunsMillis}")
privateinttimeBetweenEvictionRunsMillis;
@Value("${spring.datasource.minEvictableIdleTimeMillis}")
privateintminEvictableIdleTimeMillis;
@Value("${spring.datasource.validationQuery}")
privateStringvalidationQuery;
@Value("${spring.datasource.testWhileIdle}")
privatebooleantestWhileIdle;
@Value("${spring.datasource.testOnBorrow}")
privatebooleantestOnBorrow;
@Value("${spring.datasource.testOnReturn}")
privatebooleantestOnReturn;
@Value("${spring.datasource.poolPreparedStatements}")
privatebooleanpoolPreparedStatements;
@Value("${spring.datasource.maxPoolPreparedStatementPerConnectionSize}")
privateintmaxPoolPreparedStatementPerConnectionSize;
@Value("${spring.datasource.filters}")
privateStringfilters;
@Value("{spring.datasource.connectionProperties}")
privateStringconnectionProperties;
@Bean//声明其为Bean实例
@Primary//在同样的DataSource中,首先使用被标注的DataSource
publicDataSourcedataSource(){
DruidDataSourcedatasource=newDruidDataSource();
datasource.setUrl(this.dbUrl);
datasource.setUsername(username);
datasource.setPassword(password);
datasource.setDriverClassName(driverClassName);
//configuration
datasource.setInitialSize(initialSize);
datasource.setMinIdle(minIdle);
datasource.setMaxActive(maxActive);
datasource.setMaxWait(maxWait);
datasource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
datasource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
datasource.setValidationQuery(validationQuery);
datasource.setTestWhileIdle(testWhileIdle);
datasource.setTestOnBorrow(testOnBorrow);
datasource.setTestOnReturn(testOnReturn);
datasource.setPoolPreparedStatements(poolPreparedStatements);
datasource.setMaxPoolPreparedStatementPerConnectionSize(maxPoolPreparedStatementPerConnectionSize);
try{
datasource.setFilters(filters);
}catch(SQLExceptione){
}
datasource.setConnectionProperties(connectionProperties);
returndatasource;
}
}
springboot里默认使用tomcat的上传文件大小限制,即1MB,修改用下面的配置类:
importjavax.servlet.MultipartConfigElement;
importorg.springframework.boot.web.servlet.MultipartConfigFactory;
importorg.springframework.context.annotation.Bean;
importorg.springframework.context.annotation.Configuration;
@Configuration
publicclassMultipartConfig{
@Bean
publicMultipartConfigElementmultipartConfigElement(){
MultipartConfigFactoryfactory=newMultipartConfigFactory();
factory.setMaxFileSize("10MB");
factory.setMaxRequestSize("10MB");
returnfactory.createMultipartConfig();
}
}
六、开启Druid的数据库监控配置
1、配置Filter
importjavax.servlet.annotation.WebFilter;
importjavax.servlet.annotation.WebInitParam;
importcom.alibaba.druid.support.http.WebStatFilter;
/**
*配置druid监控统计功能
*配置Filter
*@authorZSX
*
*/
@WebFilter(filterName="druidWebStatFilter",urlPatterns="/*",
initParams={
@WebInitParam(name="exclusions",value="*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*")//忽略资源
}
)
publicclassDruidStatFilterextendsWebStatFilter{
}
2、配置web访问的servlet
importjavax.servlet.annotation.WebInitParam;
importjavax.servlet.annotation.WebServlet;
importcom.alibaba.druid.support.http.StatViewServlet;
/**
*配置druid监控统计功能
*在SpringBoot项目中基于注解的配置,如果是web.xml配置,按规则配置即可
*@authorZSX
*
*/
@WebServlet(urlPatterns="/druid/*",
initParams={
//@WebInitParam(name="allow",value="192.168.16.110,127.0.0.1"),//IP白名单(没有配置或者为空,则允许所有访问)
//@WebInitParam(name="deny",value="192.168.16.111"),//IP黑名单(存在共同时,deny优先于allow)
@WebInitParam(name="loginUsername",value="druid"),//用户名
@WebInitParam(name="loginPassword",value="druid"),//密码
@WebInitParam(name="resetEnable",value="false")//禁用HTML页面上的“ResetAll”功能
}
)
publicclassDruidStatViewServletextendsStatViewServlet{
}
这样启动项目后在浏览器中输入地址:端口/druid,就可以看到druid的监控web页面了
七、拦截器配置
importorg.springframework.context.annotation.Configuration;
importorg.springframework.web.servlet.config.annotation.InterceptorRegistry;
importorg.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
importorg.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
@Configuration
publicclassWebAppConfigurerextendsWebMvcConfigurerAdapter{
/**
*配置拦截器
*/
@Override
publicvoidaddInterceptors(InterceptorRegistryregistry){
//TODOAuto-generatedmethodstub
//多个拦截器组成一个拦截器链
//addPathPatterns用于添加拦截规则
//excludePathPatterns用户排除拦截
registry.addInterceptor(newAuthInterceptor()).addPathPatterns("/**");
super.addInterceptors(registry);
}
/**
*添加自定义的静态资源映射
这里使用代码的方式自定义目录映射,并不影响SpringBoot的默认映射,可以同时使用。
*/
@Override
publicvoidaddResourceHandlers(ResourceHandlerRegistryregistry){
//registry.addResourceHandler("/new/**").addResourceLocations("classpath:/new/");
//registry.addResourceHandler("/**").addResourceLocations("/");
super.addResourceHandlers(registry);
}
}
八、swagger发布api测试配置(可忽略)
importorg.springframework.context.annotation.Bean;
importorg.springframework.context.annotation.Configuration;
importspringfox.documentation.builders.ApiInfoBuilder;
importspringfox.documentation.builders.PathSelectors;
importspringfox.documentation.builders.RequestHandlerSelectors;
importspringfox.documentation.service.ApiInfo;
importspringfox.documentation.spi.DocumentationType;
importspringfox.documentation.spring.web.plugins.Docket;
importspringfox.documentation.swagger2.annotations.EnableSwagger2;
@Configuration
@EnableSwagger2
publicclassSwagger2{
@Bean
publicDocketcreateRestApi(){
returnnewDocket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
.apis(RequestHandlerSelectors.basePackage("com.zsx.controller.api"))
.paths(PathSelectors.any())
.build();
}
privateApiInfoapiInfo(){
returnnewApiInfoBuilder()
.title("SpringBoot中使用Swagger2构建RESTfulAPIs")
.description("描述")
.termsOfServiceUrl("http://zsx.com.cn")
.version("1.0")
.build();
}
}
至此,所有的配置已完成,下面是一个操作数据的简单demo
九、实体类
@Entity
@Table(name="t_user")
publicclassTuserimplementsjava.io.Serializable{
/**
*
*/
privatestaticfinallongserialVersionUID=1L;
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
privateLongid;
@Column(name="username")
privateStringuserName;
@Column(name="password")
privateStringpassWord;
@Column(name="email")
privateStringemail;
@Column(name="mobile")
privateStringmobile;
@Column(name="nickname")
privateStringnickName;
//省略getter和setter
}
十、dao层
1、使用jpa基本可以实现不写sql,(但实际开发中,业务逻辑会很复杂,一点不写sql完全不现实)
2、注意添加@Repository注解,添加JpaSpecificationExecutor继承可以方便分页
3、看些jpa的查询语法资料
importjava.util.List; importjava.util.Map; importorg.springframework.data.domain.Pageable; importorg.springframework.data.jpa.repository.JpaSpecificationExecutor; importorg.springframework.data.jpa.repository.Query; importorg.springframework.data.repository.PagingAndSortingRepository; importorg.springframework.data.repository.query.Param; importorg.springframework.stereotype.Repository; @Repository publicinterfaceTuserDaoextendsPagingAndSortingRepository,JpaSpecificationExecutor { TuserfindByUserName(StringuserName); @Query("fromTusertwhereid=:id") List queryFamilyList(@Param("id")Longid,Pageablepageable); }
十一、service和controller没啥好说的,跟原先的一样,下面再提供一个单元测试的demo
importjava.util.List;
importjavax.persistence.EntityManager;
importorg.junit.Test;
importorg.junit.runner.RunWith;
importorg.springframework.beans.factory.annotation.Autowired;
importorg.springframework.boot.test.SpringApplicationConfiguration;
importorg.springframework.test.context.junit4.SpringJUnit4ClassRunner;
importorg.springframework.test.context.web.WebAppConfiguration;
importcom.alibaba.fastjson.JSON;
importcom.golden.Application;
importcom.golden.dao.TUserDao;
importcom.golden.entity.Tuser;
importcom.golden.util.GeneratePageable;
@RunWith(SpringJUnit4ClassRunner.class)
//指定我们SpringBoot工程的Application启动类
@SpringApplicationConfiguration(classes=Application.class)
//由于是Web项目,Junit需要模拟ServletContext,因此我们需要给我们的测试类加上@WebAppConfiguration
@WebAppConfiguration
publicclassUtilTest{
@Autowired
privateTUserDaodao;
@Autowired
privateEntityManagerem;
@Test
publicvoidtest1(){
dao.findByUserName("admin");
}
@Test
publicvoidtest2(){
//使用jpa提供的分页类
java.util.Listlist=newArrayList();
Orderorder=newOrder(Direction.DESC,"createTime");
list.add(order);
Sortsort=newSort(list);
Pageablepageable=newPageRequest(0,10,sort);
PagefindAll=dao.findAll(pageable);
}
@Test
publicvoidtest3(){
EntityManagerem=dao.getEntityManager();
Queryquery=em.createNativeQuery("select*fromt_userlimit1");
ObjectsingleResult=query.getSingleResult();
System.out.println(singleResult);
}
/*
//执行原生SQL
QuerynativeQuery=em.createNativeQuery(Stringsql);
//指定返回对象类型
nativeQuery.unwrap(SQLQuery.class).setResultTransformer(Transformers.aliasToBean(ClassresultType));
//返回对象
ListresultList=nativeQuery.getResultList();
*/
}
后记:
不用Druid的可以把有关Druid的配置全部删掉,swagger的同理
这里没有使用hibernate.cfg.xml配置文件,主要习惯了在实体类里配置字段了,不怎么用hibernate的映xml文件了,但其实配置起来跟springmvc项目一样
说实话这里使用jpa操作数据库,没感觉有多方便,因为总有各种奇葩的需求,当然也可能是我没深入研究,所以建议改用Mybatis,这个我会再写一篇springboot加mybatis的配置教程的,最后,还可以使用原生的sql查询,即使用单元测试里的EntityManager对象去执行sql,返回结果可以指定对象类型,也很方便
还需要注意的一个点是静态文件的存放位置,这个跟原先的项目不一样,原先是在webapp下,但springboot是默认放在resources下的static目录下的,还有其他默认目录和配置,自行搜索
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。