SpringBoot + 微信小程序1

1 Spring框架搭建

1.1 下载Eclipse的SpringBoot插件

点击菜单栏的Help->Eclipse Marketplace,选中popular页签,安装Spring Tool插件


SpringBoot + 微信小程序1_第1张图片

安装完成后可以在新建向导中看到Spring Boot的目录


SpringBoot + 微信小程序1_第2张图片

1.2 创建项目

通过新建Spring Starter Project创建项目,选择MyBatis与Web组件,可以在生成的pom文件中将mybatis的依赖注释掉。

SpringBoot + 微信小程序1_第3张图片

生成的MyFirstDemoApplication为项目启动入口,通过 @SpringBootApplication注解来标识

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

创建hello类,@RestController表示该类为controller,其中匹配的路径及方法通过@RequestMapping注解来配置

@RestController
public class hello {
    @RequestMapping(value="/hello", method=RequestMethod.GET )
    public String hello() {
        return "Hello SpringBoot";      
    }
}

右键 Run As->Spring Boot App 启动项目,可以通过http://localhost:8080/hello路径来访问该controller

2 Spring Boot 项目开发

2.1 数据库表及实体类创建

在MySQL中创建表

CREATE TABLE tb_area (
    area_id int(2) NOT NULL auto_increment,
    area_name varchar(200) NOT NULL,
    priority int(2) NOT NULL DEFAULT'0',
    create_time datetime DEFAULT NULL,
    last_edit_time datetime DEFAULT NULL,
    PRIMARY KEY(area_id),
    UNIQUE KEY UK_AREA(area_name)
)ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

在项目中新建entity包,在下面新建Area实体类,生成set/get方法

public class Area {
    private Integer areaId;
    private String areaName;
    private Integer priority;
    private Date createDate;
    private Date lastEditTime;
    // set / get method
...
}

2.2 相关配置

在pom文件中添加mysql及c3p0数据库连接池的依赖,确认mybatis依赖

        
            mysql
            mysql-connector-java
        
        
            com.mchange
            c3p0
            0.9.5.2
        

在resource下创建mybatis-config.xml文件,配置全局属性




    
    
        
        
        
        
        
        
    

创建config.dao包,在下面创建文件DataSourceConfiguration,@Configuration表示其为配置文件,@MapperScan("com.example.demo.dao")配置了扫描dao的位置,创建一个dataSource的bean,返回连接池的对象实例ComboPooledDataSource

    @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;
    }

其中变量在该方法前创建,通过@Value("${jdbc.driver}")引入application.properties文件中的配置内容

    @Value("${jdbc.driver}")
    private String jdbcDriver;
    @Value("${jdbc.url}")
    private String jdbcUrl;
    @Value("${jdbc.username}")
    private String jdbcUsername;
    @Value("${jdbc.password}")
    private String jdbcPassword;

application.properties文件中添加配置信息

#DataSource
#数据库驱动
jdbc.driver=com.mysql.jdbc.Driver
#数据库链接
jdbc.url=jdbc:mysql://localhost:3306/demo?useUnicode=true&characterEncoding=utf8&useSSL=false
#数据库用户名
jdbc.username=root

创建SessionFactoryConfiguration类,创建sqlSessionFactory bean,为其设置mybatis-config.xml的ConfigLocation,mapper文件的MapperLocations,DataSource,entity包扫描路径TypeAliasesPackage

    @Value("${mybatis_config_file}")
    private static String mybatisConfigFile;
    @Value("${mapper_path}")
    private static String mapperPath;
    // 实体类所在的package
    @Value("${type_alias_package}")
    private String typeAliasPackage;
    @Autowired
    private DataSource dataSource;

    @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;
    }

2.3 DAO

创建interface AreaDao,添加相应方法

public interface AreaDao {
    List queryArea();
    Area queryAreaById(int areaId);
    int insertArea(Area area);
    int updateArea(Area area);
    int deleteArea(int areaId);
}

在resource文件夹下创建mapper/AreaDao.xml文件,实现AreaDao中的方法




    
    
    
        INSERT INTO
        tb_area(area_name,priority, create_time,last_edit_time)
        VALUES
        (#{areaName},#{priority}, #{createTime},#{lastEditTime})
    
    
        update tb_area
        
            area_name=#{areaName},
            priority=#{priority},
            last_edit_time=#{lastEditTime}
        
        where area_id=#{areaId}
    
    
        DELETE FROM tb_area
        WHERE area_id = #{areaId}
    

创建Unit Test,@RunWith @SpringBootTest表示用springboot的测试框架来运行,@Ignore忽略该方法的测试

@RunWith(SpringRunner.class)
@SpringBootTest
public class AreaDaoTest {
    //通过spring容器注入Dao的实现类
        @Autowired
        private AreaDao areaDao;

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

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

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

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

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

2.4 Service

创建配置class TransactionManagementConfiguration,通过@Configuration @EnableTransactionManagement注解标识配置,实现TransactionManagementConfigurer方法,传入dataSource

@Configuration
@EnableTransactionManagement
public class TransactionManagementConfiguration implements TransactionManagementConfigurer{ 
    @Autowired
    private DataSource dataSource;
    @Override
    public PlatformTransactionManager annotationDrivenTransactionManager() {
        // TODO Auto-generated method stub
        return new DataSourceTransactionManager(dataSource);
    }
}

新建interface

public interface AreaService {
    List getAreaList();
    Area getAreaById(int areaId);
    boolean addArea(Area area);
    boolean modifyArea(Area area);
    boolean deleteArea(int areaId);
}

新建实现类,其中增删改通过@Transactional来进行事务管理

@service
public class AreaServiceImpl implements AreaService {

    @Autowired
    private AreaDao areaDao;

    @Override
    public List 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不能为空!");
        }
    }
}

2.5 Controller

添加controller类,类上的@RequestMapping注解是该类所有方法前面要添加的前缀,@RequestBody Area area可以标识方法接受的数据类型为xml或jason

@RestController
@RequestMapping("/superadmin")
public class AreaController {
    @Autowired
    private AreaService areaService;

    @RequestMapping(value = "/listarea", method = RequestMethod.GET)
    private Map listArea() {
        Map modelMap = new HashMap();
        List list = new ArrayList();
        // 获取区域列表
        list = areaService.getAreaList();
        modelMap.put("areaList", list);
        return modelMap;
    }

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

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

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

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

}

运行测试相关url


SpringBoot + 微信小程序1_第4张图片

2.6 统一异常处理

创建异常处理类,@ExceptionHandler(value = Exception.class)指定异常类型,@ResponseBody表示返回在页面的body

@ControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(value = Exception.class)
    @ResponseBody
    public Map exceptionHandler(HttpServletRequest req, Exception e) throws Exception {
        Map modelMap = new HashMap();
        modelMap.put("success", false);
        modelMap.put("errMsg", e.getMessage());
        return modelMap;
    }

}

将service中getAreaById方法添加int a = 1/0;测试异常

SpringBoot + 微信小程序1_第5张图片

你可能感兴趣的:(SpringBoot + 微信小程序1)