首页 > 开发 > Java > 正文

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

2024-07-13 10:07:47
字体:
来源:转载
供稿:网友

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

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

不废话,直接上代码

一、maven的pom文件

<?xml version="1.0" encoding="UTF-8"?>  <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">    <modelVersion>4.0.0</modelVersion>    <groupId>com.zsx</groupId>    <artifactId>demo</artifactId>    <packaging>war</packaging>    <version>0.0.1</version>    <name>zsx Maven Webapp</name>    <url>http://maven.apache.org</url>    <properties>      <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>      <jdk.version>1.7</jdk.version>      <tomcat.version>7.0.69</tomcat.version>    </properties>    <parent>      <groupId>org.springframework.boot</groupId>      <artifactId>spring-boot-starter-parent</artifactId>      <version>1.4.0.RELEASE</version>    </parent>    <dependencies>      <!-- 添加对jsp视图解析的支持 -->      <dependency>        <groupId>org.apache.tomcat.embed</groupId>        <artifactId>tomcat-embed-jasper</artifactId>      </dependency>      <dependency>        <groupId>javax.servlet</groupId>        <artifactId>jstl</artifactId>      </dependency>      <dependency>        <groupId>org.springframework.boot</groupId>        <artifactId>spring-boot-starter-web</artifactId>      </dependency>      <!-- 下面两个引入为了操作数据库 -->      <dependency>        <groupId>org.springframework.boot</groupId>        <artifactId>spring-boot-starter-data-jpa</artifactId>      </dependency>      <dependency>        <groupId>mysql</groupId>        <artifactId>mysql-connector-java</artifactId>      </dependency>      <dependency>         <groupId>org.springframework.boot</groupId>         <artifactId>spring-boot-starter-tomcat</artifactId>         <scope>provided</scope>       </dependency>      <!-- 只需引入spring-boot-devtools 即可实现热部署 -->      <dependency>        <groupId>org.springframework.boot</groupId>        <artifactId>spring-boot-devtools</artifactId>      </dependency>      <!-- Json包 -->      <dependency>        <groupId>com.alibaba</groupId>        <artifactId>fastjson</artifactId>        <version>1.2.16</version>      </dependency>      <!-- 为了监控数据库 -->      <dependency>        <groupId>com.alibaba</groupId>        <artifactId>druid</artifactId>        <version>1.0.25</version>      </dependency>      <dependency>        <groupId>org.apache.poi</groupId>        <artifactId>poi</artifactId>        <version>3.14</version>      </dependency>      <!-- Junit 单元测试 -->      <dependency>        <groupId>org.springframework.boot</groupId>        <artifactId>spring-boot-starter-test</artifactId>        <scope>test</scope>      </dependency>      <dependency>         <groupId>io.springfox</groupId>         <artifactId>springfox-swagger2</artifactId>         <version>2.6.0</version>       </dependency>       <dependency>         <groupId>io.springfox</groupId>         <artifactId>springfox-swagger-ui</artifactId>         <version>2.6.0</version>       </dependency>    </dependencies>    <build>      <finalName>/</finalName>      <plugins>        <plugin>          <groupId>org.springframework.boot</groupId>          <artifactId>spring-boot-maven-plugin</artifactId>          <dependencies>            <!-- 热部署 -->            <dependency>              <groupId>org.springframework</groupId>              <artifactId>springloaded</artifactId>              <version>1.2.6.RELEASE</version>            </dependency>          </dependencies>        </plugin>      </plugins>    </build>    <repositories>      <repository>        <id>ali</id>        <name>ali Repository</name>        <url>http://maven.aliyun.com/nexus/content/groups/public/</url>        <snapshots>          <enabled>false</enabled>        </snapshots>      </repository>    </repositories>  </project>

二、项目架构

想想还是介绍一下项目的目录结构,这样方便梳理整体的架构配置

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 // 扫描使用注解方式的servletpublic 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}")    private 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;@Configurationpublic 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.springframework.data.repository.PagingAndSortingRepository;  import org.springframework.data.repository.query.Param;  import org.springframework.stereotype.Repository;  @Repository  public interface TuserDao extends PagingAndSortingRepository<Tuser, Long>, JpaSpecificationExecutor<Tuser> {    Tuser findByUserName(String userName);    @Query("from Tuser t where id = :id")    List<Tuser> queryFamilyList(@Param("id") Long id, Pageable pageable);  }

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

  import java.util.List;  import 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<Order> list = new ArrayList<Sort.Order>();      Order order = new Order(Direction.DESC, "createTime");      list.add(order);      Sort sort = new Sort(list);      Pageable pageable = new PageRequest(0, 10, sort);      Page<Tuser> 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<T> resultList = nativeQuery.getResultList();      */  }

后记:

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

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

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

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

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持VeVb武林网。


注:相关教程知识阅读请移步到JAVA教程频道。
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表