Spring Boot + Jpa(Hibernate) 架构基本配置详解

网友投稿 584 2023-05-14


Spring Boot + Jpa(Hibernate) 架构基本配置详解

1、基于springboot-1.4.0.RELEASE版本测试

2、springBoot + hibernate + Druid + mysql + servlet(jsp)

不废话,直接上代码

一、maven的pom文件

xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

4.0.0

com.zsx

demo

war

0.0.1

zsx Maven Webapp

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

ali Repository

http://maven.aliyun.com/nexus/content/groups/public/

false

xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

4.0.0

com.zsx

demo

war

0.0.1

zsx Maven Webapp

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

ali Repository

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=SELECT 1 FROM DUAL

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

#JPA Configuration:

spring.jpa.database=MYSQL

# Show or not log for each sql query

spring.jpa.show-sql=false

spring.jpa.generate-ddl=true

# Hibernate ddl auto (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

package com.zsx;

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

import org.springframework.boot.web.servlet.ServletComponentScan;

@SpringBootApplication

@ServletComponentScan // 扫描使用注解方式的servlet

public class Application {

public static void main(String[] args) {

SpringApplication.run(Application.class, args);

}

}

若需要部署到外部的tomcat容器中,则添加下面类即可。

package com.zsx;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.springframework.boot.SpringApplication;

import org.springframework.boot.builder.SpringApplicationBuilder;

import org.springframework.boot.context.web.SpringBootServletInitializer;

/**

* 修改启动类,继承 SpringBootServletInitializer 并重写 configure 方法

* @author ZSX

*

*/

public class SpringBootStartApplication extends SpringBootServletInitializer {

private static final Logger logger = LoggerFactory.getLogger(SpringBootStartApplication.class);

@Override

protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {

return builder.sources(Application.class);

}

}

五、数据库连接池Druid的配置

package com.zsx.common.config;

import java.sql.SQLException;

import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Value;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

import org.springframework.context.annotation.Primary;

import com.alibaba.druid.pool.DruidDataSource;

/**

* DruidDBConfig类被@Configuration标注,用作配置信息;

* DataSource对象被@Bean声明,为Spring容器所管理,

* @Primary表示这里定义的DataSource将覆盖其他来源的DataSource。

* @author ZSX

*jdbc.url=${jdbc.url}

*最新的支持方式如下:

*jdbc.url=@jdbc.url@

*/

@Configuration

public class DruidDBConfig {

// private Logger logger = LoggerFactory.getLogger(DruidDBConfig.class);

@Value("${spring.datasource.url}")

private String dbUrl;

@Value("${spring.datasource.username}")

private String username;

@Value("${spring.datasource.password}")

private String password;

@Value("${spring.datasource.driverClassName}")

privathttp://e String driverClassName;

@Value("${spring.datasource.initialSize}")

private int initialSize;

@Value("${spring.datasource.minIdle}")

private int minIdle;

@Value("${spring.datasource.maxActive}")

private int maxActive;

@Value("${spring.datasource.maxWait}")

private int maxWait;

@Value("${spring.datasource.timeBetweenEvictionRunsMillis}")

private int timeBetweenEvictionRunsMillis;

@Value("${spring.datasource.minEvictableIdleTimeMillis}")

private int minEvictableIdleTimeMillis;

@Value("${spring.datasource.validationQuery}")

private String validationQuery;

@Value("${spring.datasource.testWhileIdle}")

private boolean testWhileIdle;

@Value("${spring.datasource.testOnBorrow}")

private boolean testOnBorrow;

@Value("${spring.datasource.testOnReturn}")

private boolean testOnReturn;

@Value("${spring.datasource.poolPreparedStatements}")

private boolean poolPreparedStatements;

@Value("${spring.datasource.maxPoolPreparedStatementPerConnectionSize}")

private int maxPoolPreparedStatementPerConnectionSize;

@Value("${spring.datasource.filters}")

private String filters;

@Value("{spring.datasource.connectionProperties}")

private String connectionProperties;

@Bean // 声明其为Bean实例

@Primary // 在同样的DataSource中,首先使用被标注的DataSource

public DataSource dataSource() {

DruidDataSource datasource = new DruidDataSource();

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 (SQLException e) {

}

datasource.setConnectionProperties(connectionProperties);

return datasource;

}

}

springboot里默认使用tomcat的上传文件大小限制,即1MB, 修改用下面的配置类:

import javax.servlet.MultipartConfigElement;

import org.springframework.boot.web.servlet.MultipartConfigFactory;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

@Configuration

public class MultipartConfig {

@Bean

public MultipartConfigElement multipartConfigElement(){

MultipartConfigFactory factory = new MultipartConfigFactory();

factory.setMaxFileSize("10MB");

factory.setMaxRequestSize("10MB");

return factory.createMultipartConfig();

}

}

六、开启Druid的数据库监控配置

1、配置Filter

import javax.servlet.annotation.WebFilter;

import javax.servlet.annotation.WebInitParam;

import com.alibaba.druid.support.http.WebStatFilter;

/**

* 配置druid监控统计功能

* 配置Filter

* @author ZSX

*

*/

@WebFilter(filterName = "druidWebStatFilter", urlPatterns = "/*",

initParams = {

@WebInitParam(name="exclusions",value="*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*")// 忽略资源

}

)

public class DruidStatFilter extends WebStatFilter {

}

2、 配置web访问的servlet

import javax.servlet.annotation.WebInitParam;

import javax.servlet.annotation.WebServlet;

import com.alibaba.druid.support.http.StatViewServlet;

/**

* 配置druid监控统计功能

* 在SpringBoot项目中基于注解的配置,如果是web.xml配置,按规则配置即可

* @author ZSX

*

*/

@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页面上的“Reset All”功能

}

)

public class DruidStatViewServlet extends StatViewServlet {

}

这样启动项目后在浏览器中输入地址:端口/druid,就可以看到druid的监控web页面了

七、 拦截器配置

import org.springframework.context.annotation.Configuration;

import org.springframework.web.servlet.config.annotation.InterceptorRegistry;

import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;

import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

@Configuration

public class WebAppConfigurer extends WebMvcConfigurerAdapter {

/**

* 配置拦截器

*/

@Override

public void addInterceptors(InterceptorRegistry registry) {

// TODO Auto-generated method stub

// 多个拦截器组成一个拦截器链

// addPathPatterns 用于添加拦截规则

// excludePathPatterns 用户排除拦截

registry.addInterceptor(new AuthInterceptor()).addPathPatterns("/**");

super.addInterceptors(registry);

}

/**

* 添加自定义的静态资源映射

这里使用代码的方式自定义目录映射,并不影响Spring Boot的默认映射,可以同时使用。

*/

@Override

public void addResourceHandlers(ResourceHandlerRegistry registry) {

// registry.addResourceHandler("/new/**").addResourceLocations("classpath:/new/");

// registry.addResourceHandler("/**").addResourceLocations("/");

super.addResourceHandlers(registry);

}

}

八、swagger发布api测试配置(可忽略)

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

import springfox.documentation.builders.ApiInfoBuilder;

import springfox.documentation.builders.PathSelectors;

import springfox.documentation.builders.RequestHandlerSelectors;

import springfox.documentation.service.ApiInfo;

import springfox.documentation.spi.DocumentationType;

import springfox.documentation.spring.web.plugins.Docket;

import springfox.documentation.swagger2.annotations.EnableSwagger2;

@Configuration

@EnableSwagger2

public class Swagger2 {

@Bean

public Docket createRestApi(){

return new Docket(DocumentationType.SWAGGER_2)

.apiInfo(apiInfo())

.select()

.apis(RequestHandlerSelectors.basePackage("com.zsx.controller.api"))

.paths(PathSelectors.any())

.build();

}

private ApiInfo apiInfo(){

return new ApiInfoBuilder()

.title("Spring Boot中使用Swagger2构建RESTful APIs")

.description("描述")

.termsOfServiceUrl("http://zsx.com.cn")

.version("1.0")

.build();

}

}

至此,所有的配置已完成,下面是一个操作数据的简单demo

九、实体类

@Entity

@Table(name = "t_user")

public class Tuser implements java.io.Serializable {

/**

*

*/

private static final long serialVersionUID = 1L;

@Id

@GeneratedValue(strategy=GenerationType.IDENTITY)

private Long id;

@Column(name = "username")

private String userName;

@Column(name = "password")

private String passWord;

@Column(name = "email")

private String email;

@Column(name = "mobile")

private String mobile;

@Column(name = "nickname")

private String nickName;

// 省略getter 和 setter

}

十、dao层

1、使用jpa基本可以实现不写sql,(但实际开发中,业务逻辑会很复杂,一点不写sql完全不现实)

2、注意添加@Repository注解, 添加JpaSpecificationExecutor继承可以方便分页

3、 看些jpa的查询语法资料

import java.util.List;

import java.util.Map;

import org.springframework.data.domain.Pageable;

import org.springframework.data.jpa.repository.JpaSpecificationExecutor;

import org.springframework.data.jpa.repository.Query;

import org.springfrhttp://amework.data.repository.PagingAndSortingRepository;

import org.springframework.data.repository.query.Param;

import org.springframework.stereotype.Repository;

@Repository

public interface TuserDao extends PagingAndSortingRepository, JpaSpecificationExecutor {

Tuser findByUserName(String userName);

@Query("from Tuser t where id = :id")

List queryFamilyList(@Param("id") Long id, Pageable pageable);

}

十一、service和controller没啥好说的,跟原先的一样,下面再提供一个单元测试的demo

import java.util.List;

imhttp://port javax.persistence.EntityManager;

import org.junit.Test;

import org.junit.runner.RunWith;

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

import org.springframework.boot.test.SpringApplicationConfiguration;

import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import org.springframework.test.context.web.WebAppConfiguration;

import com.alibaba.fastjson.JSON;

import com.golden.Application;

import com.golden.dao.TUserDao;

import com.golden.entity.Tuser;

import com.golden.util.GeneratePageable;

@RunWith(SpringJUnit4ClassRunner.class)

//指定我们SpringBoot工程的Application启动类

@SpringApplicationConfiguration(classes = Application.class)

//由于是Web项目,Junit需要模拟ServletContext,因此我们需要给我们的测试类加上@WebAppConfiguration

@WebAppConfiguration

public class UtilTest {

@Autowired

private TUserDao dao;

@Autowired

private EntityManager em;

@Test

public void test1(){

dao.findByUserName("admin");

}

@Test

public void test2(){

// 使用jpa提供的分页类

java.util.List list = new ArrayList();

Order order = new Order(Direction.DESC, "createTime");

list.add(order);

Sort sort = new Sort(list);

Pageable pageable = new PageRequest(0, 10, sort);

Page findAll = dao.findAll(pageable);

}

@Test

public void test3(){

EntityManager em = dao.getEntityManager();

Query query = em.createNativeQuery("select * from t_user limit 1");

Object singleResult = query.getSingleResult();

System.out.println(singleResult);

}

/*

//执行原生SQL

Query nativeQuery = em.createNativeQuery(String sql);

//指定返回对象类型

nativeQuery.unwrap(SQLQuery.class).setResultTransformer(Transformers.aliasToBean( Class resultType));

//返回对象

List resultList = nativeQuery.getResultList();

*/

}

后记:

不用Druid的可以把有关Druid的配置全部删掉,swagger的同理

这里没有使用hibernate.cfg.xml配置文件,主要习惯了在实体类里配置字段了,不怎么用hibernate的映xml文件了,但其实配置起来跟springmvc项目一样

说实话这里使用jpa操作数据库,没感觉有多方便,因为总有各种奇葩的需求,当然也可能是我没深入研究,所以建议改用Mybatis,这个我会再写一篇springboot加mybatis的配置教程的,最后,还可以使用原生的sql查询,即使用单元测试里的EntityManager对象去执行sql,返回结果可以指定对象类型,也很方便

还需要注意的一个点是静态文件的存放位置,这个跟原先的项目不一样,原先是在webapp下,但springboot是默认放在resources下的static目录下的,还有其他默认目录和配置,自行搜索


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Spring Data + Thymeleaf 3 + Bootstrap 4 实现分页器实例代码
下一篇:Kotlin开发Android应用实例详解
相关文章

 发表评论

暂时没有评论,来抢沙发吧~