SpringBoot2集成MyBatis、Druid連接池、PageHelper分頁操作

主要知識點

SpringBoot2集成MyBatis,實現基本的CURD操作,這其中涉及到相關內容也是關注重點:

  • PageHelper 數據庫分頁查詢,重點配置和使用
  • Durid 數據庫連接池集成,主要爲sql監控而生。重點配置和使用
  • MyBatis 集成及使用
  • Controller controller層接收參數

SpringBoot整合Mybatis

之前已經說過:SpringBoot框架不是對Spring功能上的增強,而是提供了一種快速使用Spring的方式

所以說,SpringBoot整合Mybatis的思想和Spring整合Mybatis的思想基本相同,不同之處有兩點:

  • Mapper接口的XML配置文件變化。之前我們使用Mybatis接口代理開發,規定Mapper映射文件要和接口在一個目錄下;而這裏Mapper映射文件置於resources/mapper/下,且置於src/main/java/下的Mapper接口需要用@Mapper註解標識,不然映射文件與接口無法匹配。
  • SpringBoot建議使用YAML作爲配置文件,它有更簡便的配置方式。所以整合Mybatis在配置文件上有一定的區別,但最終都是那幾個參數的配置。

整合配置文件

在Spring階段用XML配置mybatis無非就是配置:1.連接池;2.數據庫url連接;3.mysql驅動;4.其他初始化配置

SpringBoot 推薦yml格式配置文件,配置更加簡潔,當然.properties格式也是支持的,對於其它配置一樣,都在yml配置文件中,配置最大程度簡單話,儘量摒棄之前SpringMVC中的xml配置

server:
  port: 8081

spring:
    datasource:
        name: local_mysql_a50
       # url: jdbc:mysql://127.0.0.1:3306/supports-demo2?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true
        url: jdbc:mysql://localhost:3306/ssm_a50_db?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true
        username: root
        password: WFCwfc123456!@#
        # 使用druid數據源
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.jdbc.Driver
        filters: stat,wall #通過別名的方式配置擴展插件,常用的插件有:監控統計用的filter:stat,日誌用的filter:log4j,防禦sql注入的filter:wall
        minIdle: 10       #最小空閒連接個數
        maxActive: 100                       #最大連接個數
        initialSize: 10                      #初始化連接個數
        maxWait: 60000    #獲取連接時最大等待時間,單位毫秒
        timeBetweenEvictionRunsMillis: 60000 #配置間隔多久才進行一次檢測,檢測需要關閉的空閒連接,單位是毫秒ååå
        minEvictableIdleTimeMillis: 300000   #配置一個連接在池中最小生存的時間,單位是毫秒
        validationQuery: select 'x'          #用來檢測連接是否有效的sql,要求是一個查詢語句。
        testWhileIdle: true                  #建議配置爲true,不影響性能,並且保證安全性。如果空閒時間大於timeBetweenEvictionRunsMillis,執行validationQuery檢測連接是否有效
        testOnBorrow: false                  #申請連接時執行validationQuery檢測連接是否有效,做了這個配置會降低性能
        testOnReturn: false                  #歸還連接時執行validationQuery檢測連接是否有效,做了這個配置會降低性能
        poolPreparedStatements: true         #是否緩存preparedStatement,也就是PSCache。PSCache對支持遊標的數據庫性能提升巨大,比如說oracle。在mysql下建議關閉。
        maxPoolPreparedStatementPerConnectionSize: 100  #要啓用PSCache,必須配置大於0,當大於0時,poolPreparedStatements自動觸發修改爲true。在Druid中,不會存在Oracle下PSCache佔用內存過多的問題,可以把這個數值配置大一些,比如說100
        maxOpenPreparedStatements: 100                  #要啓用PSCache,必須配置大於0,當大於0時,poolPreparedStatements自動觸發修改爲true。在Druid中,不會存在Oracle下PSCache佔用內存過多的問題,可以把這個數值配置大一些,比如說100
mybatis:
  mapper-locations: classpath:mapper/*.xml
  type-aliases-package: com.mybatisstudy.domain

mapper:
  mappers: com.mybatisstudy.dao
  not-empty: false
  identity: MYSQL

pagehelper:
    helperDialect: mysql
    reasonable: true
    supportMethodsArguments: true
    params: count=countSql
    returnPageInfo: check

注意:空格代表節點層次;註釋部分用#標記

解釋

  1. 我們實現的是spring-mybatis的整合,包含mybatis的配置以及datasource數據源的配置當然屬於spring配置中的一部分,所以需要在spring:下。
  2. mapper-locations相當於XML中的用來掃描Mapper層的配置文件,由於我們的配置文件在resources下,所以需要指定classpath:。
  3. type-aliases-package相當與XML中別名配置,一般取其下實體類類名作爲別名。
  4. datasource數據源的配置,name表示當前數據源的名稱,類似於之前的id屬性,這裏可以任意指定,因爲我們無需關注Spring是怎麼注入這個Bean對象的。
  5. druid代表本項目中使用了阿里的druid連接池,driver-class-name:相當於XML中的
<property
    name="driverClassName">;url代表XML中的<property
    name="url">;username代表XML中的<property
    name="username">;password代表XML中的<property
    name="password">

其他druid的私有屬性配置不再解釋。這裏注意druid連接池和c3p0連接池在XML的的name中就不同,在此處SpringBoot的配置中當然名稱也不同。

如果Spring整合Mybtis的配置你已經很熟悉了,那麼這個配置你肯定也很眼熟,從英文名稱上就很容易區分出來。這裏需要注意的就是YAML語法規定不同行空格代表了不同的層級結構。

既然完成了SpringBoot-Mybatis基本配置下面我們實戰講解如何實現基本的CRUD。其它配置按照相應的格式配置即可

項目結構圖

在這裏插入圖片描述

MyBatis相關

  1. 配置文件:上面提到,SpringBoot集成MyBatis和SpringMVC集成MyBatis使用上面無太大不同,主要是配置方式不同,上面配置已經介紹
  2. 數據源配置:DataSourceConfig.java文件中,需要到三個註解
@Configuration
@MapperScan("com.mybatisstudy.dao")
@EnableTransactionManagement
@Configuration
@MapperScan("com.mybatisstudy.dao")
@EnableTransactionManagement
public class DataSourceConfig {
    @Autowired
    private Environment env;

    @Autowired
    private PageInterceptor pageInterceptor;

    @Bean
    public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
        SqlSessionFactoryBean fb = new SqlSessionFactoryBean();
        fb.setDataSource(dataSource);
        //該配置非常的重要,如果不將PageInterceptor設置到SqlSessionFactoryBean中,導致分頁失效
        fb.setPlugins(new Interceptor[]{pageInterceptor});
        fb.setTypeAliasesPackage(env.getProperty("mybatis.type-aliases-package"));
        fb.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(env.getProperty("mybatis.mapper-locations")));
        return fb.getObject();
    }
    
}

對於@MapperScan 必須寫明,不然DAO層無法到對應的文件.xml文件

Druid相關
Druid配置,數據庫連接池,除了池概念就是sql監控

  1. 配置文件:yml配置文件中,配置druid內容
  2. 配置數據源:配置數據源,註解web過濾器,後臺管理的Servlet.在DruidDBConfig.java 文件中配置,主要用@Configuration 註解即可,然後進行配置。

@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.driver-class-name}")
    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) {
            logger.error("druid configuration initialization filter", e);
        }
        datasource.setConnectionProperties(connectionProperties);
        return datasource;
    }

    //1、配置一個管理後臺的Servlet
    @Bean
    public ServletRegistrationBean statViewServlet() {
        ServletRegistrationBean bean = new ServletRegistrationBean(new StatViewServlet(), "/druid/*");
        Map<String, String> initParams = new HashMap<>();
        initParams.put("loginUsername", "admin");
        initParams.put("loginPassword", "admin");
        initParams.put("allow", "");//默認就是允許所有訪問
        initParams.put("deny", "192.168.15.21");//黑名單的IP
        bean.setInitParameters(initParams);
        return bean;
    }

    //2、配置一個web監控的filter
    @Bean
    public FilterRegistrationBean webStatFilter() {
        FilterRegistrationBean bean = new FilterRegistrationBean();
        bean.setFilter(new WebStatFilter());
        Map<String, String> initParams = new HashMap<>();
        initParams.put("exclusions", "*.js,*.css,/druid/*");
        bean.setInitParameters(initParams);
        bean.setUrlPatterns(Arrays.asList("/*"));
        return bean;
    }


分頁組件pagehelper相關

  1. 配置到yml文件

pagehelper:
helperDialect: mysql
reasonable: true
supportMethodsArguments: true
params: count=countSql
returnPageInfo: check

  1. 配置註解:
@Configuration
public class PageHelperConfig {
    @Value("${pagehelper.helperDialect}")
    private String helperDialect;
    @Bean
    public PageInterceptor pageInterceptor(){
        PageInterceptor pageInterceptor = new PageInterceptor();
        Properties properties = new Properties();
        properties.setProperty("helperDialect", helperDialect);
        pageInterceptor.setProperties(properties);
        return pageInterceptor;
    }
}
  1. 使用:
    在dao層,進行查詢的時候,直接調用api,傳入具體參數。
    @Override
    public List<UserDomain> findAllUser(int pageNum, int pageSize) {
        //將參數傳給這個方法就可以實現物理分頁了,非常簡單。
        PageHelper.startPage(pageNum, pageSize);
        return userDao.selectUsers();
    }

在調用數據庫之前,PageHelper.startPage(pageNum, pageSize);非常簡單。如果需要其它功能,可以具體查一下具體api即可。

Controller層

@Controller
@RequestMapping(value = "/user")
public class UserController {

    @Autowired
    private UserService userService;
    @ResponseBody
    @PostMapping("/add")
    public int addUser(@RequestBody UserDomain user) {
        return userService.addUser(user);
    }
	@ResponseBody
	@GetMapping("/all")
	public Object findAllUser(@RequestParam(name = "pageNum", required = false, defaultValue = "1") int pageNum,
							  @RequestParam(name = "pageSize", required = false, defaultValue = "5") int pageSize) {
		return userService.findAllUser(pageNum, pageSize);
	}
}

注意點
SpringBoot2中搞清楚視圖層:@RestController 和 @Controller 的區別

  1. 在springboot中,@RestController 相當於 @Controller + @ResponseBody;
  2. 即在Controller類中,若想返回jsp或html頁面,則不能用@RestController,只能使用@Controller;
  3. 若返回的是json或xml數據,可以有兩種寫法:
1. @RestController註解,然後直接return json數據即可;
2. @Controller註解放類之前,然後若類中某個方法需要返回json數據,則需在該方法前添加@ResponseBody註解;

Durid監控

項目跑起來後,我們在durid配置中已經配置了Selevlet的攔截器,並配置了賬號密碼

//1、配置一個管理後臺的Servlet
    @Bean
    public ServletRegistrationBean statViewServlet() {
        ServletRegistrationBean bean = new ServletRegistrationBean(new StatViewServlet(), "/druid/*");
        Map<String, String> initParams = new HashMap<>();
        initParams.put("loginUsername", "admin");
        initParams.put("loginPassword", "admin");
        initParams.put("allow", "");//默認就是允許所有訪問
        initParams.put("deny", "192.168.15.21");//黑名單的IP
        bean.setInitParameters(initParams);
        return bean;
    }

直接訪問監控後臺頁面:http://localhost:8081/druid/datasource.html
根據自己設置端口,更改端口。監控極大利於研發人員對性能進行監控,改善系統性能。
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述

發佈了354 篇原創文章 · 獲贊 119 · 訪問量 69萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章