美文网首页从零开始学springboot
从零开始学springboot-搭建一个可以上线的项目结构-单项

从零开始学springboot-搭建一个可以上线的项目结构-单项

作者: 码哥说 | 来源:发表于2019-04-30 10:05 被阅读0次

    前言

    接 从零开始学springboot-搭建一个可以上线的项目结构-单项目篇(1)

    完善

    service/RedisService

    package com.mrcoder.sbmmultidbxmldruidatomikos.service;
    import com.mrcoder.sbmmultidbxmldruidatomikos.utils.redis.RedisUtil;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.data.redis.core.StringRedisTemplate;
    import org.springframework.stereotype.Service;
    /**
     * redis 测试业务层
     */
    @Service
    public class RedisService {
        @Autowired
        private StringRedisTemplate stringRedisTemplate;
        @Autowired
        private RedisUtil redisUtil;//内部封装了 RedisTemplate<String, Object>
        /**
         * 测试存储 String 类型数据
         */
        public void setValue(String key, String string) {
            redisUtil.set(key, string);
        }
        /**
         * 测试读取 String 类型数据
         */
        public Object getValue(String key) {
            boolean flag = redisUtil.hasKey(key);
            Object rs = null;
            if (flag) {
                rs = redisUtil.get(key);
            }
            return rs;
        }
    }
    

    service/StudentService

    package com.mrcoder.sbmmultidbxmldruidatomikos.service;
    import com.mrcoder.sbmmultidbxmldruidatomikos.entity.master.Student;
    import java.util.List;
    public interface StudentService {
        public List<Student> getListByAnno();
        public List<Student> getList();
        public Student getById(Long id);
        public Integer save(Student s);
        public Integer update(Student s);
        public Integer delete(Long id);
        public void trans(int code);
    }
    

    service/TeacherService

    package com.mrcoder.sbmmultidbxmldruidatomikos.service;
    public class TeacherService {
    }
    

    service/impl/StudentServiceImpl

    package com.mrcoder.sbmmultidbxmldruidatomikos.service.impl;
    import com.mrcoder.sbmmultidbxmldruidatomikos.entity.master.Student;
    import com.mrcoder.sbmmultidbxmldruidatomikos.entity.slave.Teacher;
    import com.mrcoder.sbmmultidbxmldruidatomikos.mapper.master.StudentMapper;
    import com.mrcoder.sbmmultidbxmldruidatomikos.mapper.slave.TeacherMapper;
    import com.mrcoder.sbmmultidbxmldruidatomikos.service.StudentService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    import org.springframework.transaction.annotation.Transactional;
    import java.util.List;
    @Service
    public class StudentServiceImpl implements StudentService {
        @Autowired
        private StudentMapper studentMapper;
        @Autowired
        private TeacherMapper teacherMapper;
        public List<Student> getListByAnno() {
            return studentMapper.getListByAnno();
        }
        public List<Student> getList() {
            return studentMapper.getList();
        }
        public Student getById(Long id) {
            return studentMapper.getById(id);
        }
        public Integer save(Student s) {
            return studentMapper.insert(s);
        }
        public Integer update(Student s) {
            return studentMapper.update(s);
        }
        public Integer delete(Long id) {
            return studentMapper.delete(id);
        }
        @Transactional
        public void trans(int code) {
            Student s1 = new Student();
            s1.setAge(10);
            s1.setGrade(10);
            s1.setName("s1");
            studentMapper.insert(s1);
    
            Teacher t1 = new Teacher();
            t1.setAge(10);
            t1.setName("t1");
            t1.setCourse(10);
            teacherMapper.insert(t1);
            int result = 1 / code;
        }
    }
    

    service/impl/TeacherServiceImpl

    package com.mrcoder.sbmmultidbxmldruidatomikos.service.impl;
    public class TeacherServiceImpl {
    }
    

    utils/redis/RedisUtil

    package com.mrcoder.sbmmultidbxmldruidatomikos.utils.redis;
    import org.springframework.data.redis.core.RedisTemplate;
    import org.springframework.util.CollectionUtils;
    import java.util.List;
    import java.util.Map;
    import java.util.Set;
    import java.util.concurrent.TimeUnit;
    /**
     * @Description: redis 工具类
     */
    public class RedisUtil {
        private RedisTemplate<String, Object> redisTemplate;
        public void setRedisTemplate(RedisTemplate<String, Object> redisTemplate) {
            this.redisTemplate = redisTemplate;
        }
        /**
         * 指定缓存失效时间
         *
         * @param key  键
         * @param time 时间(秒)
         * @return
         */
        public boolean expire(String key, long time) {
            try {
                if (time > 0) {
                    redisTemplate.expire(key, time, TimeUnit.SECONDS);
                }
                return true;
            } catch (Exception e) {
                e.printStackTrace();
                return false;
            }
        }
        /**
         * 根据key 获取过期时间
         *
         * @param key 键 不能为null
         * @return 时间(秒) 返回0代表为永久有效
         */
        public long getExpire(String key) {
            return redisTemplate.getExpire(key, TimeUnit.SECONDS);
        }
        /**
         * 判断key是否存在
         *
         * @param key 键
         * @return true 存在 false不存在
         */
        public boolean hasKey(String key) {
            try {
                return redisTemplate.hasKey(key);
            } catch (Exception e) {
                e.printStackTrace();
                return false;
            }
        }
        /**
         * 删除缓存
         *
         * @param key 可以传一个值 或多个
         */
        @SuppressWarnings("unchecked")
        public void del(String... key) {
            if (key != null && key.length > 0) {
                if (key.length == 1) {
                    redisTemplate.delete(key[0]);
                } else {
                    redisTemplate.delete(CollectionUtils.arrayToList(key));
                }
            }
        }
        /**
         * 普通缓存获取
         *
         * @param key 键
         * @return 值
         */
        public Object get(String key) {
            return key == null ? null : redisTemplate.opsForValue().get(key);
        }
        /**
         * 普通缓存放入
         *
         * @param key   键
         * @param value 值
         * @return true成功 false失败
         */
        public boolean set(String key, Object value) {
            try {
                redisTemplate.opsForValue().set(key, value);
                return true;
            } catch (Exception e) {
                e.printStackTrace();
                return false;
            }
        }
        /**
         * 普通缓存放入并设置时间
         *
         * @param key   键
         * @param value 值
         * @param time  时间(秒) time要大于0 如果time小于等于0 将设置无限期
         * @return true成功 false 失败
         */
        public boolean set(String key, Object value, long time) {
            try {
                if (time > 0) {
                    redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
                } else {
                    set(key, value);
                }
                return true;
            } catch (Exception e) {
                e.printStackTrace();
                return false;
            }
        }
        /**
         * 递增
         *
         * @param key   键
         * @param delta 要增加几(大于0)
         * @return
         */
        public long incr(String key, long delta) {
            if (delta < 0) {
                throw new RuntimeException("递增因子必须大于0");
            }
            return redisTemplate.opsForValue().increment(key, delta);
        }
        /**
         * 递减
         *
         * @param key   键
         * @param delta 要减少几(小于0)
         * @return
         */
        public long decr(String key, long delta) {
            if (delta < 0) {
                throw new RuntimeException("递减因子必须大于0");
            }
            return redisTemplate.opsForValue().increment(key, -delta);
        }
        /**
         * HashGet
         *
         * @param key  键 不能为null
         * @param item 项 不能为null
         * @return 值
         */
        public Object hget(String key, String item) {
            return redisTemplate.opsForHash().get(key, item);
        }
        /**
         * 获取hashKey对应的所有键值
         *
         * @param key 键
         * @return 对应的多个键值
         */
        public Map<Object, Object> hmget(String key) {
            return redisTemplate.opsForHash().entries(key);
        }
        /**
         * HashSet
         *
         * @param key 键
         * @param map 对应多个键值
         * @return true 成功 false 失败
         */
        public boolean hmset(String key, Map<String, Object> map) {
            try {
                redisTemplate.opsForHash().putAll(key, map);
                return true;
            } catch (Exception e) {
                e.printStackTrace();
                return false;
            }
        }
        /**
         * HashSet 并设置时间
         *
         * @param key  键
         * @param map  对应多个键值
         * @param time 时间(秒)
         * @return true成功 false失败
         */
        public boolean hmset(String key, Map<String, Object> map, long time) {
            try {
                redisTemplate.opsForHash().putAll(key, map);
                if (time > 0) {
                    expire(key, time);
                }
                return true;
            } catch (Exception e) {
                e.printStackTrace();
                return false;
            }
        }
        /**
         * 向一张hash表中放入数据,如果不存在将创建
         *
         * @param key   键
         * @param item  项
         * @param value 值
         * @return true 成功 false失败
         */
        public boolean hset(String key, String item, Object value) {
            try {
                redisTemplate.opsForHash().put(key, item, value);
                return true;
            } catch (Exception e) {
                e.printStackTrace();
                return false;
            }
        }
        /**
         * 向一张hash表中放入数据,如果不存在将创建
         *
         * @param key   键
         * @param item  项
         * @param value 值
         * @param time  时间(秒)  注意:如果已存在的hash表有时间,这里将会替换原有的时间
         * @return true 成功 false失败
         */
        public boolean hset(String key, String item, Object value, long time) {
            try {
                redisTemplate.opsForHash().put(key, item, value);
                if (time > 0) {
                    expire(key, time);
                }
                return true;
            } catch (Exception e) {
                e.printStackTrace();
                return false;
            }
        }
        /**
         * 删除hash表中的值
         *
         * @param key  键 不能为null
         * @param item 项 可以使多个 不能为null
         */
        public void hdel(String key, Object... item) {
            redisTemplate.opsForHash().delete(key, item);
        }
        /**
         * 判断hash表中是否有该项的值
         *
         * @param key  键 不能为null
         * @param item 项 不能为null
         * @return true 存在 false不存在
         */
        public boolean hHasKey(String key, String item) {
            return redisTemplate.opsForHash().hasKey(key, item);
        }
        /**
         * hash递增 如果不存在,就会创建一个 并把新增后的值返回
         *
         * @param key  键
         * @param item 项
         * @param by   要增加几(大于0)
         * @return
         */
        public double hincr(String key, String item, double by) {
            return redisTemplate.opsForHash().increment(key, item, by);
        }
        /**
         * hash递减
         *
         * @param key  键
         * @param item 项
         * @param by   要减少记(小于0)
         * @return
         */
        public double hdecr(String key, String item, double by) {
            return redisTemplate.opsForHash().increment(key, item, -by);
        }
        /**
         * 根据key获取Set中的所有值
         *
         * @param key 键
         * @return
         */
        public Set<Object> sGet(String key) {
            try {
                return redisTemplate.opsForSet().members(key);
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
        }
        /**
         * 根据value从一个set中查询,是否存在
         *
         * @param key   键
         * @param value 值
         * @return true 存在 false不存在
         */
        public boolean sHasKey(String key, Object value) {
            try {
                return redisTemplate.opsForSet().isMember(key, value);
            } catch (Exception e) {
                e.printStackTrace();
                return false;
            }
        }
        /**
         * 将数据放入set缓存
         *
         * @param key    键
         * @param values 值 可以是多个
         * @return 成功个数
         */
        public long sSet(String key, Object... values) {
            try {
                return redisTemplate.opsForSet().add(key, values);
            } catch (Exception e) {
                e.printStackTrace();
                return 0;
            }
        }
        /**
         * 将set数据放入缓存
         *
         * @param key    键
         * @param time   时间(秒)
         * @param values 值 可以是多个
         * @return 成功个数
         */
        public long sSetAndTime(String key, long time, Object... values) {
            try {
                Long count = redisTemplate.opsForSet().add(key, values);
                if (time > 0) expire(key, time);
                return count;
            } catch (Exception e) {
                e.printStackTrace();
                return 0;
            }
        }
        /**
         * 获取set缓存的长度
         *
         * @param key 键
         * @return
         */
        public long sGetSetSize(String key) {
            try {
                return redisTemplate.opsForSet().size(key);
            } catch (Exception e) {
                e.printStackTrace();
                return 0;
            }
        }
        /**
         * 移除值为value的
         *
         * @param key    键
         * @param values 值 可以是多个
         * @return 移除的个数
         */
        public long setRemove(String key, Object... values) {
            try {
                Long count = redisTemplate.opsForSet().remove(key, values);
                return count;
            } catch (Exception e) {
                e.printStackTrace();
                return 0;
            }
        }
       //===============================list=================================
        /**
         * 获取list缓存的内容
         *
         * @param key   键
         * @param start 开始
         * @param end   结束  0 到 -1代表所有值
         * @return
         */
        public List<Object> lGet(String key, long start, long end) {
            try {
                return redisTemplate.opsForList().range(key, start, end);
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
        }
        /**
         * 获取list缓存的长度
         *
         * @param key 键
         * @return
         */
        public long lGetListSize(String key) {
            try {
                return redisTemplate.opsForList().size(key);
            } catch (Exception e) {
                e.printStackTrace();
                return 0;
            }
        }
        /**
         * 通过索引 获取list中的值
         *
         * @param key   键
         * @param index 索引  index>=0时, 0 表头,1 第二个元素,依次类推;index<0时,-1,表尾,-2倒数第二个元素,依次类推
         * @return
         */
        public Object lGetIndex(String key, long index) {
            try {
                return redisTemplate.opsForList().index(key, index);
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
        }
        /**
         * 将list放入缓存
         *
         * @param key   键
         * @param value 值
         * @return
         */
        public boolean lSet(String key, Object value) {
            try {
                redisTemplate.opsForList().rightPush(key, value);
                return true;
            } catch (Exception e) {
                e.printStackTrace();
                return false;
            }
        }
        /**
         * 将list放入缓存
         *
         * @param key   键
         * @param value 值
         * @param time  时间(秒)
         * @return
         */
        public boolean lSet(String key, Object value, long time) {
            try {
                redisTemplate.opsForList().rightPush(key, value);
                if (time > 0) expire(key, time);
                return true;
            } catch (Exception e) {
                e.printStackTrace();
                return false;
            }
        }
        /**
         * 将list放入缓存
         *
         * @param key   键
         * @param value 值
         * @return
         */
        public boolean lSet(String key, List<Object> value) {
            try {
                redisTemplate.opsForList().rightPushAll(key, value);
                return true;
            } catch (Exception e) {
                e.printStackTrace();
                return false;
            }
        }
        /**
         * 将list放入缓存
         *
         * @param key   键
         * @param value 值
         * @param time  时间(秒)
         * @return
         */
        public boolean lSet(String key, List<Object> value, long time) {
            try {
                redisTemplate.opsForList().rightPushAll(key, value);
                if (time > 0) expire(key, time);
                return true;
            } catch (Exception e) {
                e.printStackTrace();
                return false;
            }
        }
        /**
         * 根据索引修改list中的某条数据
         *
         * @param key   键
         * @param index 索引
         * @param value 值
         * @return
         */
        public boolean lUpdateIndex(String key, long index, Object value) {
            try {
                redisTemplate.opsForList().set(key, index, value);
                return true;
            } catch (Exception e) {
                e.printStackTrace();
                return false;
            }
        }
        /**
         * 移除N个值为value
         *
         * @param key   键
         * @param count 移除多少个
         * @param value 值
         * @return 移除的个数
         */
        public long lRemove(String key, long count, Object value) {
            try {
                Long remove = redisTemplate.opsForList().remove(key, count, value);
                return remove;
            } catch (Exception e) {
                e.printStackTrace();
                return 0;
            }
        }
    }
    

    controller/CurdController

    package com.mrcoder.sbmmultidbxmldruidatomikos.controller;
    import com.mrcoder.sbmmultidbxmldruidatomikos.entity.master.Student;
    import com.mrcoder.sbmmultidbxmldruidatomikos.service.RedisService;
    import com.mrcoder.sbmmultidbxmldruidatomikos.service.StudentService;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.http.ResponseEntity;
    import org.springframework.web.bind.annotation.*;
    import java.util.List;
    @RestController
    public class CurdController {
        @Autowired
        private StudentService studentService;
        @Autowired
        private RedisService redisService;
        private Logger logger = LoggerFactory.getLogger(CurdController.class);
        @RequestMapping("log")
        public void testAll() {
            logger.info("====info");
            logger.warn("====warn");
            logger.error("====error");
        }
        //列表查询
        @RequestMapping("getStudentList")
        public ResponseEntity<List<Student>> getStudentList() {
            return ResponseEntity.ok(studentService.getList());
        }
        //列表查询
        @RequestMapping("getStudentListByAnno")
        public ResponseEntity<List<Student>> getStudentListByAnno() {
            return ResponseEntity.ok(studentService.getListByAnno());
        }
        //新增
        @RequestMapping("addStudent")
        public int addStudent() {
            Student student = new Student();
            student.setAge(1);
            student.setGrade(1);
            student.setName("student");
            return studentService.save(student);
        }
        //更新
        @RequestMapping("updateStudent/{id}")
        public int updateStudent(@PathVariable(name = "id") Long id) {
            Student student = new Student();
            student.setAge(10);
            student.setGrade(10);
            student.setName("update");
            student.setId(id);
            return studentService.update(student);
        }
        //删除
        @RequestMapping("deleteStudent/{id}")
        public int deleteStudent(@PathVariable(name = "id") Long id) {
            return studentService.delete(id);
        }
        //事务
        @RequestMapping("transSuccess")
        public void transSuccess() {
            //人为制造0除异常测试事务分布式事务回滚
            studentService.trans(1);
        }
        //事务
        @RequestMapping("transRoll")
        public void transRoll() {
            //人为制造0除异常测试事务分布式事务回滚
            studentService.trans(0);
        }
        //redis string读写
        @RequestMapping(value = "/redis")
        public String redis(){
            redisService.setValue("test", "test123");
            return redisService.getValue("test").toString();
        }
    }
    

    resource/generator/masterGenerator.xml

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE generatorConfiguration PUBLIC
            "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
            "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd" >
    <generatorConfiguration>
    
        <!-- 本地数据库驱动程序jar包的全路径 -->
        <classPathEntry location="D:\MaveRepository\mysql\mysql-connector-java\8.0.15\mysql-connector-java-8.0.15.jar"/>
    
        <context id="context" targetRuntime="MyBatis3">
    
            <!-- optional,旨在创建class时,对注释进行控制 -->
            <commentGenerator>
                <property name="suppressAllComments" value="true"/>
                <property name="suppressDate" value="true"/>
            </commentGenerator>
    
            <!-- 数据库的相关配置 -->
            <jdbcConnection driverClass="com.mysql.cj.jdbc.Driver" connectionURL="jdbc:mysql://192.168.145.131:3306/test"
                            userId="root" password="123456"/>
    
            <!-- 非必需,类型处理器,在数据库类型和java类型之间的转换控制-->
            <javaTypeResolver>
                <property name="forceBigDecimals" value="false"/>
            </javaTypeResolver>
    
            <!-- Model实体类生成的位置 -->
            <javaModelGenerator targetPackage="com.mrcoder.sbmmultidbxmldruidatomikos.entity.master" targetProject="src/main/java">
                <!-- 是否对model添加 构造函数 -->
                <property name="constructorBased" value="false"/>
                <!-- 是否允许子包,即targetPackage.schemaName.tableName -->
                <property name="enableSubPackages" value="true"/>
                <!-- 建立的Model对象是否 不可改变  即生成的Model对象不会有 setter方法,只有构造方法 -->
                <property name="immutable" value="false"/>
                <!-- 给Model添加一个父类 -->
                <!--<property name="rootClass" value="com.foo.louis.Hello"/>-->
                <!-- 是否对类CHAR类型的列的数据进行trim操作 -->
                <property name="trimStrings" value="true"/>
            </javaModelGenerator>
    
            <!-- *Mapper.xml 文件的位置 -->
            <sqlMapGenerator targetPackage="mapper/master" targetProject="src/main/resources">
                <property name="enableSubPackages" value="true"/>
            </sqlMapGenerator>
    
            <!-- Mapper 接口文件的位置 -->
            <javaClientGenerator targetPackage="com.mrcoder.sbmmultidbxmldruidatomikos.mapper.master" targetProject="src/main/java"
                                 type="XMLMAPPER">
                <property name="enableSubPackages" value="true"/>
                <!--
                        定义Maper.java 源代码中的ByExample() 方法的可视性,可选的值有:
                        public;
                        private;
                        protected;
                        default
                        注意:如果 targetRuntime="MyBatis3",此参数被忽略
                 -->
                <property name="exampleMethodVisibility" value=""/>
                <!--方法名计数器Important note: this property is ignored if the target runtime is MyBatis3.-->
                <property name="methodNameCalculator" value=""/>
                <!--为生成的接口添加父接口-->
                <property name="rootInterface" value=""/>
            </javaClientGenerator>
    
            <!-- 相关表的配置 -->
            <table tableName="person" enableCountByExample="false" enableDeleteByExample="false"
                   enableSelectByExample="false"
                   enableUpdateByExample="false"/>
        </context>
    </generatorConfiguration>
    

    resource/generator/slaveGenerator.xml

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE generatorConfiguration PUBLIC
            "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
            "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd" >
    <generatorConfiguration>
    
        <!-- 本地数据库驱动程序jar包的全路径 -->
        <classPathEntry location="D:\MaveRepository\mysql\mysql-connector-java\8.0.15\mysql-connector-java-8.0.15.jar"/>
    
        <context id="context" targetRuntime="MyBatis3">
    
            <!-- optional,旨在创建class时,对注释进行控制 -->
            <commentGenerator>
                <property name="suppressAllComments" value="true"/>
                <property name="suppressDate" value="true"/>
            </commentGenerator>
    
            <!-- 数据库的相关配置 -->
            <jdbcConnection driverClass="com.mysql.cj.jdbc.Driver" connectionURL="jdbc:mysql://192.168.145.131:3306/test2"
                            userId="root" password="123456"/>
    
            <!-- 非必需,类型处理器,在数据库类型和java类型之间的转换控制-->
            <javaTypeResolver>
                <property name="forceBigDecimals" value="false"/>
            </javaTypeResolver>
    
            <!-- Model实体类生成的位置 -->
            <javaModelGenerator targetPackage="com.mrcoder.sbmmultidbxmldruidatomikos.entity.slave" targetProject="src/main/java">
                <!-- 是否对model添加 构造函数 -->
                <property name="constructorBased" value="false"/>
                <!-- 是否允许子包,即targetPackage.schemaName.tableName -->
                <property name="enableSubPackages" value="true"/>
                <!-- 建立的Model对象是否 不可改变  即生成的Model对象不会有 setter方法,只有构造方法 -->
                <property name="immutable" value="false"/>
                <!-- 给Model添加一个父类 -->
                <!--<property name="rootClass" value="com.foo.louis.Hello"/>-->
                <!-- 是否对类CHAR类型的列的数据进行trim操作 -->
                <property name="trimStrings" value="true"/>
            </javaModelGenerator>
    
            <!-- *Mapper.xml 文件的位置 -->
            <sqlMapGenerator targetPackage="mapper/slave" targetProject="src/main/resources">
                <property name="enableSubPackages" value="true"/>
            </sqlMapGenerator>
    
            <!-- Mapper 接口文件的位置 -->
            <javaClientGenerator targetPackage="com.mrcoder.sbmmultidbxmldruidatomikos.mapper.slave" targetProject="src/main/java"
                                 type="XMLMAPPER">
                <property name="enableSubPackages" value="true"/>
                <!--
                        定义Maper.java 源代码中的ByExample() 方法的可视性,可选的值有:
                        public;
                        private;
                        protected;
                        default
                        注意:如果 targetRuntime="MyBatis3",此参数被忽略
                 -->
                <property name="exampleMethodVisibility" value=""/>
                <!--方法名计数器Important note: this property is ignored if the target runtime is MyBatis3.-->
                <property name="methodNameCalculator" value=""/>
                <!--为生成的接口添加父接口-->
                <property name="rootInterface" value=""/>
            </javaClientGenerator>
    
            <!-- 相关表的配置 -->
            <table tableName="info" enableCountByExample="false" enableDeleteByExample="false"
                   enableSelectByExample="false"
                   enableUpdateByExample="false"/>
        </context>
    </generatorConfiguration>
    

    mapper/master/StudentMapper.xml

    <?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.mrcoder.sbmmultidbxmldruidatomikos.mapper.master.StudentMapper">
        <resultMap id="BaseResultMap" type="com.mrcoder.sbmmultidbxmldruidatomikos.entity.master.Student">
            <id column="id" property="id" jdbcType="INTEGER"/>
            <result column="name" property="name" jdbcType="VARCHAR"/>
            <result column="age" property="age" jdbcType="INTEGER"/>
            <result column="grade" property="grade" javaType="INTEGER"/>
        </resultMap>
    
        <sql id="Base_Column_List">
            id, name, age, grade
        </sql>
    
        <select id="getList" resultMap="BaseResultMap">
            SELECT
            <include refid="Base_Column_List"/>
            FROM student
        </select>
    
        <select id="getById" parameterType="java.lang.Long" resultMap="BaseResultMap">
            SELECT
            <include refid="Base_Column_List"/>
            FROM student
            WHERE id = #{id}
        </select>
    
        <insert id="insert" parameterType="com.mrcoder.sbmmultidbxmldruidatomikos.entity.master.Student">
           INSERT INTO
                student
                (age,grade,name)
            VALUES
                (#{age}, #{grade}, #{name})
        </insert>
    
        <update id="update" parameterType="com.mrcoder.sbmmultidbxmldruidatomikos.entity.master.Student">
            UPDATE
            student
            SET
            age = #{age},
            grade = #{grade},
            name = #{name}
            WHERE
            id = #{id}
        </update>
    
        <delete id="delete" parameterType="java.lang.Long">
           DELETE FROM
                 student
           WHERE
                 id =#{id}
        </delete>
    </mapper>
    

    mapper/slave/TeacherMapper.xml

    <?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.mrcoder.sbmmultidbxmldruidatomikos.mapper.slave.TeacherMapper">
        <resultMap id="BaseResultMap" type="com.mrcoder.sbmmultidbxmldruidatomikos.entity.slave.Teacher">
            <id column="id" property="id" jdbcType="INTEGER"/>
            <result column="name" property="name" jdbcType="VARCHAR"/>
            <result column="age" property="age" jdbcType="INTEGER"/>
            <result column="course" property="course" javaType="INTEGER"/>
        </resultMap>
    
        <sql id="Base_Column_List">
            id, name, age, course
        </sql>
    
        <select id="getList" resultMap="BaseResultMap">
            SELECT
            <include refid="Base_Column_List"/>
            FROM teacher
        </select>
    
        <select id="getById" parameterType="java.lang.Long" resultMap="BaseResultMap">
            SELECT
            <include refid="Base_Column_List"/>
            FROM teacher
            WHERE id = #{id}
        </select>
    
        <insert id="insert" parameterType="com.mrcoder.sbmmultidbxmldruidatomikos.entity.slave.Teacher">
           INSERT INTO
                teacher
                (age,course,name)
            VALUES
                (#{age}, #{course}, #{name})
        </insert>
    
        <update id="update" parameterType="com.mrcoder.sbmmultidbxmldruidatomikos.entity.slave.Teacher">
            UPDATE
            teacher
            SET
            age = #{age},
            course = #{course},
            name = #{name}
            WHERE
            id = #{id}
        </update>
    
        <delete id="delete" parameterType="java.lang.Long">
           DELETE FROM
                 teacher
           WHERE
                 id =#{id}
        </delete>
    
    </mapper>
    

    application.yml

    ## 公共配置start
    ## 配置数据源相关信息
    spring:
      ## 环境配置
      profiles:
        active: dev
      ## 数据源设置
      datasource:
        type: com.alibaba.druid.pool.xa.DruidXADataSource
        druid:
          ## 连接池配置
          master:
            ## JDBC配置
            name: master
            url: jdbc:mysql://192.168.145.131:3306/test?useUnicode=true&characterEncoding=UTF-8&useSSL=false&autoReconnect=true&failOverReadOnly=false&serverTimezone=GMT%2B8
            username: root
            password: 123456
            driver-class-name: com.mysql.cj.jdbc.Driver
            filters: stat
            maxActive: 20
            initialSize: 1
            maxWait: 60000
            minIdle: 1
            timeBetweenEvictionRunsMillis: 60000
            minEvictableIdleTimeMillis: 300000
            validationQuery: select 'x'
            testWhileIdle: true
            testOnBorrow: true
            testOnReturn: true
            poolPreparedStatements: true
            maxOpenPreparedStatements: 20
          slave:
            ## JDBC配置
            name: slave
            url: jdbc:mysql://192.168.145.131:3306/test2?useUnicode=true&characterEncoding=UTF-8&useSSL=false&autoReconnect=true&failOverReadOnly=false&serverTimezone=GMT%2B8
            username: root
            password: 123456
            driver-class-name: com.mysql.cj.jdbc.Driver
            filters: stat
            maxActive: 20
            initialSize: 1
            maxWait: 60000
            minIdle: 1
            timeBetweenEvictionRunsMillis: 60000
            minEvictableIdleTimeMillis: 300000
            validationQuery: select 'x'
            testWhileIdle: true
            testOnBorrow: true
            testOnReturn: true
            poolPreparedStatements: true
            maxOpenPreparedStatements: 20
    
      redis:
        host: 127.0.0.1  # redis服务所在的地址
        port: 6379
        password:   # redis的密码默认为空
        pool:
          max-active: 8  #连接池最大连接数(使用负值表示没有限制)
          max-idle: 8  #连接池最大空闲数
          min-idle: 1  #连接池最小空闲数
          max-wait: 60000  #获取连接的超时等待事件
        timeout: 30000  #连接redis服务器的最大等待时间
    
      #druid监控页面用户名和密码
      druid:
        name: admin
        pass: admin
    
    ## 该配置节点为独立的节点
    mybatis:
      mapper-locations: classpath:mapper/*/*.xml  # 注意:一定要对应mapper映射xml文件的所在路径
      type-aliases-package: com.mrcoder.sbmmultidbxmldruidatomikos.entity # 注意:对应实体类的路径
      configuration:
        map-underscore-to-camel-case: true
    
    ## 公共配置 end
    ---
    ## 开发环境配置
    spring:
      profiles: dev
    server:
      port: 8080
    ---
    ## 测试环境配置
    spring:
      profiles: test
    server:
      port: 8082
    ---
    ## 生产环境配置
    spring:
      profiles: prod
    server:
      port: 8084
    

    jta.properties

    com.atomikos.icatch.service=com.atomikos.icatch.standalone.UserTransactionServiceFactory
    com.atomikos.icatch.max_timeout=600000
    com.atomikos.icatch.default_jta_timeout=600000
    com.atomikos.icatch.log_base_dir =transaction-logs
    com.atomikos.icatch.log_base_name=springboot-mybatis
    com.atomikos.icatch.serial_jta_transactions=false
    

    logback-spring.xml

    <configuration debug="false" scan="true" scanPeriod="10 seconds">
        <contextName>logback</contextName>
        <!--输出sql语句-->
        <logger name="com.mrcoder.sbjpamultidbatomikos" level="debug"/>
        <property name="path" value="/logs"></property>
        <property name="maxHistory" value="30"/>
        <property name="maxFileSize" value="50MB"/>
    
        <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
            <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
                <level>debug</level>
            </filter>
            <encoder>
                <pattern>%date %level [%thread] %logger{36} [%file : %line] %msg%n
                </pattern>
            </encoder>
        </appender>
    
        <appender name="debug_file" class="ch.qos.logback.core.rolling.RollingFileAppender">
            <file>logs/logback_debug.log</file>
            <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
                <!-- 每天一归档 -->
                <fileNamePattern>${path}/logback_debug.log.%d{yyyy-MM-dd}-%i.zip</fileNamePattern>
                <maxHistory>${maxHistory}</maxHistory>
                <timeBasedFileNamingAndTriggeringPolicy
                        class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                    <maxFileSize>${maxFileSize}</maxFileSize>
                </timeBasedFileNamingAndTriggeringPolicy>
            </rollingPolicy>
            <encoder>
                <pattern>%date %level [%thread] %logger{36} [%file : %line] %msg%n
                </pattern>
            </encoder>
            <filter class="ch.qos.logback.classic.filter.LevelFilter">
                <level>DEBUG</level>
                <onMatch>ACCEPT</onMatch>
                <onMismatch>DENY</onMismatch>
            </filter>
        </appender>
    
        <appender name="info_file" class="ch.qos.logback.core.rolling.RollingFileAppender">
            <file>logs/logback_info.log</file>
            <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
                <!-- 每天一归档 -->
                <fileNamePattern>${path}/logback_info.log.%d{yyyy-MM-dd}-%i.zip</fileNamePattern>
                <maxHistory>${maxHistory}</maxHistory>
                <timeBasedFileNamingAndTriggeringPolicy
                        class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                    <maxFileSize>${maxFileSize}</maxFileSize>
                </timeBasedFileNamingAndTriggeringPolicy>
            </rollingPolicy>
            <encoder>
                <pattern>%date %level [%thread] %logger{36} [%file : %line] %msg%n
                </pattern>
            </encoder>
            <filter class="ch.qos.logback.classic.filter.LevelFilter">
                <level>INFO</level>
                <onMatch>ACCEPT</onMatch>
                <onMismatch>DENY</onMismatch>
            </filter>
        </appender>
    
        <appender name="warn_file" class="ch.qos.logback.core.rolling.RollingFileAppender">
            <file>logs/logback_warn.log</file>
            <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
                <!-- 每天一归档 -->
                <fileNamePattern>${path}/logback_warn.log.%d{yyyy-MM-dd}-%i.zip</fileNamePattern>
                <maxHistory>${maxHistory}</maxHistory>
                <timeBasedFileNamingAndTriggeringPolicy
                        class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                    <maxFileSize>${maxFileSize}</maxFileSize>
                </timeBasedFileNamingAndTriggeringPolicy>
            </rollingPolicy>
            <encoder>
                <pattern>%date %level [%thread] %logger{36} [%file : %line] %msg%n
                </pattern>
            </encoder>
            <filter class="ch.qos.logback.classic.filter.LevelFilter">
                <level>WARN</level>
                <onMatch>ACCEPT</onMatch>
                <onMismatch>DENY</onMismatch>
            </filter>
        </appender>
    
    
        <appender name="error_file" class="ch.qos.logback.core.rolling.RollingFileAppender">
            <file>logs/logback_error.log</file>
            <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
                <!-- 每天一归档 -->
                <fileNamePattern>${path}/logback_error.log.%d{yyyy-MM-dd}-%i.zip</fileNamePattern>
                <maxHistory>${maxHistory}</maxHistory>
                <timeBasedFileNamingAndTriggeringPolicy
                        class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                    <maxFileSize>${maxFileSize}</maxFileSize>
                </timeBasedFileNamingAndTriggeringPolicy>
            </rollingPolicy>
            <encoder>
                <pattern>%date %level [%thread] %logger{36} [%file : %line] %msg%n
                </pattern>
            </encoder>
            <filter class="ch.qos.logback.classic.filter.LevelFilter">
                <level>ERROR</level>
                <onMatch>ACCEPT</onMatch>
                <onMismatch>DENY</onMismatch>
            </filter>
        </appender>
    
        <root>
            <level value="info"/>
            <appender-ref ref="console"/>
            <appender-ref ref="debug_file"/>
            <appender-ref ref="info_file"/>
            <appender-ref ref="warn_file"/>
            <appender-ref ref="error_file"/>
        </root>
    
    </configuration>
    

    运行

    http://localhost:8080/getStudentList
    http://localhost:8080/getStudentListByAnno
    http://localhost:8080/addStudent
    http://localhost:8080/updateStudent/1
    http://localhost:8080/deleteStudent/1
    http://localhost:8080/transSuccess
    http://localhost:8080/transRoll
    http://localhost:8080/redis

    项目地址

    https://github.com/MrCoderStack/SpringBootDemo/tree/master/sbm-multidb-xml-druid-atomikos

    https://gitee.com/MrCoderStack/SpringBootDemo/tree/master/sbm-multidb-xml-druid-atomikos

    请关注我的订阅号

    订阅号.png

    相关文章

      网友评论

        本文标题:从零开始学springboot-搭建一个可以上线的项目结构-单项

        本文链接:https://www.haomeiwen.com/subject/shlmnqtx.html