SpringBoot学习(二)--SpringBoot集成mybatis+freemark

版权声明:作者原创,转载请注明出处。
本系列文章目录地址:http://blog.csdn.net/u011961421/article/details/79416510

本文在构建第一个SpringBoot工程的基础上,总结集成mybatis+freemark,实现最基础的web开发框架。

简介

MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录。

FreeMarker是一款模板引擎: 即一种基于模板和要改变的数据, 并用来生成输出文本(HTML网页、电子邮件、配置文件、源代码等)的通用工具。 它不是面向最终用户的,而是一个Java类库,是一款程序员可以嵌入他们所开发产品的组件。其模板编写为FreeMarker Template Language(FTL),属于简单、专用的语言

实战

1.配置pom依赖
在pom.xml中加入相关依赖,如下,方便大家可以自行对照比较。
需要注意的是:
(1)properties部分是增加工程的编码和jdk版本配置;
(2)这里指定的version均为稳定版本,你也可以使用最新版本(不指定及为最新)。

<?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.pf.org</groupId>
    <artifactId>cms</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>cms</name>
    <description>Demo project for Spring Boot</description>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.8.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <!-- spring web -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!-- freemarker -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-freemarker</artifactId>
            <version>1.5.8.RELEASE</version>
        </dependency>

        <!-- 数据库 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.0</version>
        </dependency>
        <!-- mybatis -->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.3.0</version>
        </dependency>

        <!-- fastjson -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.8</version>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

2.配置application.yml配置文件
由于默认application.properties文件配置方式比较繁琐,可以重命名该文件为.yml格式,具体配置如下:

server:
  port: 8080

spring:
    datasource:
        name: test
        url: jdbc:mysql://127.0.0.1:3306/cms?characterEncoding=utf8&useSSL=true
        username: root
        password: 199215
        # 使用druid数据源
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.jdbc.Driver
        filters: stat
        maxActive: 20
        initialSize: 1
        maxWait: 60000
        minIdle: 1
        timeBetweenEvictionRunsMillis: 60000
        minEvictableIdleTimeMillis: 300000
        validationQuery: select 'x'
        testWhileIdle: true
        testOnBorrow: false
        testOnReturn: false
        poolPreparedStatements: true
        maxOpenPreparedStatements: 20
    freemarker:
        #是否缓存页面
        cache: false
        #freemarker文件路径
        template-loader-path: classpath:/templates

mybatis:
    #扫描sql.xml文件
    mapper-locations: classpath:mapping/*.xml
    #自动扫描实体类
    type-aliases-package: com.pf.org.cms.entity

简单介绍:
(1)“server:”为服务器相关配置,这里先配了一个端口号为8080其他默认。
(2)“spring:”为Spring相关配置,下面包含了数据源和freemarker两小类,需要注意的是datasource的url这里的?characterEncoding=utf8&useSSL=true设置的是字符集和是否SLL加密连接,useSSL针对的是高版本mysql的配置(5.5.45+, 5.6.26+ and 5.7.6+)。
(3) freemarker的热部署需要配置cache: false。
(4)“mybatis:”为mybatis的相关配置,具体说明注释均有说明,其他配置暂时默认,后面有需要时修改。

3.编写实体类

package com.pf.org.cms.entity;

public class Demo {
    private Long id;

    private String name;

    private String remark;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getRemark() {
        return remark;
    }

    public void setRemark(String remark) {
        this.remark = remark;
    }

    @Override
    public String toString() {
        return "Demo{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", remark='" + remark + '\'' +
                '}';
    }
}

4.编写DAO层
编写接口DemoMapper

package com.pf.org.cms.mapper;

import com.pf.org.cms.entity.Demo;

import java.util.List;

public interface DemoMapper {
    List<Demo> getDemos();
}

编写映射文件DemoMapper.xml
注意namespace对应接口路径,id对应查询方法名,resultType对应返回结果类型

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.pf.org.cms.mapper.DemoMapper" >
    <select id="getDemos" resultType="com.pf.org.cms.entity.Demo">
        select * from cms_demo
    </select>
</mapper>

5.编写Service层
Service这里没有复杂的业务逻辑,为透传,如下:
DemoService.java

扫描二维码关注公众号,回复: 2649311 查看本文章
package com.pf.org.cms.service;

import com.pf.org.cms.entity.Demo;

import java.util.List;

public interface DemoService {
    public List<Demo> getDemos();
}

DemoServiceImpl.java

package com.pf.org.cms.service.impl;

import com.pf.org.cms.entity.Demo;
import com.pf.org.cms.mapper.DemoMapper;
import com.pf.org.cms.service.DemoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service(value = "demoServie")
public class DemoServiceImpl implements DemoService {
    @Autowired
    private DemoMapper demoMapper;

    @Override
    public List<Demo> getDemos() {
        return demoMapper.getDemos();
    }
}

6.编写Web层
DemoController.java

package com.pf.org.cms.web;

import com.pf.org.cms.entity.Demo;
import com.pf.org.cms.service.DemoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import java.util.List;
import java.util.Map;

@Controller
@RequestMapping(value =  "/demo")
public class DemoController {
    @Autowired
    DemoService demoService;

    @RequestMapping(value = "/getAll")
    public String testDemo(Map<String,Object> map) {
        List<Demo> demos = demoService.getDemos();
        map.put("data", demos);
        System.out.println(demos.toString());
        return ("/testDemo");
    }
}

7.编写页面
testDemo.ftl
注意页面存放路径为application.yml中配置的template-loader-path,加上controller中return返回的路径一致,例如此处application.yml在resources根目录下,则页面路径为resources/templates/testDemo.ftl。

<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body>
<div>
    <span>hello world! this is my first springboot demo!</span>
    <table border="1px">
    <#list data as item>
        <tr><td>${item.id}</td><td>${item.name}</td><td>${item.remark}</td></tr>
    </#list>
    </table>
</div>
</body>

</html>

8.启动服务,测试结果
服务启动时需要扫描mybatis的接口自动注入,所以在启动类加上扫描路径,如下
CmsApplication.java

package com.pf.org.cms;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
// mybatis 支持
@MapperScan("com.pf.org.cms.mapper")
public class CmsApplication {

    public static void main(String[] args) {
        SpringApplication.run(CmsApplication.class, args);
    }
}

注意 CmsApplication启动类根据SpringBoot建议,要放在根包目录下,若移动会导致包扫描不全而报错。
启动服务,浏览器访问http://localhost:8080/demo/getAll/ 可以看见测试数据。
这里写图片描述

9.事务支持
SpringBoot自身对事务进行了集成,关于事务管理器,不管是JPA还是JDBC等都实现自接口 PlatformTransactionManager如果你添加的是spring-boot-starter-jdbc依赖,框架会默认注入DataSourceTransactionManager实例。如果你添加的是spring-boot-starter-data-jpa依赖,框架会默认注入JpaTransactionManager实例。

所以我们需要做的仅是在配置中开启事务(使用注解@EnableTransactionManagement)即可使用@Transactional进行事务管理,注意增加配置需要编写配置类(增加配置类后可以省去步骤8),如下:

@Configuration
@EnableTransactionManagement
// mybatis 支持
@MapperScan("com.pf.org.cms.mapper")
public class BaseDataSource {

    private static final Logger log = LoggerFactory.getLogger(BaseDataSource.class);
    @Bean
    @Primary
    @ConfigurationProperties(prefix = "spring.datasource")
    public DataSource dataSource() {
        log.debug("Configuring Datasource");
        return new DruidDataSource();
    }

    @Bean
    public PlatformTransactionManager txManager() {
        return new DataSourceTransactionManager(dataSource());
    }

}

@Transactional属性

属性 类型 描述
value String 可选的限定描述符,指定使用的事务管理器
propagation enum: Propagation 可选的事务传播行为设置
isolation enum: Isolation 可选的事务隔离级别设置
readOnly boolean 读写或只读事务,默认读写
timeout int (in seconds granularity) 事务超时时间设置
rollbackFor Class对象数组,必须继承自Throwable 导致事务回滚的异常类数组
rollbackForClassName 类名数组,必须继承自Throwable 导致事务回滚的异常类名字数组
noRollbackFor Class对象数组,必须继承自Throwable 不会导致事务回滚的异常类数组
noRollbackForClassName 类名数组,必须继承自Throwable 不会导致事务回滚的异常类名字数组

@Transactional(propagation = Propagation.REQUIRED,isolation = Isolation.DEFAULT,timeout=36000,rollbackFor=Exception.class)

用法
@Transactional 可以作用于接口、接口方法、类以及类方法上。当作用于类上时,该类的所有 public 方法将都具有该类型的事务属性,同时,我们也可以在方法级别使用该标注来覆盖类级别的定义。

虽然 @Transactional 注解可以作用于接口、接口方法、类以及类方法上,但是 Spring 建议不要在接口或者接口方法上使用该注解,因为这只有在使用基于接口的代理时它才会生效。另外, @Transactional 注解应该只被应用到 public 方法上,这是由 Spring AOP 的本质决定的。如果你在 protected、private 或者默认可见性的方法上使用 @Transactional 注解,这将被忽略,也不会抛出任何异常。

默认情况下,只有来自外部的方法调用才会被AOP代理捕获,也就是,类内部方法调用本类内部的其他方法并不会引起事务行为,即使被调用方法使用@Transactional注解进行修饰。

写在最后,本文案例已上传至github(https://github.com/15651037763/cms),博主学习过程代码会同步更新至github,博文略有延迟,喜欢的可以关注。

猜你喜欢

转载自blog.csdn.net/u011961421/article/details/78674241