乐清市网站建设服务,做区块链网站的公司,广州市手机网站建设服务机构,企业员工信息管理系统本章概要
依赖整合和添加控制层配置编写(SpringMVC 整合)业务配置编写(AOP/TX 整合)持久层配置编写(MyBatis 整合)容器初始化配置类整合测试
2.1 依赖整合和添加
数据库准备 数据库脚本 CREATE DATABASE mybatis-example;USE mybatis-example;CREATE TABLE t_emp(emp_id INT…本章概要
依赖整合和添加控制层配置编写(SpringMVC 整合)业务配置编写(AOP/TX 整合)持久层配置编写(MyBatis 整合)容器初始化配置类整合测试
2.1 依赖整合和添加
数据库准备 数据库脚本 CREATE DATABASE mybatis-example;USE mybatis-example;CREATE TABLE t_emp(emp_id INT AUTO_INCREMENT,emp_name CHAR(100),emp_salary DOUBLE(10,5),PRIMARY KEY(emp_id)
);INSERT INTO t_emp(emp_name,emp_salary) VALUES(tom,200.33);
INSERT INTO t_emp(emp_name,emp_salary) VALUES(jerry,666.66);
INSERT INTO t_emp(emp_name,emp_salary) VALUES(andy,777.77);准备项目
part04-ssm-integration转成 web项目
依赖导入
?xml version1.0 encodingUTF-8?project xmlnshttp://maven.apache.org/POM/4.0.0 xmlns:xsihttp://www.w3.org/2001/XMLSchema-instance xsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd modelVersion4.0.0/modelVersion groupIdcom.atguigu/groupId artifactIdpart04-ssm-integration/artifactId version1.0-SNAPSHOT/version packagingwar/packagingpropertiesspring.version6.0.6/spring.versionjakarta.annotation-api.version2.1.1/jakarta.annotation-api.versionjakarta.jakartaee-web-api.version9.1.0/jakarta.jakartaee-web-api.versionjackson-databind.version2.15.0/jackson-databind.versionhibernate-validator.version8.0.0.Final/hibernate-validator.versionmybatis.version3.5.11/mybatis.versionmysql.version8.0.25/mysql.versionpagehelper.version5.1.11/pagehelper.versiondruid.version1.2.8/druid.versionmybatis-spring.version3.0.2/mybatis-spring.versionjakarta.servlet.jsp.jstl-api.version3.0.0/jakarta.servlet.jsp.jstl-api.versionlogback.version1.2.3/logback.versionlombok.version1.18.26/lombok.versionmaven.compiler.source17/maven.compiler.sourcemaven.compiler.target17/maven.compiler.target project.build.sourceEncodingUTF-8/project.build.sourceEncoding /properties!--需要依赖清单分析:springioc/dispring-context / 6.0.6jakarta.annotation-api / 2.1.1 jsr250aopspring-aspects / 6.0.6txspring-tx / 6.0.6spring-jdbc / 6.0.6springmvcspring-webmvc 6.0.6jakarta.jakartaee-web-api 9.1.0jackson-databind 2.15.0hibernate-validator / hibernate-validator-annotation-processor 8.0.0.Finalmybatismybatis / 3.5.11mysql / 8.0.25pagehelper / 5.1.11整合需要加载spring容器 spring-web / 6.0.6整合mybatis mybatis-spring x x数据库连接池 druid / xlombok lombok / 1.18.26logback logback/ 1.2.3--dependencies!--spring pom.xml依赖--dependencygroupIdorg.springframework/groupIdartifactIdspring-context/artifactIdversion${spring.version}/version/dependencydependencygroupIdjakarta.annotation/groupIdartifactIdjakarta.annotation-api/artifactIdversion${jakarta.annotation-api.version}/version/dependencydependencygroupIdorg.springframework/groupIdartifactIdspring-aop/artifactIdversion${spring.version}/version/dependencydependencygroupIdorg.springframework/groupIdartifactIdspring-aspects/artifactIdversion${spring.version}/version/dependencydependencygroupIdorg.springframework/groupIdartifactIdspring-tx/artifactIdversion${spring.version}/version/dependencydependencygroupIdorg.springframework/groupIdartifactIdspring-jdbc/artifactIdversion${spring.version}/version/dependency!--springmvcspring-webmvc 6.0.6jakarta.jakartaee-web-api 9.1.0jackson-databind 2.15.0hibernate-validator / hibernate-validator-annotation-processor 8.0.0.Final--dependencygroupIdorg.springframework/groupIdartifactIdspring-webmvc/artifactIdversion${spring.version}/version/dependencydependencygroupIdjakarta.platform/groupIdartifactIdjakarta.jakartaee-web-api/artifactIdversion${jakarta.jakartaee-web-api.version}/versionscopeprovided/scope/dependency!-- jsp需要依赖! jstl--dependencygroupIdjakarta.servlet.jsp.jstl/groupIdartifactIdjakarta.servlet.jsp.jstl-api/artifactIdversion${jakarta.servlet.jsp.jstl-api.version}/version/dependencydependencygroupIdcom.fasterxml.jackson.core/groupIdartifactIdjackson-databind/artifactIdversion${jackson-databind.version}/version/dependency!-- https://mvnrepository.com/artifact/org.hibernate.validator/hibernate-validator --dependencygroupIdorg.hibernate.validator/groupIdartifactIdhibernate-validator/artifactIdversion${hibernate-validator.version}/version/dependency!-- https://mvnrepository.com/artifact/org.hibernate.validator/hibernate-validator-annotation-processor --dependencygroupIdorg.hibernate.validator/groupIdartifactIdhibernate-validator-annotation-processor/artifactIdversion${hibernate-validator.version}/version/dependency!--mybatismybatis / 3.5.11mysql / 8.0.25pagehelper / 5.1.11--!-- mybatis依赖 --dependencygroupIdorg.mybatis/groupIdartifactIdmybatis/artifactIdversion${mybatis.version}/version/dependency!-- MySQL驱动 mybatis底层依赖jdbc驱动实现,本次不需要导入连接池,mybatis自带! --dependencygroupIdmysql/groupIdartifactIdmysql-connector-java/artifactIdversion${mysql.version}/version/dependencydependencygroupIdcom.github.pagehelper/groupIdartifactIdpagehelper/artifactIdversion${pagehelper.version}/version/dependency!-- 整合第三方特殊依赖 --dependencygroupIdorg.springframework/groupIdartifactIdspring-web/artifactIdversion${spring.version}/version/dependencydependencygroupIdorg.mybatis/groupIdartifactIdmybatis-spring/artifactIdversion${mybatis-spring.version}/version/dependency!-- 日志 会自动传递slf4j门面--dependencygroupIdch.qos.logback/groupIdartifactIdlogback-classic/artifactIdversion${logback.version}/version/dependencydependencygroupIdorg.projectlombok/groupIdartifactIdlombok/artifactIdversion${lombok.version}/version/dependencydependencygroupIdcom.alibaba/groupIdartifactIddruid/artifactIdversion${druid.version}/version/dependency/dependencies/project实体类添加 com.atguigu.pojo Data
public class Employee {private Integer empId;private String empName;private Double empSalary;
}logback配置 位置resources/logback.xml ?xml version1.0 encodingUTF-8?
configuration debugtrue!-- 指定日志输出的位置ConsoleAppender表示输出到控制台 --appender nameSTDOUTclassch.qos.logback.core.ConsoleAppenderencoder!-- 日志输出的格式 --!-- 按照顺序分别是时间、日志级别、线程名称、打印日志的类、日志主体内容、换行 --pattern[%d{HH:mm:ss.SSS}] [%-5level] [%thread] [%logger] [%msg]%n/patterncharsetUTF-8/charset/encoder/appender!-- 设置全局日志级别。日志级别按顺序分别是TRACE、DEBUG、INFO、WARN、ERROR --!-- 指定任何一个日志级别都只打印当前级别和后面级别的日志。 --root levelDEBUG!-- 指定打印日志的appender这里通过“STDOUT”引用了前面配置的appender --appender-ref refSTDOUT //root!-- 根据特殊需求指定局部日志级别可也是包名或全类名。 --logger namecom.atguigu.mybatis levelDEBUG //configuration2.2 控制层配置编写(SpringMVC 整合) 主要配置controller,springmvc相关组件配置 。位置com.atguigu.config.WebJavaConfig.java(命名随意) /*** projectName: com.atguigu.config* * 1.实现Springmvc组件声明标准化接口WebMvcConfigurer 提供了各种组件对应的方法* 2.添加配置类注解Configuration* 3.添加mvc复合功能开关EnableWebMvc* 4.添加controller层扫描注解* 5.开启默认处理器,支持静态资源处理*/
Configuration
EnableWebMvc
ComponentScan(com.atguigu.controller)
public class WebJavaConfig implements WebMvcConfigurer {//开启静态资源Overridepublic void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {configurer.enable(); }
}2.3 业务配置编写(AOP/TX 整合) 主要配置service,注解aop和声明事务相关配置。位置 com.atguigu.config.ServiceJavaConfig.java(命名随意) /*** projectName: com.atguigu.config* * 1. 声明Configuration注解,代表配置类* 2. 声明EnableTransactionManagement注解,开启事务注解支持* 3. 声明EnableAspectJAutoProxy注解,开启aspect aop注解支持* 4. 声明ComponentScan(com.atguigu.service)注解,进行业务组件扫描* 5. 声明transactionManager(DataSource dataSource)方法,指定具体的事务管理器*/
EnableTransactionManagement
EnableAspectJAutoProxy
Configuration
ComponentScan(com.atguigu.service)
public class ServiceJavaConfig {Beanpublic DataSourceTransactionManager transactionManager(DataSource dataSource){DataSourceTransactionManager transactionManager new DataSourceTransactionManager();transactionManager.setDataSource(dataSource);return transactionManager;}}2.4 持久层配置编写(MyBatis 整合) 主要配置mapper代理对象连接池和mybatis核心组件配置 MyBatis整合思路
//1.读取外部配置文件
InputStream ips Resources.getResourceAsStream(mybatis-config.xml);//2.创建sqlSessionFactory
SqlSessionFactory sqlSessionFactory new SqlSessionFactoryBuilder().build(ips);//3.创建sqlSession
SqlSession sqlSession sqlSessionFactory.openSession();
//4.获取mapper代理对象
EmpMapper empMapper sqlSession.getMapper(EmpMapper.class);
//5.数据库方法调用
int rows empMapper.deleteEmpById(1);
System.out.println(rows rows);
//6.提交和回滚
sqlSession.commit();
sqlSession.close();MyBatis核心api介绍 SqlSessionFactoryBuilder 这个类可以被实例化、使用和丢弃一旦创建了 SqlSessionFactory就不再需要它了。因此 SqlSessionFactoryBuilder 实例的最佳作用域是方法作用域也就是局部方法变量。 无需ioc容器管理 SqlSessionFactory 一旦被创建就应该在应用的运行期间一直存在没有任何理由丢弃它或重新创建另一个实例。 使用 SqlSessionFactory 的最佳实践是在应用运行期间不要重复创建多次因此 SqlSessionFactory 的最佳作用域是应用作用域。需要ioc容器管理 SqlSession 每个线程都应该有它自己的SqlSession实例。SqlSession的实例不是线程安全的因此是不能被共享的所以它的最佳的作用域是请求或方法作用域。 无需**ioc**容器管理 Mapper 映射器实例 映射器是一些绑定映射语句的接口。映射器接口的实例是从SqlSession中获得的。虽然从技术层面上来讲任何映射器实例的最大作用域与请求它们的SqlSession相同。但方法作用域才是映射器实例的最合适的作用域。 从作用域的角度来说映射器实例不应该交给ioc容器管理 但是从使用的角度来说业务类service需要注入mapper接口所以mapper应该交给ioc容器管理 总结 将SqlSessionFactory实例存储到IoC容器将Mapper实例存储到IoC容器 MyBatis整合思路理解 MyBatis的api实例化需要复杂的过程。 例如自己实现sqlSessionFactory加入ioc容器
Bean
public SqlSessionFactory sqlSessionFactory(){//1.读取外部配置文件InputStream ips Resources.getResourceAsStream(mybatis-config.xml);//2.创建sqlSessionFactorySqlSessionFactory sqlSessionFactory new SqlSessionFactoryBuilder().build(ips);return sqlSessionFactory;
}过程比较繁琐为了提高整合效率MyBatis提供了提供封装SqlSessionFactory和Mapper实例化的逻辑的FactoryBean组件我们只需要声明和指定少量的配置即可 SqlSessionFactoryBean源码展示(MyBatis提供) package org.mybatis.spring;public class SqlSessionFactoryBeanimplements FactoryBeanSqlSessionFactory, InitializingBean, ApplicationListenerContextRefreshedEvent {//封装了实例化流程public SqlSessionFactory getObject() throws Exception {if (this.sqlSessionFactory null) {//实例化对象逻辑afterPropertiesSet();}//返回对象逻辑return this.sqlSessionFactory;}}MyBatis整合思路总结
需要将SqlSessionFactory和Mapper实例加入到IoC容器使用MyBatis整合包提供的FactoryBean快速整合
整合外部配置文件 数据库连接信息。位置 resources/jdbc.properties jdbc.userroot
jdbc.passwordroot
jdbc.urljdbc:mysql:///mybatis-example
jdbc.drivercom.mysql.cj.jdbc.Driver整合方式1保留mybatis-config.xml
介绍 依然保留MyBatis的外部配置文件xml, 但是数据库连接信息交给Druid连接池配置 缺点 依然保留MyBatis的外部配置文件xml, 但是数据库连接信息交给Druid连接
MyBatis配置文件 数据库信息以及mapper扫描包设置使用Java配置类处理MyBatis其他的功能别名、settings、插件等信息依然在mybatis-config.xml配置 ?xml version1.0 encodingUTF-8 ?
!DOCTYPE configurationPUBLIC -//mybatis.org//DTD Config 3.0//ENhttp://mybatis.org/dtd/mybatis-3-config.dtd
configurationsettings!-- 开启驼峰式映射--setting namemapUnderscoreToCamelCase valuetrue/!-- 开启logback日志输出--setting namelogImpl valueSLF4J/!--开启resultMap自动映射 --setting nameautoMappingBehavior valueFULL//settingstypeAliases!-- 给实体类起别名 --package namecom.atguigu.pojo//typeAliasespluginsplugin interceptorcom.github.pagehelper.PageInterceptor!--helperDialect分页插件会自动检测当前的数据库链接自动选择合适的分页方式。你可以配置helperDialect属性来指定分页插件使用哪种方言。配置时可以使用下面的缩写值oracle,mysql,mariadb,sqlite,hsqldb,postgresql,db2,sqlserver,informix,h2,sqlserver2012,derby完整内容看 PageAutoDialect 特别注意使用 SqlServer2012 数据库时https://github.com/pagehelper/Mybatis-PageHelper/blob/master/wikis/zh/HowToUse.md#%E5%A6%82%E4%BD%95%E9%85%8D%E7%BD%AE%E6%95%B0%E6%8D%AE%E5%BA%93%E6%96%B9%E8%A8%80--property namehelperDialect valuemysql//plugin/plugins
/configurationMyBatis和持久层配置类 持久层Mapper配置、数据库配置、Mybatis配置信息。 位置com.atguigu.config.MapperJavaConfig.java(命名随意) Configuration
PropertySource(classpath:jdbc.properties)
public class MapperJavaConfig {Value(${jdbc.user})private String user;Value(${jdbc.password})private String password;Value(${jdbc.url})private String url;Value(${jdbc.driver})private String driver;//数据库连接池配置Beanpublic DataSource dataSource(){DruidDataSource dataSource new DruidDataSource();dataSource.setUsername(user);dataSource.setPassword(password);dataSource.setUrl(url);dataSource.setDriverClassName(driver);return dataSource;}/*** 配置SqlSessionFactoryBean,指定连接池对象和外部配置文件即可* param dataSource 需要注入连接池对象* return 工厂Bean*/Beanpublic SqlSessionFactoryBean sqlSessionFactoryBean(DataSource dataSource){//实例化SqlSessionFactory工厂SqlSessionFactoryBean sqlSessionFactoryBean new SqlSessionFactoryBean();//设置连接池sqlSessionFactoryBean.setDataSource(dataSource);//设置配置文件//包裹外部配置文件地址对象Resource resource new ClassPathResource(mybatis-config.xml);sqlSessionFactoryBean.setConfigLocation(resource);return sqlSessionFactoryBean;}/*** 配置Mapper实例扫描工厂,配置 mapper package 对应接口和mapperxml文件所在的包* return*/Beanpublic MapperScannerConfigurer mapperScannerConfigurer(){MapperScannerConfigurer mapperScannerConfigurer new MapperScannerConfigurer();//设置mapper接口和xml文件所在的共同包mapperScannerConfigurer.setBasePackage(com.atguigu.mapper);return mapperScannerConfigurer;}}问题 当在Spring配置类中添加了sqlSessionFactoryBean和mapperScannerConfigurer配置方法时可能会导致Value注解读取不到值为null的问题。这是因为SqlSessionFactoryBean和MapperScannerConfigurer是基于MyBatis框架的配置它们的初始化顺序可能会导致属性注入的问题。
SqlSessionFactoryBean和MapperScannerConfigurer在配置类中通常是用来配置MyBatis相关的Bean例如数据源、事务管理器、Mapper扫描等。这些配置类通常在Configuration注解下定义并且使用Value注解来注入属性值。
当配置类被加载时Spring容器会首先处理Bean的定义和初始化其中包括sqlSessionFactoryBean和mapperScannerConfigurer的初始化。在这个过程中如果Value注解所在的Bean还没有被完全初始化可能会导致注入的属性值为null。
解决方案 分成两个配置类独立配置互不影响数据库提取一个配置类MyBatis提取一个配置类即可解决
拆分配置 数据库配置类DataSourceJavaConfig.java Configuration
PropertySource(classpath:jdbc.properties)
public class DataSourceJavaConfig {Value(${jdbc.user})private String user;Value(${jdbc.password})private String password;Value(${jdbc.url})private String url;Value(${jdbc.driver})private String driver;//数据库连接池配置Beanpublic DataSource dataSource(){DruidDataSource dataSource new DruidDataSource();dataSource.setUsername(user);dataSource.setPassword(password);dataSource.setUrl(url);dataSource.setDriverClassName(driver);return dataSource;}}MyBatis配置类MapperJavaConfig.java Configuration
public class MapperJavaConfig {/*** 配置SqlSessionFactoryBean,指定连接池对象和外部配置文件即可* param dataSource 需要注入连接池对象* return 工厂Bean*/Beanpublic SqlSessionFactoryBean sqlSessionFactoryBean(DataSource dataSource){//实例化SqlSessionFactory工厂SqlSessionFactoryBean sqlSessionFactoryBean new SqlSessionFactoryBean();//设置连接池sqlSessionFactoryBean.setDataSource(dataSource);//设置配置文件//包裹外部配置文件地址对象Resource resource new ClassPathResource(mybatis-config.xml);sqlSessionFactoryBean.setConfigLocation(resource);return sqlSessionFactoryBean;}/*** 配置Mapper实例扫描工厂,配置 mapper package 对应接口和mapperxml文件所在的包* return*/Beanpublic MapperScannerConfigurer mapperScannerConfigurer(){MapperScannerConfigurer mapperScannerConfigurer new MapperScannerConfigurer();//设置mapper接口和xml文件所在的共同包mapperScannerConfigurer.setBasePackage(com.atguigu.mapper);return mapperScannerConfigurer;}}整合方式2 完全配置类 去掉mybatis-config.xml
介绍 不在保留MyBatis的外部配置文件xml, 所有配置信息settings、插件、别名等全部在声明SqlSessionFactoryBean的代码中指定数据库信息依然使用DruidDataSource实例替代 优势全部配置类避免了**XML**文件解析效率低问题
mapper配置类
/*** projectName: com.atguigu.config** description: 持久层配置和Druid和Mybatis配置 使用一个配置文件*/
Configuration
public class MapperJavaConfigNew {/*** 配置SqlSessionFactoryBean,指定连接池对象和外部配置文件即可* param dataSource 需要注入连接池对象* return 工厂Bean*/Beanpublic SqlSessionFactoryBean sqlSessionFactoryBean(DataSource dataSource){//实例化SqlSessionFactory工厂SqlSessionFactoryBean sqlSessionFactoryBean new SqlSessionFactoryBean();//设置连接池sqlSessionFactoryBean.setDataSource(dataSource);//TODO: 替代xml文件的java配置/*settings!-- 开启驼峰式映射--setting namemapUnderscoreToCamelCase valuetrue/!-- 开启logback日志输出--setting namelogImpl valueSLF4J/!--开启resultMap自动映射 --setting nameautoMappingBehavior valueFULL//settingstypeAliases!-- 给实体类起别名 --package namecom.atguigu.pojo//typeAliasespluginsplugin interceptorcom.github.pagehelper.PageInterceptor!--helperDialect分页插件会自动检测当前的数据库链接自动选择合适的分页方式。你可以配置helperDialect属性来指定分页插件使用哪种方言。配置时可以使用下面的缩写值oracle,mysql,mariadb,sqlite,hsqldb,postgresql,db2,sqlserver,informix,h2,sqlserver2012,derby完整内容看 PageAutoDialect 特别注意使用 SqlServer2012 数据库时https://github.com/pagehelper/Mybatis-PageHelper/blob/master/wikis/zh/HowToUse.md#%E5%A6%82%E4%BD%95%E9%85%8D%E7%BD%AE%E6%95%B0%E6%8D%AE%E5%BA%93%E6%96%B9%E8%A8%80--property namehelperDialect valuemysql//plugin/plugins*///settings [包裹到一个configuration对象,切记别倒错包]org.apache.ibatis.session.Configuration configuration new org.apache.ibatis.session.Configuration();configuration.setMapUnderscoreToCamelCase(true);configuration.setLogImpl(Slf4jImpl.class);configuration.setAutoMappingBehavior(AutoMappingBehavior.FULL);sqlSessionFactoryBean.setConfiguration(configuration);//typeAliasessqlSessionFactoryBean.setTypeAliasesPackage(com.atguigu.pojo);//分页插件配置PageInterceptor pageInterceptor new PageInterceptor();Properties properties new Properties();properties.setProperty(helperDialect,mysql);pageInterceptor.setProperties(properties);sqlSessionFactoryBean.addPlugins(pageInterceptor);return sqlSessionFactoryBean;}/*** 配置Mapper实例扫描工厂,配置 mapper package 对应接口和mapperxml文件所在的包* return*/Beanpublic MapperScannerConfigurer mapperScannerConfigurer(){MapperScannerConfigurer mapperScannerConfigurer new MapperScannerConfigurer();//设置mapper接口和xml文件所在的共同包mapperScannerConfigurer.setBasePackage(com.atguigu.mapper);return mapperScannerConfigurer;}}2.5 容器初始化配置类
public class MyWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {//指定root容器对应的配置类Overrideprotected Class?[] getRootConfigClasses() {return new Class?[] {MapperJavaConfig.class, ServiceJavaConfig.class, DataSourceJavaConfig.class };}//指定web容器对应的配置类Overrideprotected Class?[] getServletConfigClasses() {return new Class?[] { WebJavaConfig.class };}//指定dispatcherServlet处理路径通常为 / Overrideprotected String[] getServletMappings() {return new String[] { / };}
}2.6 整合测试
需求
查询所有员工信息返回对应 json 数据
controller
Slf4j
RestController
RequestMapping(/employee)
public class EmployeeController {Autowiredprivate EmployeeService employeeService;GetMapping(list)public ListEmployee retList(){ListEmployee employees employeeService.findAll();log.info(员工数据:{},employees);return employees;}
}service
Service
public class EmployeeServiceImpl implements EmployeeService {Autowiredprivate EmployeeMapper employeeMapper;/*** 查询所有员工信息*/Overridepublic ListEmployee findAll() {ListEmployee employeeList employeeMapper.queryAll();return employeeList;}
}mapper mapper接口 包com.atguigu.mapper public interface EmployeeMapper {ListEmployee queryAll();
}mapper XML 文件位置 resources/mappers ?xml version1.0 encodingUTF-8 ?
!DOCTYPE mapperPUBLIC -//mybatis.org//DTD Mapper 3.0//ENhttps://mybatis.org/dtd/mybatis-3-mapper.dtd
!-- namespace等于mapper接口类的全限定名,这样实现对应 --
mapper namespacecom.atguigu.mapper.EmployeeMapperselect idqueryAll resultTypeemployee!-- #{empId}代表动态传入的参数,并且进行赋值!后面详细讲解 --select emp_id empId,emp_name empName, emp_salary empSalary from t_emp/select/mapper