当前位置: 首页 > news >正文

Chapter7: SpringBoot与数据访问

尚硅谷SpringBoot顶尖教程

1. JDBC

1.1 依赖及配置

<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><version>8.0.12</version>
</dependency>

全局配置文件配置数据源基础参数

## 数据源
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.url=jdbc:mysql://localhost:3306/jdbc?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
spring.datasource.driver-class-name=com.mysql.jdbc.Driver

数据源的配置属性封装在DataSourceProperties里面,支持在全局配置文件配置spring.datasource.xxx的属性。

@ConfigurationProperties(prefix = "spring.datasource")
public class DataSourcePropertiesimplements BeanClassLoaderAware, EnvironmentAware, InitializingBean {private Class<? extends DataSource> type;private String driverClassName;private String url;private String username;private String password;// ...// 构建数据源public DataSourceBuilder initializeDataSourceBuilder() {return DataSourceBuilder.create(getClassLoader()).type(getType()).driverClassName(determineDriverClassName()).url(determineUrl()).username(determineUsername()).password(determinePassword());}// ...
}

1.2 数据源自动配置原理

数据源的自动配置查看自动配置类DataSourceAutoConfiguration, 导入了DataSourceConfiguration数据源配置类, 数据源实例化的相关配置都在这个类中;

@Configuration
@ConditionalOnClass({ DataSource.class, EmbeddedDatabaseType.class })
@EnableConfigurationProperties(DataSourceProperties.class)
@Import({ Registrar.class, DataSourcePoolMetadataProvidersConfiguration.class })
public class DataSourceAutoConfiguration {// ...@Configuration@Conditional(PooledDataSourceCondition.class)@ConditionalOnMissingBean({ DataSource.class, XADataSource.class })@Import({ DataSourceConfiguration.Tomcat.class, DataSourceConfiguration.Hikari.class,DataSourceConfiguration.Dbcp.class, DataSourceConfiguration.Dbcp2.class,DataSourceConfiguration.Generic.class })@SuppressWarnings("deprecation")protected static class PooledDataSourceConfiguration {}// ...
}

上面的自动配置类中导入了配置类DataSourceConfiguration, web模块自动导入了spring-boot-starter-tomcat, 默认使用org.apache.tomcat.jdbc.pool.DataSource作为数据源, 可以使用spring.datasource.type指定数据源类型。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-e7uqYZUV-1686468913853)(SpringBoot学习笔记-atguigu.assets/1686146719144.png)]

abstract class DataSourceConfiguration {@SuppressWarnings("unchecked")protected <T> T createDataSource(DataSourceProperties properties,Class<? extends DataSource> type) {// 根据导入的数据源类型type,实例化数据源return (T) properties.initializeDataSourceBuilder().type(type).build();}/*** Tomcat Pool DataSource configuration.*/@ConditionalOnClass(org.apache.tomcat.jdbc.pool.DataSource.class)@ConditionalOnProperty(name = "spring.datasource.type", havingValue = "org.apache.tomcat.jdbc.pool.DataSource", matchIfMissing = true)static class Tomcat extends DataSourceConfiguration {@Bean@ConfigurationProperties(prefix = "spring.datasource.tomcat")public org.apache.tomcat.jdbc.pool.DataSource dataSource(DataSourceProperties properties) {// 创建数据库连接池org.apache.tomcat.jdbc.pool.DataSource dataSource = createDataSource(properties, org.apache.tomcat.jdbc.pool.DataSource.class);DatabaseDriver databaseDriver = DatabaseDriver.fromJdbcUrl(properties.determineUrl());String validationQuery = databaseDriver.getValidationQuery();if (validationQuery != null) {dataSource.setTestOnBorrow(true);dataSource.setValidationQuery(validationQuery);}return dataSource;}}/*** Hikari DataSource configuration.*/@ConditionalOnClass(HikariDataSource.class)@ConditionalOnProperty(name = "spring.datasource.type", havingValue = "com.zaxxer.hikari.HikariDataSource", matchIfMissing = true)static class Hikari extends DataSourceConfiguration {@Bean@ConfigurationProperties(prefix = "spring.datasource.hikari")public HikariDataSource dataSource(DataSourceProperties properties) {return createDataSource(properties, HikariDataSource.class);}}/*** DBCP DataSource configuration.** @deprecated as of 1.5 in favor of DBCP2*/@ConditionalOnClass(org.apache.commons.dbcp.BasicDataSource.class)@ConditionalOnProperty(name = "spring.datasource.type", havingValue = "org.apache.commons.dbcp.BasicDataSource", matchIfMissing = true)@Deprecatedstatic class Dbcp extends DataSourceConfiguration {@Bean@ConfigurationProperties(prefix = "spring.datasource.dbcp")public org.apache.commons.dbcp.BasicDataSource dataSource(DataSourceProperties properties) {org.apache.commons.dbcp.BasicDataSource dataSource = createDataSource(properties, org.apache.commons.dbcp.BasicDataSource.class);DatabaseDriver databaseDriver = DatabaseDriver.fromJdbcUrl(properties.determineUrl());String validationQuery = databaseDriver.getValidationQuery();if (validationQuery != null) {dataSource.setTestOnBorrow(true);dataSource.setValidationQuery(validationQuery);}return dataSource;}}/*** DBCP DataSource configuration.*/@ConditionalOnClass(org.apache.commons.dbcp2.BasicDataSource.class)@ConditionalOnProperty(name = "spring.datasource.type", havingValue = "org.apache.commons.dbcp2.BasicDataSource", matchIfMissing = true)static class Dbcp2 extends DataSourceConfiguration {@Bean@ConfigurationProperties(prefix = "spring.datasource.dbcp2")public org.apache.commons.dbcp2.BasicDataSource dataSource(DataSourceProperties properties) {return createDataSource(properties,org.apache.commons.dbcp2.BasicDataSource.class);}}/*** Generic DataSource configuration.*/@ConditionalOnMissingBean(DataSource.class)// 使用spring.datasource.type指定数据源类型@ConditionalOnProperty(name = "spring.datasource.type")static class Generic {@Beanpublic DataSource dataSource(DataSourceProperties properties) {return properties.initializeDataSourceBuilder().build();}}
}

DataSourceBuilder#build()方法实例化数据源, 默认支持的数据源类型有:org.apache.tomcat.jdbc.pool.DataSource
org.apache.commons.dbcp.BasicDataSource
org.apache.commons.dbcp2.BasicDataSource
com.zaxxer.hikari.HikariDataSource

public class DataSourceBuilder {private static final String[] DATA_SOURCE_TYPE_NAMES = new String[] {"org.apache.tomcat.jdbc.pool.DataSource","com.zaxxer.hikari.HikariDataSource","org.apache.commons.dbcp.BasicDataSource", // deprecated 过时了"org.apache.commons.dbcp2.BasicDataSource" };private Class<? extends DataSource> type;// ...public DataSource build() {// 返回的就是当前builder的数据源类型type//type出处: DataSourceProperties#initializeDataSourceBuilder().type(type)Class<? extends DataSource> type = getType();DataSource result = BeanUtils.instantiate(type);maybeGetDriverClassName();bind(result);return result;}public DataSourceBuilder type(Class<? extends DataSource> type) {this.type = type;return this;}// ...
}	

1.3 数据源数据初始化

数据源自动配置类中实例化DataSourceInitializer,数据源的一些初始化工作在这里面完成。

@Configuration
@ConditionalOnClass({ DataSource.class, EmbeddedDatabaseType.class })
@EnableConfigurationProperties(DataSourceProperties.class)
@Import({ Registrar.class, DataSourcePoolMetadataProvidersConfiguration.class })
public class DataSourceAutoConfiguration {// ...@Bean@ConditionalOnMissingBeanpublic DataSourceInitializer dataSourceInitializer(DataSourceProperties properties,ApplicationContext applicationContext) {return new DataSourceInitializer(properties, applicationContext);}// ...
}

DataSourceInitializer实现了ApplicationListener接口,重写onApplicationEvent方法, 里面会调用runDataScripts()方法执行指定sql文件中插入数据的sql语句。

class DataSourceInitializer implements ApplicationListener<DataSourceInitializedEvent> {DataSourceInitializer(DataSourceProperties properties,ApplicationContext applicationContext) {this.properties = properties;this.applicationContext = applicationContext;}// 重写ApplicationListener#onApplicationEvent方法@Overridepublic void onApplicationEvent(DataSourceInitializedEvent event) {if (!this.properties.isInitialize()) {logger.debug("Initialization disabled (not running data scripts)");return;}// NOTE the event can happen more than once and// the event datasource is not used hereif (!this.initialized) {// 执行数据库脚本runDataScripts();this.initialized = true;}}// 执行数据库脚本private void runDataScripts() {// 获取spring.datasource.data配置的sql脚本List<Resource> scripts = getScripts("spring.datasource.data",this.properties.getData(), "data");String username = this.properties.getDataUsername();String password = this.properties.getDataPassword();// 运行脚本runScripts(scripts, username, password);}// 运行脚本private void runScripts(List<Resource> resources, String username, String password) {if (resources.isEmpty()) {return;}ResourceDatabasePopulator populator = new ResourceDatabasePopulator();populator.setContinueOnError(this.properties.isContinueOnError());populator.setSeparator(this.properties.getSeparator());if (this.properties.getSqlScriptEncoding() != null) {populator.setSqlScriptEncoding(this.properties.getSqlScriptEncoding().name());}for (Resource resource : resources) {populator.addScript(resource);}DataSource dataSource = this.dataSource;if (StringUtils.hasText(username) && StringUtils.hasText(password)) {dataSource = DataSourceBuilder.create(this.properties.getClassLoader()).driverClassName(this.properties.determineDriverClassName()).url(this.properties.determineUrl()).username(username).password(password).build();}// 获取数据库连接,执行sql语句DatabasePopulatorUtils.execute(populator, dataSource);}
}

DataSourceInitializer中的init方法使用@PostConstruct注解声明,在实例化完成后会执行该方法进行初始化工作,里面通过runSchemaScripts() 运行sql脚本执行了创建表的操作。

class DataSourceInitializer implements ApplicationListener<DataSourceInitializedEvent> {DataSourceInitializer(DataSourceProperties properties,ApplicationContext applicationContext) {this.properties = properties;this.applicationContext = applicationContext;}// 初始化@PostConstructpublic void init() {if (!this.properties.isInitialize()) {logger.debug("Initialization disabled (not running DDL scripts)");return;}if (this.applicationContext.getBeanNamesForType(DataSource.class, false,false).length > 0) {this.dataSource = this.applicationContext.getBean(DataSource.class);}if (this.dataSource == null) {logger.debug("No DataSource found so not initializing");return;}// 运行schema脚本runSchemaScripts();}// 运行schema脚本private void runSchemaScripts() {// 获取spring.datasource.schema配置的schema脚本List<Resource> scripts = getScripts("spring.datasource.schema",this.properties.getSchema(), "schema");if (!scripts.isEmpty()) {String username = this.properties.getSchemaUsername();String password = this.properties.getSchemaPassword();runScripts(scripts, username, password);try {this.applicationContext.publishEvent(new DataSourceInitializedEvent(this.dataSource));// The listener might not be registered yet, so don't rely on it.if (!this.initialized) {runDataScripts();this.initialized = true;}}catch (IllegalStateException ex) {logger.warn("Could not send event to complete DataSource initialization ("+ ex.getMessage() + ")");}}}
}

上面运行的两个脚本都是从DataSourceInitializer#getScripts方法中查找得到的,支持执行类路径下指定的脚本文件,如果没有指定就执行默认的脚本。

spring.datasource.platform配置xxx,那么脚本文件默认命名为schema-xxx.sql 或 data-xxx.sql ;

spring.datasource.platform没有配置,脚本文件默认为schema.sql或schema-all.sql, 可以使用schema属性指定加载sql的位置

// resources=spring.datasource.data or spring.datasource.schema指定的sql脚本
// fallback=data or schame
private List<Resource> getScripts(String propertyName, List<String> resources,String fallback) {if (resources != null) {// 如果spring.datasource.data 或 spring.datasource.schema有配置指定的脚本,就执行此处查找脚本资源。return getResources(propertyName, resources, true);}// 如果spring.datasource.data 或 spring.datasource.schema没有配置,就查找类路径下默认的脚本// platform=allString platform = this.properties.getPlatform();List<String> fallbackResources = new ArrayList<String>();// 默认脚本 schema-all.sql or data-all.sql fallbackResources.add("classpath*:" + fallback + "-" + platform + ".sql");// 默认脚本 schema.sql or data.sqlfallbackResources.add("classpath*:" + fallback + ".sql");return getResources(propertyName, fallbackResources, false);
}

全局配置文件配置执行的脚本, 建表脚本teacher.sql和初始化数据脚本initTeacher.sql

# 初始化执行sql
#spring.datasource.platform=xxx
spring.datasource.schema=classpath*:ddlSql/teacher.sql
spring.datasource.data=classpath*:ddlSql/initTeacher.sql

teacher.sql脚本内容

 CREATE TABLE `teacher` (`tid` int(11) NOT NULL AUTO_INCREMENT,`tname` varchar(50) DEFAULT NULL,PRIMARY KEY (`tid`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;

initTeacher.sql脚本内容

insert into teacher(tid,tname) values (null,'王老师'),(null,'crysw老师');

启动应用,查看启动日志。

[2023-06-07 23:01:36.036] [com.alibaba.druid.pool.DruidDataSource] [main] [923] [INFO ] {dataSource-1} inited
[2023-06-07 23:01:36.036] [org.springframework.jdbc.datasource.init.ScriptUtils] [main] 
// 运行sql脚本teacher.sql
[441] [INFO ] Executing SQL script from URL [file:/D:/Develops/IdeaProjects/study-spring-boot/spring-boot-atguigu/spring-boot-02-config/target/classes/ddlSql/teacher.sql]
[2023-06-07 23:01:36.036] [org.springframework.jdbc.datasource.init.ScriptUtils] [main] 
// 创建表teacher
[473] [DEBUG] 0 returned as update count for SQL: CREATE TABLE `teacher` ( `tid` int(11) NOT NULL AUTO_INCREMENT, `tname` varchar(50) DEFAULT NULL, PRIMARY KEY (`tid`) ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8
[2023-06-07 23:01:36.036] [org.springframework.jdbc.datasource.init.ScriptUtils] [main] [476] [DEBUG] SQLWarning ignored: SQL state 'HY000', error code '1681', message [Integer display width is deprecated and will be removed in a future release.]
[2023-06-07 23:01:36.036] [org.springframework.jdbc.datasource.init.ScriptUtils] [main] [476] [DEBUG] SQLWarning ignored: SQL state 'HY000', error code '3719', message ['utf8' is currently an alias for the character set UTF8MB3, but will be an alias for UTF8MB4 in a future release. Please consider using UTF8MB4 in order to be unambiguous.]
[2023-06-07 23:01:36.036] [org.springframework.jdbc.datasource.init.ScriptUtils] [main] [507] [INFO ] Executed SQL script from URL [file:/D:/Develops/IdeaProjects/study-spring-boot/spring-boot-atguigu/spring-boot-02-config/target/classes/ddlSql/teacher.sql] in 28 ms.
[2023-06-07 23:01:36.036] [org.springframework.jdbc.datasource.DataSourceUtils] [main] [329] [DEBUG] Returning JDBC Connection to DataSource
[2023-06-07 23:01:36.036] [org.springframework.jdbc.datasource.DataSourceUtils] [main] [110] [DEBUG] Fetching JDBC Connection from DataSource
// 运行sql脚本initTeacher.sql
[2023-06-07 23:01:36.036] [org.springframework.jdbc.datasource.init.ScriptUtils] [main] [441] [INFO ] Executing SQL script from URL [file:/D:/Develops/IdeaProjects/study-spring-boot/spring-boot-atguigu/spring-boot-02-config/target/classes/ddlSql/initTeacher.sql]
[2023-06-07 23:01:36.036] [org.springframework.jdbc.datasource.init.ScriptUtils] [main] 
// 插入初始化数据到teacher表
[473] [DEBUG] 2 returned as update count for SQL: insert into teacher(tid,tname) values (null,'王老师'),(null,'crysw老师')
[2023-06-07 23:01:36.036] [org.springframework.jdbc.datasource.init.ScriptUtils] [main] [507] [INFO ] Executed SQL script from URL [file:/D:/Develops/IdeaProjects/study-spring-boot/spring-boot-atguigu/spring-boot-02-config/target/classes/ddlSql/initTeacher.sql] in 4 ms.

1.4 数据模板

spring提供了数据库模板JdbcTemplate给我们来操作数据库, 自动配置类JdbcTemplateAutoConfiguration提供了jdbcTemplate组件。

@Configuration
@ConditionalOnClass({ DataSource.class, JdbcTemplate.class })
@ConditionalOnSingleCandidate(DataSource.class)
@AutoConfigureAfter(DataSourceAutoConfiguration.class)
public class JdbcTemplateAutoConfiguration {private final DataSource dataSource;public JdbcTemplateAutoConfiguration(DataSource dataSource) {this.dataSource = dataSource;}@Bean@Primary@ConditionalOnMissingBean(JdbcOperations.class)public JdbcTemplate jdbcTemplate() {return new JdbcTemplate(this.dataSource);}
}

编写controller,使用数据模板jdbcTemplate操作数据库测试。

@Controller
public class HelloController {Logger logger = LoggerFactory.getLogger(this.getClass());@Autowiredprivate JdbcTemplate jdbcTemplate;@ResponseBody@GetMapping("/queryTeacher")public Map<String, Object> queryTeacher() {List<Map<String, Object>> teachers = jdbcTemplate.queryForList("select * from teacher");return teachers.get(0);}
}

访问 http://localhost:8082/boot1/queryTeacher, 返回结果:

{"tid": 1,"tname": "王老师"
}

2. 整合Druid数据源

2.1 依赖及配置

导入依赖

<dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.1.8</version>
</dependency>

全局配置文件指定数据库连接池类型(指定数据源)

spring.datasource.type=com.alibaba.druid.pool.DruidDataSource

编写配置类,整合Druid数据源

@Configuration
public class DruidConfig {@ConfigurationProperties(prefix = "spring.datasource")@Beanpublic DataSource druidDataSource() {return new DruidDataSource();}// 配置Druid监控// 1. 配置一个管理后台的Servlet@Beanpublic ServletRegistrationBean statViewServlet() {ServletRegistrationBean bean = new ServletRegistrationBean(new StatViewServlet(), "/druid/*");Map<String, String> initParams = new HashMap<>();// 设置Druid监控登录用户和密码initParams.put("loginUsername", "admin");initParams.put("loginPassword", "123456");initParams.put("allow", ""); // 默认允许所有initParams.put("deny", "192.168.1.103"); // 拒绝该主机访问bean.setInitParameters(initParams);return bean;}// 2. 配置一个web监控的filter@Beanpublic FilterRegistrationBean webStatFilter() {FilterRegistrationBean filterBean = new FilterRegistrationBean();filterBean.setFilter(new WebStatFilter());Map<String, String> filterParams = new HashMap<>();filterParams.put("exclusions", "*.js,*.css,/druid/*");filterBean.setInitParameters(filterParams);filterBean.setUrlPatterns(Arrays.asList("/*"));return filterBean;}
}

2.2 druid监控

启动应用,访问 http://localhost:8082/boot1/druid 进入Druid监控登录界面
在这里插入图片描述

访问查询请求 , http://localhost:8082/boot1/queryTeacher 查看监控。
在这里插入图片描述

2.3 druid自动配置类

上面是自定义的数据源配置类,提供了DruidDataSource实例。还可以使用druid官方提供的启动器提供了自动配置类 DruidDataSourceAutoConfigure, 不用自己编写配置类。

<dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId><version>1.2.3</version>
</dependency>

自动配置类 DruidDataSourceAutoConfigure

@Configuration
@ConditionalOnClass(DruidDataSource.class)
@AutoConfigureBefore(DataSourceAutoConfiguration.class)
@EnableConfigurationProperties({DruidStatProperties.class, DataSourceProperties.class})
@Import({DruidSpringAopConfiguration.class,// 监控的servlet配置DruidStatViewServletConfiguration.class,// 监控的filter配置DruidWebStatFilterConfiguration.class,// DruidFilterConfiguration.class})
public class DruidDataSourceAutoConfigure {private static final Logger LOGGER = LoggerFactory.getLogger(DruidDataSourceAutoConfigure.class);@Bean(initMethod = "init")@ConditionalOnMissingBeanpublic DataSource dataSource() {LOGGER.info("Init DruidDataSource");return new DruidDataSourceWrapper();}
}

druid的监控servlet配置中,需要指定监控界面开启为true,才能访问监控界面;

@ConditionalOnWebApplication
@ConditionalOnProperty(name = "spring.datasource.druid.stat-view-servlet.enabled", havingValue = "true")
public class DruidStatViewServletConfiguration {//...
}

druid监控url请求,需要配置开启webFilter,才能实现请求的拦截监控。

@ConditionalOnWebApplication
@ConditionalOnProperty(name = "spring.datasource.druid.web-stat-filter.enabled", havingValue = "true")
public class DruidWebStatFilterConfiguration {//...
}

在全局配置文件中配置druid监控的相关参数

# 开启druid监控
spring.datasource.druid.stat-view-servlet.enabled=true
spring.datasource.druid.stat-view-servlet.login-username=admin
spring.datasource.druid.stat-view-servlet.login-password=12345678
spring.datasource.druid.stat-view-servlet.reset-enable=false
spring.datasource.druid.stat-view-servlet.url-pattern=/druid/*
spring.datasource.druid.web-stat-filter.enabled=true
spring.datasource.druid.web-stat-filter.url-pattern=/*
spring.datasource.druid.web-stat-filter.exclusions=*.js,*.css,/druid/*

注释掉自定义的数据源配置类, 再次启动应用访问 http://localhost:8082/boot1/druid 也成功进入Druid监控登录界面。随机触发几个请求,也可以实现监控。
在这里插入图片描述

druid监控博文学习

Spring系列之集成Druid连接池及监控配置 - 掘金

SpringBoot开启Druid监控统计功能(SQL监控、慢SQL记录、Spring监控、去广告)

3. 整合Mybatis

3.1 依赖管理

<dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>1.3.5</version>
</dependency>

依赖关系图
在这里插入图片描述

3.2 mybatis核心配置及参数配置

在类路径下添加mybatis核心配置文件mybatis-config.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration><!-- 全局配置参数,需要时再设置 --><settings><!-- 打开延迟加载开关 --><setting name="lazyLoadingEnabled" value="true"/><!-- 将积极加载改为消极加载,即按需加载 --><setting name="aggressiveLazyLoading" value="false"/><!-- 开启二级缓存 --><setting name="cacheEnabled" value="true"/><!--开启驼峰映射--><setting name="mapUnderscoreToCamelCase" value="true"/></settings>
</configuration>

在全局配置文件application.properties中配置mybatis参数

## mybatis配置
mybatis.config-location=classpath:mybatis/mybatis-config.xml
mybatis.mapper-locations=classpath:mybatis/mapper/*.xml
mybatis.type-aliases-package=com.aiguigu.springboot02config.entities

3.3 mapper接口开发

注解版mapper接口,不需要mapper映射xml文件,sql直接写在接口方法上。

// 指定这是一个操作数据库的mapper接口
//@Mapper  // 注释掉后在启动类上加@MapperScan(value = {"com.aiguigu.spriingboot02config.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(department_name) values(#{departmentName})")public int insertDept(Department department);@Update("update department set department_name=#{departmentName} where id=#{id}")public int updateDept(Department department);
}

mapper接口+mapper映射xml文件的方式

// @Mapper 或 @MapperScan将接口扫描装配到容器中
public interface EmployeeMapper {Employee2 getEmpById(Integer id);void insertEmp(Employee2 employee);
}

EmployeeMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.aiguigu.springboot02config.mapper.EmployeeMapper"><select id="getEmpById" resultType="com.aiguigu.springboot02config.entities.Employee2">select * from employee where id = #{id}</select><insert id="insertEmp" useGeneratedKeys="true" keyProperty="id" keyColumn="id">insert into employee(lastName,email,gender,d_id)values(#{lastName},#{email},#{gender},#{d_id})</insert>
</mapper>

4. 整合JPA

4.1 Spring Data简介

Spring Data项目简化了基于Spring框架应用的数据访问技术,包括非关系型数据库、Map-Reduce框架、云数据服务等,另外也包含对关系数据库的访问支持。

Spring Data为我们提供使用统一的API来对数据访问层进行操作;这主要是Spring Data Commons项目来实现的。Spring Data Commons让我们在使用关系型或非关系型数据访问技术时都基于Spring提供的统一标准,标准包含了CRUD(创建、获取、更新、删除)、查询、排序和分页的相关操作。

Repository<T ID extends Serializable> 统一的Repository接口 ;

RevisionRepository<T, ID extends Serializable, N extends Number & Comparable<N>> 基于乐观锁机制;

CrudRepository<T, ID extends Serializable> 基本的CRUD操作;

PagingAndSortingRepository<T, ID extends Serializable> 基本CRUD及分页;

xxxTemplate 数据访问模板类 (JdbcTemplate, RedisTemplate);

JPA与Spring Data

  • JpaRepository 基本功能, 编写接口继承JpaRepository, 就有了crud及分页等基本功能;
  • 定义符合规范的方法命名, 在接口中只需要声明符合规范的方法, 就拥有对应的功能;

在这里插入图片描述

  • @Query 自定义查询, 定制查询SQL;

    整合框架图
    在这里插入图片描述

4.2 使用Spring Data JPA

导入依赖

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

编写一个实体类(bean)和数据库表进行映射, 并且配置好映射关系。

// 使用JPA注解配置映射关系
@Entity // 标识这是一个实体类,和数据库表映射
@Table(name = "tb_user") // 指定映射的库表, 如果省略默认表名就是user
public class User {@Id // 主键@GeneratedValue(strategy = GenerationType.IDENTITY) // 自增主键private Integer id;@Column(name = "last_name", length = 50)private String lastName;@Column // 省略默认列名就是属性名private String email;public User() {}public User(Integer id, String lastName, String email) {this.id = id;this.lastName = lastName;this.email = email;}// setXXX and getXXX   
}    

编写一个Dao接口操作, 实体类对应的数据库表(Repository)。

// 继承 JpaRepository 完成对数据库表的操作
public interface UserRepository extends JpaRepository<User, Integer> {
}

基本的配置

## 更新或者创建数据库表结构
spring.jpa.hibernate.ddl-auto=update
## 控制台显示sql
spring.jpa.show-sql=true

编写controller使用repository

@RestController
public class UserController {@AutowiredUserRepository userRepository;@GetMapping("/user/{id}")public User getUser(@PathVariable("id") Integer id) {User user = userRepository.findOne(id);return user;}@GetMapping("/user")public User insertUser(User user) {User _user = userRepository.save(user);return _user; // 封装了自增主键id返回}
}

测试 http://localhost:8082/boot1/user?lastName=admin&email=admin@qq.com
在这里插入图片描述

访问 http://localhost:8082/boot1/user/1
在这里插入图片描述

http://www.lryc.cn/news/93674.html

相关文章:

  • 【Sqlite3】maraidb和sqlite3部分命令操作区别
  • Linux中新建用户使用sudo问题
  • Sentinel源码分析-ProceesorSlotChain调用链及树状资源节点
  • springboot 连接 kafka集群(kafka版本 2.13-3.4.0)
  • Nacos配置中心使用(Spring Cloud版)
  • STM32F407硬件I2C实现MPU6050通讯(CUBEIDE)
  • HTML5 语义元素(一)页面结构
  • 嵌套滚动实践:onInterceptTouchEvent与NestedScrolling【实用为准】
  • Redis入门 - 5种基本数据类型
  • mybatis-plus用法(一)
  • 源码安装包管理
  • Vue|获取表单数据
  • 微信小程序入门学习02-TDesign中的自定义组件
  • 【linux kernel】linux media子系统分析之media控制器设备
  • Scala--03
  • 【MongoDB】--MongoDB高级功能
  • C# new与malloc
  • 微软MFC技术简明介绍
  • 汽车电子Autosar之车载以太网
  • MSP430_C语言例程注释详
  • Vb+access库存管理系统(论文+开题报告+源代码+目录)
  • Java 数组
  • CSDN 编程竞赛五十八期题解
  • Unity入门6——光源组件
  • C语言之动态内存分配(1)
  • AIGC新时代,注意政策走向,产业方向,拥抱可信AI。需要了解基本理论,基础模型,前沿进展,产品应用,以及小小的项目复现
  • 如何白嫖一年CSDN会员?618活动!亲测有效!!!
  • 微服务: 00-rabbitmq出现的异常以及解决方案
  • Vue3与Vue2比较
  • 如何对待工作中的失误?