springboot006SpringBoot与数据访问
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: zhangjiahui
url: jdbc:mysql://192.168.199.172:3306/jdbc
driver-class-name: com.mysql.cj.jdbc.Driver
效果:
默认是用com.zaxxer.hikari.HikariDataSource作为数据源
数据源相关配置都在DataSourceProperties里面
自动配置原理:
org.springframework.boot.autoconfigure.jdbc
参考DataSourceConfiguration, 根据配置创建数据源,默认使用HikariDataSource;可以使用spring.datasource.type指定自定义的数据源类型
SpringBoot默认可以支持以下几种数据源
org.apache.commons.dbcp2.BasicDataSource
com.zaxxer.hikari.HikariDataSource
org.apache.tomcat.jdbc.pool.DataSource
自定义数据源
@ConditionalOnMissingBean({DataSource.class})
@ConditionalOnProperty(
name = {"spring.datasource.type"}
)
static class Generic {
Generic() {
}
@Bean
public DataSource dataSource(DataSourceProperties properties) {
//使用DataSourceBuilder创建数据源,利用反射创建响应type数据源,并且绑定相关属性
return properties.initializeDataSourceBuilder().build();
}
}
DataSourceInitializerInvoker
DataSourceAutoConfiguration
@Configuration@ConditionalOnClass({ DataSource.class, EmbeddedDatabaseType.class })
@EnableConfigurationProperties(DataSourceProperties.class)
@Import({ DataSourcePoolMetadataProvidersConfiguration.class,
DataSourceInitializationConfiguration.class })
public class DataSourceAutoConfiguration {
DataSourceInitializationConfiguration
@Configuration@Import({ DataSourceInitializerInvoker.class,
DataSourceInitializationConfiguration.Registrar.class })
class DataSourceInitializationConfiguration {
DataSourceInitializerInvoker
/** * Bean to handle {@link DataSource} initialization by running {@literal schema-*.sql} on
* {@link InitializingBean#afterPropertiesSet()} and {@literal data-*.sql} SQL scripts on
* a {@link DataSourceSchemaCreatedEvent}.
*
* @author Stephane Nicoll
* @see DataSourceAutoConfiguration
*/
class DataSourceInitializerInvoker
implements ApplicationListener<DataSourceSchemaCreatedEvent>, InitializingBean {
@Override
public void onApplicationEvent(DataSourceSchemaCreatedEvent event) {
// NOTE the event can happen more than once and
// the event datasource is not used here
DataSourceInitializer initializer = getDataSourceInitializer();
if (!this.initialized && initializer != null) {
initializer.initSchema();
this.initialized = true;
}
}
DataSourceInitializerInvoker将为我们自动创建表并初始化数据,只需要我们将脚本以特定的命名方法,放置在指定的目录即可:
默认放在classpath路径下,命名规则如下:
- 建表脚本:schema-*.sql
- 初始化数据脚本:data-*.sql
自定义路径:
spring: datasource:
schema:
- classpath:db/department.sql
- classpath:db/init_department.sql
SpringBoot2.X重要设置项:spring.datasource.initialization-mode 初始化模式(springboot2.0),其中有三个值,always为始终执行初始化,embedded只初始化内存数据库(默认值),如h2等,never为不执行初始化。
注:mysql数据库对大小写敏感
- JdbcTemplate自动注入
@Configuration@ConditionalOnClass({ DataSource.class, JdbcTemplate.class })
@ConditionalOnSingleCandidate(DataSource.class)
@AutoConfigureAfter(DataSourceAutoConfiguration.class)
@EnableConfigurationProperties(JdbcProperties.class)
public class JdbcTemplateAutoConfiguration {
2. 整合基本Druid数据源
Druid数据源配置:
引入数据源
<!-- https://mvnrepository.com/artifact/com.alibaba/druid -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.12</version>
</dependency>
数据源属性绑定
@Configuration
public class DruidConfig {
@ConfigurationProperties(prefix = "spring.datasource")
@Bean
public DataSource druid() {
return new DruidDataSource();
}
}
属性配置
spring:
datasource:
initialSize: 5
minIdle: 5
maxActive: 20
maxWait: 60000
timeBetweenEvictionRunMillis: 60000
minEvictableIdleTimeMillis: 300000
validationQuery: SELECT 1 FROM DUAL
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
poolPreparedStatements: true
#配置监控统计拦截的filters,去掉后监控界面sql无法统计,‘wall’用于防火墙
filters: stat,wall,log4j2
maxPoolPreparedStatementPerConnectionSize: 20
useGlobalDataSourceStat: true
connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500
配置Servlet和Filter
@Configurationpublic class DruidConfig {
@Bean
public ServletRegistrationBean statViewServlet() {
ServletRegistrationBean bean = new ServletRegistrationBean(new StatViewServlet(), "/druid/*");
Map<String, String> initParams = new HashMap<>();
initParams.put("loginUsername", "admin");
initParams.put("loginPassword", "admin");
initParams.put("allow", "");
initParams.put("deny", "");
bean.setInitParameters(initParams);
return bean;
}
@Bean
public FilterRegistrationBean webStatFilter() {
FilterRegistrationBean bean = new FilterRegistrationBean();
Map<String, String> initParams = new HashMap<>();
initParams.put("exclusions", "*.js,*.png,*.io,/druid/*");
bean.setFilter(new WebStatFilter());
bean.setUrlPatterns(Arrays.asList("/*"));
bean.setInitParameters(initParams);
return bean;
}
}
3. 整合Mybatis
<dependency> <groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.2</version>
</dependency>
依赖关系:
步骤:
1. 引入依赖、配置属性(见上一节)
2. 建数据库表
3. 创建JavaBean:Department/Employee
4. 实现增删改查
1. 注解版
- Mapper
//指定这是一个操作数据库的mapper@Mapper
public interface DepartmentMapper {
@Select("SELECT * FROM department WHERE id=#{id}")
public Department getDeptById(Integer id);
@Delete("DELETE FROM department WHERE 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);
}
- Controller
@RestControllerpublic class DeptController {
@Autowired
DepartmentMapper departmentMapper;
@GetMapping("/dept/{id}")
public Department getDept(@PathVariable("id") Integer id) {
return departmentMapper.getDeptById(id);
}
@GetMapping("/dept")
public Department insertDept(Department department) {
departmentMapper.insertDept(department);
return department;
}
}
- 自定义Mybatis配置方法
@org.springframework.context.annotation.Configurationpublic class MybatisConfig {
@Bean
public ConfigurationCustomizer configurationCustomizer() {
return new ConfigurationCustomizer() {
@Override
public void customize(Configuration configuration) {
configuration.setMapUnderscoreToCamelCase(true);
}
};
}
}
2. 配置文件版
- Mapper
//@Mapper或者@MapperScan将接口扫描装配到容器中public interface EmployeeMapper {
public Employee getEmpById(Integer id);
public void insertEmp(Employee employee);
}
- Controller
@Controllerpublic class EmpController {
@Autowired
EmployeeMapper employeeMapper;
@ResponseBody
@GetMapping("/emp/{id}")
public Employee getEmp(@PathVariable(value = "id") Integer id) {
Employee employee = employeeMapper.getEmpById(id);
return employee;
}
}
- mybatis主配置文件mybatis-config.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>
- mapper配置文件EmployeeMapper.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.qiang.springboot.mapper.EmployeeMapper">
<!--
public Employee getEmpById(Integer id);
public void insertEmp(Employee employee);-->
<select id="getEmpById" resultType="com.qiang.springboot.bean.Employee">
SELECT * FROM employee WHERE id=#{id}
</select>
<insert id="insertEmp">
INSERT INTO employee(last_name, email, gender, department_id, birth) VALUES(#{lastName}, #{email}, #{gender}, #{departmentId}, CURRENT_DATE);
</insert>
</mapper>
- 主配置文件及mapper文件路径指定
#mybatis相关配置,都以mybatis开头mybatis:
#指定主配置文件路径
config-location: classpath:mybatis/mybatis-config.xml
#指定mapper配置文件路径(数组,可使用通配符进行匹配)
mapper-locations: classpath:mybatis/mapper/*.xml
5. 指定Mapper的两种方法
使用@Mapper注解
//直接将@Mapper注解加在接口类上,指定这是一个操作数据库的mapper
@Mapper
public interface DepartmentMapper {
@Select("SELECT * FROM department WHERE id=#{id}")
public Department getDeptById(Integer id);
@Delete("DELETE FROM department WHERE 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);
}
使用@MapperScan(value="mapper-package")注解
//在SpringBoot主程序上添加注解@MapperScan(value="mapper-package")
//则mapper-package包下所有类都会被标识为mapper
@MapperScan(value = "com.qiang.springboot.mapper")
@SpringBootApplication
public class SpringBoot06DataMybatisApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBoot06DataMybatisApplication.class, args);
}
}
4. 整合JPA
1. Spring Data简介
2. 整合Spring Data JPA
JPA是基于ORM(Object Relational Mapping)思想的
- 编写一个实体类(bean)和数据表进行映射,并且配置好关系
@Entity //告诉JPA这是一个实体类(和数据表映射的类)@Table(name = "tbl_user") //指定和哪个数据表相对应,如果省略此注解,则默认使用小写类名作为映射表名
public class User {
/**
* @Id : 告诉JPA这是一个主键字段
* @GeneratedValue : 设置自增
*/
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY) //设置自增
private Integer id;
/**
* @Column : 和数据表中某列对应的属性,默认属性名就是列名
*/
@Column
private String lastName;
/**
* @Column : 可使用name指定列名,使用length指定列长度
*/
@Column(name = "user_email", length = 50)
private String email;
//getter & setter
//...
}
- 编写一个dao接口来操作实体类对应的数据表(Repository)
//Repository必须是一个接口//继承JpaRepository来完成对数据库的操作
public interface UserRepository extends JpaRepository<User, Integer> {
}
- 基本的配置JpaProperties
spring: datasource:
url: jdbc:mysql://192.168.199.172:3306/jpa
username: root
password: zhangjiahui
driver-class-name: com.mysql.cj.jdbc.Driver
jpa:
hibernate:
#更新或者创建数据表结构
ddl-auto: update
#在控制台显示SQL
show-sql: true
JPA 2.x版本后 findOne() 的变化
以上是 springboot006SpringBoot与数据访问 的全部内容, 来源链接: utcz.com/z/510424.html