本文共 14272 字,大约阅读时间需要 47 分钟。
首先使用SpringBoot Initializer
来快速创建一个Web
项目。创建完后在我们的Pom
文件,关键依赖是:
org.springframework.boot spring-boot-starter-parent 1.5.9.RELEASE mysql mysql-connector-java runtime org.springframework.boot spring-boot-starter-jdbc org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-maven-plugin
这里给出本教程最开始的初始项目:
链接:https://pan.baidu.com/s/1rYb4WQEA4ZgJOaO1XWt_Gw
提取码:6bml
下载好了项目后我们需要在application.yml
文件里面加入下面内容(根据自己的实际环境来配置):
spring: datasource: username: root password: 123456 url: jdbc:mysql://localhost:3306/db_course driver-class-name: com.mysql.jdbc.Driver
接下来我们运行测试文件DatademoApplicationTests
如下,说明测试成功:
sql
文件内容如下: /*Navicat MySQL Data TransferSource Server : 本地Source Server Version : 50528Source Host : 127.0.0.1:3306Source Database : restful_crudTarget Server Type : MYSQLTarget Server Version : 50528File Encoding : 65001Date: 2018-03-05 10:41:40*/SET FOREIGN_KEY_CHECKS=0;-- ------------------------------ Table structure for department-- ----------------------------DROP TABLE IF EXISTS `department`;CREATE TABLE `department` ( `id` int(11) NOT NULL AUTO_INCREMENT, `departmentName` varchar(255) DEFAULT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
再次执行我们发现:
表已经帮我们建好了。这里我需要稍微来讲一下原理(不感兴趣可以跳过
):
dataSource
的默认注入的是: org.apache.tomcat.jdbc.pool.DataSource
作为数据源;而有关数据源的相关配置都在DataSourceProperties
这个类里面;那么如何根据这个配置来创建数据源的呢,我们来看一下自动配置的原理: 在下面这个类里面: org\springframework\boot\autoconfigure\jdbc\DataSourceConfiguration.class
上面这里就是说明了如果在配置类DataSourceProperties
里如果没有指定要创建的类型就使用org.apache.tomcat.jdbc.pool.DataSource
,当然也还支持HikariDataSource、BasicDataSource
,如下: 也就是说SpringBoot
是默认支持org.apache.tomcat.jdbc.pool.DataSource、HikariDataSource、BasicDataSource
三种数据源的。但是如果我们指定的数据源不是上面的三种,这里还有一个方法如下: 他用来获得我们自己指定的数据源。 有下面这个方法:
这里DataSourceInitializer
的实际类型为ApplicationListener
,它里面的方法有 1)runSchemaScripts();运行建表语句;
2)runDataScripts();运行插入数据的sql语句;
默认情况是把sql文件命名为schema.sql或者schema-all.sql就可执行
当然我们也可自己指定我们的文件去执行:
spring: datasource: username: root password: 123456 url: jdbc:mysql://localhost:3306/db_course driver-class-name: com.mysql.jdbc.Driver schema: - classpath:department.sql - classpath:employee.sql
我们首先把我们之前的department.sql
删除,不然每次启动都会执行一次。接下来自己在department
表里面加数据。
HelloController
: package com.jack.controller;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.jdbc.core.JdbcTemplate;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.ResponseBody;import java.util.List;import java.util.Map;@Controllerpublic class HelloController { @Autowired JdbcTemplate jdbcTemplate; @ResponseBody @GetMapping("/query") public Mapquery(){ List
添加依赖:
com.alibaba druid 1.1.8
application.yml
文件内容为:
spring: datasource: #数据源基本配置 username: root password: 123456 driver-class-name: com.mysql.jdbc.Driver url: jdbc:mysql://localhost:3306/db_course type: com.alibaba.druid.pool.DruidDataSource initialSize: 5 minIdle: 5 maxActive: 20 maxWait: 60000 timeBetweenEvictionRunsMillis: 60000 minEvictableIdleTimeMillis: 300000 validationQuery: SELECT 1 FROM DUAL testWhileIdle: true testOnBorrow: false testOnReturn: false poolPreparedStatements: true #配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙 filters: stat,wall,log4j maxPoolPreparedStatementPerConnectionSize: 20 useGlobalDataSourceStat: true connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500
这样配置之后我们可以使用Druid
连接池,但是这样存在问题就是上面initialSize
往下的配置都没有被加载进来。需要做下面的事情:
package com.jack.datademo.config;import com.alibaba.druid.pool.DruidDataSource;import org.springframework.boot.context.properties.ConfigurationProperties;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import javax.sql.DataSource;@Configurationpublic class DruidConfig{ @ConfigurationProperties(prefix = "spring.datasource") @Bean public DataSource druid(){ return new DruidDataSource(); }}
不过我们还要使用Druid
的另外的强大的功能就是它的监控的功能。
DruidConfig
添加下面代码: //配置Druid监控分为两步://①配置管理后台的Servlet//②配置一个监控的filter@Beanpublic ServletRegistrationBean statViewServlet(){ //StatViewServlet类可以帮助我们访问到后台页面,"/druid/*"表示访问路径 ServletRegistrationBean bean = new ServletRegistrationBean(new StatViewServlet(), "/druid/*"); Mapmap = new HashMap<>(20); //指定登录的用户是admin map.put("loginUsername","admin"); map.put("loginPassword","123456"); map.put("allow","");//这里默认允许任何所有访问,如果写localhost就表示只有主机可以访问 map.put("deny","192.168.43.228");//表示拒绝访问,我的主机IPV4地址为192.168.43.228 bean.setInitParameters(map); return bean;}public FilterRegistrationBean webStatFilter(){ FilterRegistrationBean bean = new FilterRegistrationBean(); bean.setFilter(new WebStatFilter()); Map map = new HashMap<>(20); //表示不拦截的请求 map.put("exclutions","*.js,*.css,/druid/*"); bean.setInitParameters(map); //表示拦截哪些请求 bean.setUrlPatterns(Arrays.asList("/*")); return bean;}
上面参数请见下面两张图:
下面演示: 当我们来访问一次我们前面第一大节访问的http://localhost:8080/query
时,我们可以再来查看Druid的后台如下: 更详细Druid介绍请参见: 这里给一个全面的中文文档:
添加依赖:
org.mybatis.spring.boot mybatis-spring-boot-starter 1.3.1
这里我们准备了两个bean
对象:
package com.jack.datademo.bean;public class Department { private Integer id; private String departmentName; public void setId(Integer id) { this.id = id; } public void setDepartmentName(String departmentName) { this.departmentName = departmentName; } public Integer getId() { return id; } public String getDepartmentName() { return departmentName; }}
package com.jack.datademo.bean;public class Employee { private Integer id; private String lastName; private Integer gender; private String email; private Integer dId; public void setId(Integer id) { this.id = id; } public void setLastName(String lastName) { this.lastName = lastName; } public void setGender(Integer gender) { this.gender = gender; } public void setEmail(String email) { this.email = email; } public void setdId(Integer dId) { this.dId = dId; } public Integer getId() { return id; } public String getLastName() { return lastName; } public Integer getGender() { return gender; } public String getEmail() { return email; } public Integer getdId() { return dId; }}
然后是两个sql
文件用于建表
SET FOREIGN_KEY_CHECKS=0;-- ------------------------------ Table structure for employee-- ----------------------------DROP TABLE IF EXISTS `employee`;CREATE TABLE `employee` ( `id` int(11) NOT NULL AUTO_INCREMENT, `lastName` varchar(255) DEFAULT NULL, `email` varchar(255) DEFAULT NULL, `gender` int(2) DEFAULT NULL, `d_id` int(11) DEFAULT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
SET FOREIGN_KEY_CHECKS=0;-- ------------------------------ Table structure for department-- ----------------------------DROP TABLE IF EXISTS `department`;CREATE TABLE `department` ( `id` int(11) NOT NULL AUTO_INCREMENT, `departmentName` varchar(255) DEFAULT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
application.yml
文件内容为:
spring: datasource: #数据源基本配置 username: root password: 123456 driver-class-name: com.mysql.jdbc.Driver url: jdbc:mysql://localhost:3306/db_course type: com.alibaba.druid.pool.DruidDataSource initialSize: 5 minIdle: 5 maxActive: 20 maxWait: 60000 timeBetweenEvictionRunsMillis: 60000 minEvictableIdleTimeMillis: 300000 validationQuery: SELECT 1 FROM DUAL testWhileIdle: true testOnBorrow: false testOnReturn: false poolPreparedStatements: true #配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙 filters: stat,wall,log4j maxPoolPreparedStatementPerConnectionSize: 20 useGlobalDataSourceStat: true connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500 schema: - classpath:sql/employee.sql - classpath:sql/department.sql
现在我们启动项目后检查建表情况:
莫急,肯定不会就是这种功能嘛,我们接着学。(现在需要把sql文件删除,防止下次再次执行
) 我们创建Mapper
和Controller
来演示
package com.jack.datademo.mapper;import com.jack.datademo.bean.Department;import org.apache.ibatis.annotations.*;//指定操作数据库的mapper@Mapperpublic interface DepartmentMapper { @Select("select * from department where id=#{id}") public Department queryById(Integer id); @Insert("insert into department (departmentName) values(#{departmentName})") public int insertDepartment(Department department); @Delete("delete from department where id=#{id}") public int deleteDepartment(Integer id); @Update("update department set deartmentName=#{departmentName} where id=#{id}") public int updateDepartment(Department department);}
package com.jack.datademo.controller;import com.jack.datademo.bean.Department;import com.jack.datademo.mapper.DepartmentMapper;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.PathVariable;import org.springframework.web.bind.annotation.RestController;//让返回的数据不是页面而是文本数据@RestControllerpublic class DeptController { @Autowired DepartmentMapper departmentMapper; @GetMapping("/dept/{id}") public Department getDepartment(@PathVariable("id") Integer id){ return departmentMapper.queryById(id); } @GetMapping("/dept") public Department insertDepartment(Department department){ departmentMapper.insertDepartment(department); return department; }}
现在我们的department
表的内容只有一条记录:
1 管理部
下面我们来演示:
成功插入 但是在浏览器上回显的是id=null
,那么我们可以这么做: 下面演示查询: 不过我们要解决一个问题就是数据库表的属性名与我们的javaBean对象的属性名不一致时如何解决(这里介绍的是开启驼峰命名法
)? 那么我们的DepartmentMapper
类就应该修改为: package com.jack.datademo.mapper;import com.jack.datademo.bean.Department;import org.apache.ibatis.annotations.*;//指定操作数据库的mapper@Mapperpublic interface DepartmentMapper { @Select("select * from department where id=#{id}") public Department queryById(Integer id); @Options(useGeneratedKeys = true,keyProperty = "id") @Insert("insert into department (department_name) values(#{departmentName})") public int insertDepartment(Department department); @Delete("delete from department where id=#{id}") public int deleteDepartment(Integer id); @Update("update department set deartment_name=#{departmentName} where id=#{id}") public int updateDepartment(Department department);}
这里就出现了departmentName
和deartment_name
不一致的问题。
package com.jack.datademo.config;import org.mybatis.spring.boot.autoconfigure.ConfigurationCustomizer;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;@Configurationpublic class MyBatisConfig { @Bean public ConfigurationCustomizer configurationCustomizer(){ return new ConfigurationCustomizer() { @Override public void customize(org.apache.ibatis.session.Configuration configuration) { configuration.setMapUnderscoreToCamelCase(true); } }; }}
接下来重启一下SpringBoot
应用。
Mapper
那么我们就会把每一个Mapper
都加上@Mapper
注解,这样就会很麻烦了,于是我们可以这么做: 这样我们可以把之前的@mapper
全部去掉,运行得到: 这里我们以Employee
为例子来演示。
mybatis-config.xml:
EmloyeeMapper.xml:
insert into Employee values(#{id},#{lastName},#{email},#{gender},#{dId})
我们的Mapper
类为:
package com.jack.datademo.mapper;import com.jack.datademo.bean.Employee;//这里需要填@Mapper,也可以是在主应用程序上加上@MapperScan,这点是必须的public interface EmployeeMapper{ public Employee getEmployeeById(Integer id); public void insertEmployee(Employee employee);}
最后编写EmployeeController
来测试:
package com.jack.datademo.controller;import com.jack.datademo.bean.Employee;import com.jack.datademo.mapper.EmployeeMapper;import org.apache.ibatis.annotations.Options;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.PathVariable;import org.springframework.web.bind.annotation.RestController;@RestControllerpublic class EmployeeController{ @Autowired EmployeeMapper employeeMapper; @GetMapping("/emp/{id}") public Employee queryEmpById(@PathVariable("id") Integer id){ return employeeMapper.getEmployeeById(id); } @Options(useGeneratedKeys = true,keyProperty = "id") @GetMapping("/emp") public Employee insert(Employee employee){ employeeMapper.insertEmployee(employee); return employee; }}
最后需要在application.yml
文件里面配置:
mybatis: #指定全局配置文件的路径 config-location: classpath:mybatis/mybatis-config.xml #指定特定mapper的配置路径 mapper-locations: classpath:mybatis/mapper/*.xml
测试得到发现dId为空
这出现了我们在讲注解是出现的表与bean属性名不一致导致的问题,由于我们之前配置的MybatisConfig
并不对XML方式来起作用,我们可以这样解决: 再次测试: 不过这里要说明的是:如果没有我们的MybatisConfig
,这里的xml
配置也可以保证解决我们对dempartment
的访问也不会存在驼峰命名不匹配的问题。 转载地址:http://pllzi.baihongyu.com/