springBoot+Mybatis模板代码

Posted 晴空无云

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了springBoot+Mybatis模板代码相关的知识,希望对你有一定的参考价值。

目录

  1 目录结构

  2 全局配置文件

    2.1 application.properties(resources下,自动生成)

    2.2 mybatis-config.xml(resources下,手动创建)

    2.3 config文件夹(java包下,手动创建)

      2.3.1 mapper文件夹

      2.3.2 service文件夹

  3 代码流程

    3.1 第一步:Entity层

    3.2 第二步:Dao层

    3.3 第三步:Mapper配置文件

    3.4 第四部:测试Dao层类

    3.4 第五步:service层

    3.5 第六步:controller层

  4 运行效果

1 目录结构

   

 

    注意:

    1)Java包下的子文件夹需要手动创建

     2)resources下的mapper文件夹和mybatis-config.xml文件需要手动创建。

2 全局配置文件

  全局配置文件主要包括数据库配置、服务端口配置、事务配置等。

2.1 application.properties(resources下,自动生成)

  application.properties是全局配置文件,通过修改此文件可以实现自定义配置,如端口、根路径等。

本模板仅配置数据源配置,配置如下:

  

#DataSource
#数据库驱动(高版本mysql配置)
jdbc.driver=com.mysql.cj.jdbc.Driver
#数据库链接(高版本mysql配置)
jdbc.url=jdbc:mysql://localhost:3306/demo?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone = GMT
#数据库用户名
jdbc.username=root
#数据库密码
jdbc.password=1234

#Mybatis
mybatis_config_file=mybatis-config.xml
mapper_path=/mapper/**.xml
# 要与包名一致
type_alias_package=com.example.demo.entity

2.2 mybatis-config.xml(resources下,手动创建)

  此文件需要手动创建。名称可以自定义,需要与application.properties中一致。

  配置如下:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <!-- 配置全局属性 -->
    <settings>
        <!-- 使用jdbc的getGeneratedKeys获取数据库自增主键值 -->
        <setting name="useGeneratedKeys" value="true" />

        <!-- 使用列标签替换列别名 默认:true -->
        <setting name="useColumnLabel" value="true" />

        <!-- 开启驼峰命名转换:Table{create_time} -> Entity{createTime} -->
        <setting name="mapUnderscoreToCamelCase" value="true" />
    </settings>
</configuration>

2.3 config文件夹(java包下,手动创建)

  本项目中,config文件夹下包含两个子文件夹mapper和service

2.3.1 mapper文件夹

  mapper文件夹中为数据源的相关配置,主要实现全局配置文件Application.properties中的配置生效。

  1)DataSourceConfiguration(数据配置类)

    代码如下:

      

package com.example.demo.config.mapper;


import java.beans.PropertyVetoException;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.mchange.v2.c3p0.ComboPooledDataSource;

/**
 * 配置datasource到ioc容器里面
 *
 * @author xiangze
 *
 */
@Configuration
// 配置mybatis mapper的扫描路径
@MapperScan("com.example.demo.dao")
public class DataSourceConfiguration {
    @Value("${jdbc.driver}")
    private String jdbcDriver;
    @Value("${jdbc.url}")
    private String jdbcUrl;
    @Value("${jdbc.username}")
    private String jdbcUsername;
    @Value("${jdbc.password}")
    private String jdbcPassword;

    /**
     * 生成与spring-dao.xml对应的bean dataSource
     *
     * @return
     * @throws PropertyVetoException
     */
    @Bean(name = "dataSource")
    public ComboPooledDataSource createDataSource() throws PropertyVetoException {
        // 生成datasource实例
        ComboPooledDataSource dataSource = new ComboPooledDataSource();
        // 跟配置文件一样设置以下信息
        // 驱动
        dataSource.setDriverClass(jdbcDriver);
        // 数据库连接URL
        dataSource.setJdbcUrl(jdbcUrl);
        // 设置用户名
        dataSource.setUser(jdbcUsername);
        // 设置用户密码
        dataSource.setPassword(jdbcPassword);
        // 配置c3p0连接池的私有属性
        // 连接池最大线程数
        dataSource.setMaxPoolSize(30);
        // 连接池最小线程数
        dataSource.setMinPoolSize(10);
        // 关闭连接后不自动commit
        dataSource.setAutoCommitOnClose(false);
        // 连接超时时间
        dataSource.setCheckoutTimeout(10000);
        // 连接失败重试次数
        dataSource.setAcquireRetryAttempts(2);
        return dataSource;
    }
}
DataSourceConfiguration

  2)SessionFactoryConfiguration(数据库连接池配置类)

    代码如下:

package com.example.demo.config.mapper;

import java.io.IOException;

import javax.sql.DataSource;

import org.mybatis.spring.SqlSessionFactoryBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;

@Configuration
public class SessionFactoryConfiguration {
    // mybatis-config.xml配置文件的路径
    private static String mybatisConfigFile;

    @Value("${mybatis_config_file}")
    public void setMybatisConfigFile(String mybatisConfigFile) {
        SessionFactoryConfiguration.mybatisConfigFile = mybatisConfigFile;
    }

    // mybatis mapper文件所在路径
    private static String mapperPath;

    @Value("${mapper_path}")
    public void setMapperPath(String mapperPath) {
        SessionFactoryConfiguration.mapperPath = mapperPath;
    }

    // 实体类所在的package
    @Value("${type_alias_package}")
    private String typeAliasPackage;

    @Autowired
    private DataSource dataSource;

    /**
     * 创建sqlSessionFactoryBean 实例 并且设置configtion 设置mapper 映射路径 设置datasource数据源
     *
     * @return
     * @throws IOException
     */
    @Bean(name = "sqlSessionFactory")
    public SqlSessionFactoryBean createSqlSessionFactoryBean() throws IOException {
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        // 设置mybatis configuration 扫描路径
        sqlSessionFactoryBean.setConfigLocation(new ClassPathResource(mybatisConfigFile));
        // 添加mapper 扫描路径
        PathMatchingResourcePatternResolver pathMatchingResourcePatternResolver = new PathMatchingResourcePatternResolver();
        String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX + mapperPath;
        sqlSessionFactoryBean.setMapperLocations(pathMatchingResourcePatternResolver.getResources(packageSearchPath));
        // 设置dataSource
        sqlSessionFactoryBean.setDataSource(dataSource);
        // 设置typeAlias 包扫描路径
        sqlSessionFactoryBean.setTypeAliasesPackage(typeAliasPackage);
        return sqlSessionFactoryBean;
    }

}
SessionFactoryConfiguration(数据库连接池配置类)

2.3.2 service文件夹

  1)TransactionManagementConfiguration(事务配置类)

    代码如下:

        

package com.example.demo.config.service;


import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.transaction.annotation.TransactionManagementConfigurer;

/**
 * 对标spring-service里面的transactionManager
 * 继承TransactionManagementConfigurer是因为开启annotation-driven
 *
 * @author xiangze
 *
 */
@Configuration
// 首先使用注解 @EnableTransactionManagement 开启事务支持后
// 在Service方法上添加注解 @Transactional 便可
@EnableTransactionManagement
public class TransactionManagementConfiguration implements TransactionManagementConfigurer {

    @Autowired
    // 注入DataSourceConfiguration里边的dataSource,通过createDataSource()获取
    private DataSource dataSource;

    @Override
    /**
     * 关于事务管理,需要返回PlatformTransactionManager的实现
     */
    public PlatformTransactionManager annotationDrivenTransactionManager() {
        return new DataSourceTransactionManager(dataSource);
    }

}
TransactionManagementConfiguration(事务配置类)

3 代码流程

  编写代码的顺序,便于快速实现和测试。

3.1 第一步:Entity层

  实体类层,需要提前建立数据库、数据表并添加实例数据。

  代码如下:

package com.example.demo.entity;


import java.util.Date;

/**
 * 区域信息
 * @author xiangze
 *
 */
public class Area {
    // 主键ID
    private Integer areaId;
    // 名称
    private String areaName;
    // 权重,越大越排前显示
    private Integer priority;
    // 创建时间
    private Date createTime;
    // 更新时间
    private Date lastEditTime;

    public Integer getAreaId() {
        return areaId;
    }

    public void setAreaId(Integer areaId) {
        this.areaId = areaId;
    }

    public String getAreaName() {
        return areaName;
    }

    public void setAreaName(String areaName) {
        this.areaName = areaName;
    }

    public Integer getPriority() {
        return priority;
    }

    public void setPriority(Integer priority) {
        this.priority = priority;
    }

    public Date getCreateTime() {
        return createTime;
    }

    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }

    public Date getLastEditTime() {
        return lastEditTime;
    }

    public void setLastEditTime(Date lastEditTime) {
        this.lastEditTime = lastEditTime;
    }

}
Area

 

3.2 第二步:Dao层

  编写接口,代码如下:

package com.example.demo.dao;

import java.util.List;
import com.example.demo.entity.Area;
public interface AreaDao {

    /**
     * 列出区域列表
     *
     * @return areaList
     */
    List<Area> queryArea();

    /**
     * 根据Id列出具体区域
     *
     * @return area
     */
    Area queryAreaById(int areaId);

    /**
     * 插入区域信息
     *
     * @param area
     * @return
     */
    int insertArea(Area area);

    /**
     * 更新区域信息
     *
     * @param area
     * @return
     */
    int updateArea(Area area);

    /**
     * 删除区域信息
     *
     * @param areaId
     * @return
     */
    int deleteArea(int areaId);
}
AreaDao

3.3 第三步:Mapper配置文件

  编写Dao层中的SQL语句,代码如下:

<?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.example.demo.dao.AreaDao">
    <select id="queryArea" resultType="com.example.demo.entity.Area">
        SELECT area_id, area_name,
        priority, create_time, last_edit_time
        FROM tb_area
        ORDER BY priority
        DESC
    </select>
    <select id="queryAreaById" resultType="com.example.demo.entity.Area">
        SELECT area_id, area_name,
        priority, create_time, last_edit_time
        FROM tb_area
        WHERE
        area_id=#{areaId}
    </select>
    <insert id="insertArea" useGeneratedKeys="true" keyProperty="areaId"
            keyColumn="area_id" parameterType="com.example.demo.entity.Area">
        INSERT INTO
        tb_area(area_name,priority,
        create_time,last_edit_time)
        VALUES
        (#{areaName},#{priority},
        #{createTime},#{lastEditTime})
    </insert>
    <update id="updateArea" parameterType="com.example.demo.entity.Area">
        update tb_area
        <set>
            <if test="areaName != null">area_name=#{areaName},</if>
            <if test="priority != null">priority=#{priority},</if>
            <if test="lastEditTime != null">last_edit_time=#{lastEditTime}</if>
        </set>
        where area_id=#{areaId}
    </update>
    <delete id="deleteArea">
        DELETE FROM
        tb_area
        WHERE
        area_id =
        #{areaId}
    </delete>
</mapper>
AreaMapper.xml

3.4 第四部:测试Dao层类

  测试Dao类是否可以正常操作数据库。代码如下:

  idea下快捷方式:选中Dao类名,按Alt+Insert(先按Alt再按Insert),勾选要测试的类。具体测试方法需要手动编写。

package com.example.demo.dao;

import static org.junit.Assert.assertEquals;

import java.util.Date;
import java.util.List;

import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.MethodSorters;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import com.example.demo.entity.Area;

@RunWith(SpringRunner.class)
@SpringBootTest
@FixMethodOrder(MethodSorters.NAME_ASCENDING) // 按方法名大小升序执行
public class AreaDaoTest {
    //通过spring容器注入Dao的实现类
    @Autowired
    private AreaDao areaDao;

    @Test
    public void testAQueryArea() {
        List<Area> areaList = areaDao.queryArea();
        // 验证预期值和实际值是否相符
        assertEquals(2, areaList.size());
    }

    @Test
    public void testBInsertArea() {
        //创建一个区域对象
        Area area = new Area();
        area.setAreaName("测试区域");
        area.setCreateTime(new Date());
        area.setPriority(1);
        //将该对象实例添加入库
        int effectedNum = areaDao.insertArea(area);
        //检测影响行数
        assertEquals(1, effectedNum);
        //校验总数是否+1
        List<Area> areaList = areaDao.queryArea();
        assertEquals(3, areaList.size());
    }

    @Test
    public void testCQueryAreaById() {
        Area area = areaDao.queryAreaById(2);
        assertEquals("东苑", area.getAreaName());
    }

    @Test
    public void testDUpateArea() {
        List<Area> areaList = areaDao.queryArea();
        for (Area area : areaList) {
            if ("测试区域".equals(area.getAreaName())) {
                // 对比之前的priority值
                assertEquals(1, area.getPriority().intValue());
                area.setPriority(2);
                int effectedNum = areaDao.updateArea(area);
                assertEquals(1, effectedNum);
            }
        }
    }

    @Test
    public void testEDeleteArea() {
        List<Area> areaList = areaDao.queryArea();
        for (Area area : areaList) {
            if ("测试区域".equals(area.getAreaName())) {
                int effectedNum = areaDao.deleteArea(area.getAreaId());
                assertEquals(1, effectedNum);
            }
        }
        // 重新获取一次列表,看看总数是否少1
        areaList = areaDao.queryArea();
        assertEquals(2, areaList.size());
    }
}
AreaDaoTest

 

3.5 第四步:service层

  调用Dao层中的类实现业务逻辑,先写接口再实现,目录结构如下:

    

 

 

  代码如下:

    1)接口代码

package com.example.demo.service;

import java.util.List;

import com.example.demo.entity.Area;
public interface AreaService {
    /**
     * 获取区域列表
     *
     * @return
     */
    List<Area> getAreaList();

    /**
     * 通过区域Id获取区域信息
     *
     * @param areaId
     * @return
     */
    Area getAreaById(int areaId);

    /**
     * 增加区域信息
     *
     * @param area
     * @return
     */
    boolean addArea(Area area);

    /**
     * 修改区域信息
     *
     * @param area
     * @return
     */
    boolean modifyArea(Area area);

    /**
     * 删除区域信息
     *
     * @return
     */
    boolean deleteArea(int areaId);
}
AreaService

    2)实现类代码

   

package com.example.demo.service.Impl;


import java.io.IOException;
import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.example.demo.dao.AreaDao;
import com.example.demo.entity.Area;
import com.example.demo.service.AreaService;

@Service
public class AreaServiceImpl implements AreaService {
    @Autowired
    private AreaDao areaDao;

    @Override
    public List<Area> getAreaList() {
        // 返回所有的区域信息
        return areaDao.queryArea();
    }

    @Override
    public Area getAreaById(int areaId) {
        return areaDao.queryAreaById(areaId);
    }

    @Transactional
    @Override
    public boolean addArea(Area area) {
        // 空值判断,主要是判断areaName不为空
        if (area.getAreaName() != null && !"".equals(area.getAreaName())) {
            // 设置默认值
            area.setCreateTime(new Date());
            area.setLastEditTime(new Date());
            try {
                int effectedNum = areaDao.insertArea(area);
                if (effectedNum > 0) {
                    return true;
                } else {
                    throw new RuntimeException("添加区域信息失败!");
                }
            } catch (Exception e) {
                throw new RuntimeException("添加区域信息失败:" + e.toString());
            }
        } else {
            throw new RuntimeException("区域信息不能为空!");
        }
    }

    @Transactional
    @Override
    public boolean modifyArea(Area area) {
        // 空值判断,主要是areaId不为空
        if (area.getAreaId() != null && area.getAreaId() > 0) {
            // 设置默认值
            area.setLastEditTime(new Date());
            try {
                // 更新区域信息
                int effectedNum = areaDao.updateArea(area);
                if (effectedNum > 0) {
                    return true;
                } else {
                    throw new RuntimeException("更新区域信息失败!");
                }
            } catch (Exception e) {
                throw new RuntimeException("更新区域信息失败:" + e.toString());
            }
        } else {
            throw new RuntimeException("区域信息不能为空!");
        }
    }

    @Transactional
    @Override
    public boolean deleteArea(int areaId) {
        if (areaId > 0) {
            try {
                // 删除区域信息
                int effectedNum = areaDao.deleteArea(areaId);
                if (effectedNum > 0) {
                    return true;
                } else {
                    throw new RuntimeException("删除区域信息失败!");
                }
            } catch (Exception e) {
                throw new RuntimeException("删除区域信息失败:" + e.toString());
            }
        } else {
            throw new RuntimeException("区域Id不能为空!");
        }
    }
}
AreaServiceImpl

 

    

3.6 第五步:controller层

  controller负责接收请求和响应。

  代码如下:

package com.example.demo.controller;


import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.example.demo.entity.Area;
import com.example.demo.service.AreaService;
@RestController
public class AreaController {
    @Autowired
    private AreaService areaService;

    /**
     * 获取所有的区域信息
     *
     * @return
     */
    @RequestMapping(value = "/listarea", method = RequestMethod.GET)
    private Map<String, Object> listArea() {
        Map<String, Object> modelMap = new HashMap<String, Object>();
        List<Area> list = new ArrayList<Area>();
        // 获取区域列表
        list = areaService.getAreaList();
        modelMap.put("areaList", list);
        return modelMap;
    }

    /**
     * 通过区域Id获取区域信息
     *
     * @return
     */
    @RequestMapping(value = "/getareabyid", method = RequestMethod.GET)
    private Map<String, Object> getAreaById(Integer areaId) {
        Map<String, Object> modelMap = new HashMap<String, Object>();
        // 获取区域信息
        Area area = areaService.getAreaById(areaId);
        modelMap.put("area", area);
        return modelMap;
    }

    /**
     * 添加区域信息
     *
     * @param area
     * @return
     * @throws IOException
     * @throws JsonMappingException
     * @throws JsonParseException
     */
    @RequestMapping(value = "/addarea", method = RequestMethod.POST)
    private Map<String, Object> addArea(@RequestBody Area area)
            throws JsonParseException, JsonMappingException, IOException {
        Map<String, Object> modelMap = new HashMap<String, Object>();
        // 添加区域信息
        modelMap.put("success", areaService.addArea(area));
        return modelMap;
    }

    /**
     * 修改区域信息,主要修改名字
     *
     * @param area
     * @return
     * @throws IOException
     * @throws JsonMappingException
     * @throws JsonParseException
     */
    @RequestMapping(value = "/modifyarea", method = RequestMethod.POST)
    private Map<String, Object> modifyArea(@RequestBody Area area)
            throws JsonParseException, JsonMappingException, IOException {
        Map<String, Object> modelMap = new HashMap<String, Object>();
        // 修改区域信息
        modelMap.put("success", areaService.modifyArea(area));
        return modelMap;
    }

    @RequestMapping(value = "/removearea", method = RequestMethod.GET)
    private Map<String, Object> removeArea(Integer areaId) {
        Map<String, Object> modelMap = new HashMap<String, Object>();
        System.out.println(areaId);
        // 修改区域信息
        modelMap.put("success", areaService.deleteArea(areaId));
        return modelMap;
    }
}
AreaServiceImpl

4 运行效果

  

 

以上是关于springBoot+Mybatis模板代码的主要内容,如果未能解决你的问题,请参考以下文章

还在写CURD?试试这款基于mybatis-plus的springboot代码生成器

一个基于SpringBoot + Mybatis + Vue的代码生成器

Mybatis Plus 生成数据库访问模板代码

Mybatis Plus 生成数据库访问模板代码

SpringBoot学习- 11更好用的代码生成工具EasyCode

SpringBoot使用Mybatis-PageHelper