2.整合基本的JDBC和数据源
1. jdbc
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
如何配置才能和数据路进行交互呢?
spring:
datasource:
username: root
password: 123456
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://192.168.124.182:3306/jdbc
我们只需要在springboot的全局配置文件中,编写一下配置,就能和数据库进行交互
通过以上配置我们就能够在容器中获取数据源,获取数据库连接
效果:
默认是使用 com.zaxxer.hikari.HikariDataSource作为数据源的
数据源的相关配置都在DataSourceProperties这个类中.
数据源的自动配置原理:
所有这些神奇的效果都是由于springboot对数据源的自动配置,和自动配置相关的类都在org.springframework.boot.autoconfigure.jdbc下.
1 . 参考DataSourceConfiguration,使用spring.datasource.type指定自定义的数据源的类型
它的作用就是根据你的配置,创建并且给容器中添加数据源,默认添加的是 com.zaxxer.hikari.HikariDataSource,它支持的数据源有以下
"org.apache.tomcat.jdbc.pool.DataSource""
"com.zaxxer.hikari.HikariDataSource"
"org.apache.commons.dbcp2.BasicDataSource"
自定义数据源
@Configuration
@ConditionalOnMissingBean(DataSource.class)
@ConditionalOnProperty(name = "spring.datasource.type")
static class Generic {
@Bean
public DataSource dataSource(DataSourceProperties properties) {
//它是通过DatasourceBuiluder创建数据源,利用反射来创建type类型的数据源,然后绑定相关的属性
return properties.initializeDataSourceBuilder().build();
}
}
public DataSourceBuilder<?> initializeDataSourceBuilder() {
return DataSourceBuilder.create(getClassLoader()).type(getType())
.driverClassName(determineDriverClassName()).url(determineUrl())
.username(determineUsername()).password(determinePassword());
}
public static DataSourceBuilder<?> create(ClassLoader classLoader) {
return new DataSourceBuilder<>(classLoader);
}
@SuppressWarnings("unchecked")
public T build() {
Class<? extends DataSource> type = getType();
DataSource result = BeanUtils.instantiateClass(type);
maybeGetDriverClassName();
bind(result);
return (T) result;
}
4、DataSourceInitializer:它是一个ApplicationListener;
作用:
1)、runSchemaScripts();运行建表语句;
2)、runDataScripts();运行插入数据的sql语句;
默认规则:
把文件命名为:
schema-*.xml , data-*.xml
默认的加载文件是,classpath:schema.sql
classpath:schema-all.sql
可以使用
schema:
- classpath:department.sql
指定SQL文件的名称和位置
这就要求我们如果想让容器在创建数据源之后,执行建表或其他的SQL,我们需要把SQL文件放在classpath然后命名为 schema或者schema-all.sql
注意:类路径下的这些SQL文件,每次在启动容器的时候都会重新加载
5、操作数据库:自动配置了JdbcTemplate操作数据库
@Controller
public class HelloController {
@Autowired
JdbcTemplate jdbcTemplate;
@GetMapping("/query")
@ResponseBody
public Map<String,Object> map(){
List<Map<String, Object>> list =
jdbcTemplate.queryForList("select * from department");
return list.get(0);
}
}
结果:
2:整合Druid数据源
1,首先导入druid依赖(最好是把log4j的依赖也一起导进去)
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.12</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
2,在application.yml文件中配置druid
spring:
datasource:
username: root
password: 123456
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://192.168.43.186:3306/jdbc1
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,但是关于druid的其他设置都不会生效,因为我们所有对spring.datasource的配置都是基于DataSourceProperties这个类,springboot会把application.yml中对spring.datasource 的值和类中相应的属性进行绑定,而这个类中是没有惯有druid的属性,所以这样配置是不会生效的.效果如下图
如何让配置文件中的druid设置生效?
1,我们需要写一个druid的配置类,来保存配置文件中对druid的配置
@Configuration
public class DruidConfig {
@Bean
@ConfigurationProperties(prefix = "spring.datasource")
public DataSource druid(){
//springboot底层是通过反射创建数据源并且保存属性,
//我们直接创建一个druid然后放入到容器中就行
return new DruidDataSource();
}
}
效果如图:
如何配置druid的监控呢?
1,我们需要设置一个处理登录后台请求的servlet
//配置druid的监控
//1,配置一个管理后台的servlet,由于没有web.xml,所以我们使用ServletRegistrationBean创建servlet
//该servlet的默认名称是StatViewServlet
@Bean
public ServletRegistrationBean statViewServlet(){
//创建一个StatViewservlet,然后负责处理Druid下的所有请求
ServletRegistrationBean bean = new ServletRegistrationBean(new StatViewServlet(), "/druid/*");
//创建一个map用来保存servlet的初始化参数
Map<String,String> initParams = new HashMap<String,String>();
initParams.put("loginUsername","admin");
initParams.put("loginPassword","123456");
//设置允许谁登录,不写的话默认值就是允许所有
initParams.put("allow","");
//配置要拒绝的用户
initParams.put("deny","192.168.124.182");
//以map传参的方式设置servlet的初始化参数,
bean.setInitParameters(initParams);
return bean;
}
我们如果还想设置其他的servlet初始化参数,我们可以参考StatViewServlet和它的父类.
public class StatViewServlet extends ResourceServlet {
private final static Log LOG = LogFactory.getLog(StatViewServlet.class);
private static final long serialVersionUID = 1L;
public static final String PARAM_NAME_RESET_ENABLE = "resetEnable";
public static final String PARAM_NAME_JMX_URL = "jmxUrl";
public static final String PARAM_NAME_JMX_USERNAME = "jmxUsername";
public static final String PARAM_NAME_JMX_PASSWORD = "jmxPassword";
public abstract class ResourceServlet extends HttpServlet {
private final static Log LOG = LogFactory.getLog(ResourceServlet.class);
public static final String SESSION_USER_KEY = "druid-user";
public static final String PARAM_NAME_USERNAME = "loginUsername";
public static final String PARAM_NAME_PASSWORD = "loginPassword";
public static final String PARAM_NAME_ALLOW = "allow";
public static final String PARAM_NAME_DENY = "deny";
public static final String PARAM_REMOTE_ADDR = "remoteAddress";
2,我们需要设置一个监控所有请求的filter
//2,配置一个web监控的filter
//创建filter要用FilterRegistrationBean,druid的默认的Filter的名称是WebStatFilter
@Bean
public FilterRegistrationBean webStatFilter(){
FilterRegistrationBean bean = new FilterRegistrationBean();
//创建WebStatFilter
bean.setFilter(new WebStatFilter());
Map<String ,String> initParams = new HashMap<>();
//设置需要排除的请求
initParams.put("exclusions","*.js,*.css,/druid/*");
bean.setInitParameters(initParams);
//设置要监控的请求路径
bean.setUrlPatterns(Arrays.asList("/*"));
return bean;
}
如果还想要配置filter的其他参数,参考它的实现类
public class WebStatFilter extends AbstractWebStatImpl implements Filter {
private final static Log LOG = LogFactory.getLog(WebStatFilter.class);
public final static String PARAM_NAME_PROFILE_ENABLE = "profileEnable";
public final static String PARAM_NAME_SESSION_STAT_ENABLE = "sessionStatEnable";
public final static String PARAM_NAME_SESSION_STAT_MAX_COUNT = "sessionStatMaxCount";
public static final String PARAM_NAME_EXCLUSIONS = "exclusions";
public static final String PARAM_NAME_PRINCIPAL_SESSION_NAME = "principalSessionName";
public static final String PARAM_NAME_PRINCIPAL_COOKIE_NAME = "principalCookieName";
public static final String PARAM_NAME_REAL_IP_HEADER = "realIpHeader";
监控效果如图:
发出/query请求:
后台监控结果:
3. 整合mybatis(1)
1,引入mybatis的依赖:(这个依赖是mybatis整合spring的,所以不是spring官方的)
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.0.1</version>
</dependency>
2,创建数据库表
3,创建相应的Javabean
4,基于注解实现的mybatis整合
其实我们只需要写一个被@mapper注解标注的mapper接口,在接口中写入具体的方法来操作数据库即可,根本不用做其他的配置,都是自动配置的.所有的自动配置都是在 MybatisAutoConfiguration 和 mybatisPropeties 这两个类中
@Mapper
public interface DepartmentMapper {
@Select("select * from department where id=#{id}")
public Department getDeptById(Integer id);
@Delete("delete from department wherer id =#{id}")
public int deleteDeptById(Integer id);
@Options(useGeneratedKeys = true,keyProperty = "id")
@Insert("insert into department(departmentName) values(#{departmentName})")
public int insertDept(Department dept);
@Update("update department set departmentName=#{departmentName} where id=#{id}")
public int updateDept(Department dept);
}
//该注解就是用来获取自增id的
@Options(useGeneratedKeys = true,keyProperty = "id")
注意
如果我们想自定义mybatis的配置规则,例如开启驼峰命名法,等功能,我们可以自定义一个mybatis的配置类,来配置规则:
如何之自定义mybatis的配置规则:解决方案如下:
@Configuration
public class MybatisConfig {
@Bean
public ConfigurationCustomizer customizer() {
return new ConfigurationCustomizer() {
@Override
public void customize(org.apache.ibatis.session.Configuration configuration) {
//开启驼峰命名法
configuration.setMapUnderscoreToCamelCase(true);
}
};
}
}
在MybatisAutoConfiguration类中,它是遍历容器中所有的ConfigurationCustomizer,在遍历的过程中执行每一个ConfigurationCustomizer的customize()方法,我们只需要在customize()方法中配置我们想要的规则,然后使用@Bean来把方法的返回值放入到容器中就行了.
@MapperScan(value = “com.atguigu.springboot.mapper”):可以批量扫描mapper接口,适用于mapper接口过多,写@mapper太麻烦了,该注解可以扫描到目标包下的所有mapper接口.
5,基于配置文件整合mybatis
核心步骤:
1,创建mapper接口
public interface EmployeeMapper {
public Employee getEmpById(Integer id);
public void insertEmp(Employee emp);
}
2,创建mybatis的配置文件,指定mybatis的全局配置文件和映射文件的位置
mybatis:
#指定全部配置文件
config-location: classpath:mybatis/mybatis-config.xml
# 指定映射文件
mapper-locations: classpath:mybatis/mapper/*.xml
全局配置文件的内容:
<?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>
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
</configuration>
映射文件的内容:
<?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.atguigu.springboot.mapper.EmployeeMapper">
<select id="getEmpById" resultType="com.atguigu.springboot.bean.Employee">
select * from employee where id =#{id}
</select>
<insert id="insertEmp">
insert into employee(lastName,email,gender,d_id) values(#{lastName},#{email},#{gender},#{dId})
</insert>
</mapper>
2,整合SpringData Jpa
1.编写一个实体类和数据表进行映射,并且配置好映射关系
//使用JPA注解配置映射关系
@Data
@Entity //告诉jpa这是一个实体类(是和数据库表映射的类)
@Table(name = "tbl_user") //指明该实体类和具体的那张表进行映射,name的值就是表名称
//如果name省略,默认表名就是类名的小写,user
public class User {
@Id //标识这是一个主键
@GeneratedValue(strategy = GenerationType.IDENTITY) //标识主键自动递增
private Integer id;
@Column(name = "last_name",length = 50)
//标识这是和数据表对应的一个列,也可以用name来制定列名称,length制定字段的长度
private String lastName;
@Column //省略的话,列名就是属性名
private String email;
}
2.编写一个Dao接口来操作实体类对应的数据表(Repository)
//继承JpaRepository 来完成对数据表的操作
public interface UserRepository extends JpaRepository<User,Integer> {
}
3.关于jpa的基本的配置,如果还想要其他的配置可以参考 JpaProperties这个类
jpa:
hibernate:
# 定义数据表的生成策略,update表示更新或者创建数据表
ddl-auto: update
# 在控制台显示SQL语句
show-sql: true