Spring与持久层进行整合
1.为什么spring要与持久层进行整合?
1.javaEE的开发需要持久层进行数据库的操作。
2.JDBC,Hibernate Mybatis在开发过程中存在大量的代码冗余
3.spring基于模板设计模式对上述的持久层技术进行了封装
2.spring可以与哪些持久层技术进行整合?
1.JDBC--->JdbcTemplate
2.Hibernate(JPA)--->HibernateTemplate
3.Mybatis--->sqlSessionFactoryBean,MapperScannerConfigure
Spring与Mybatis整合
Mybatis使用回顾
-
环境准备,导入相关jar包
<dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.4</version> <scope>compile</scope> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.20</version> </dependency>
-
定义实体类---->mybatis-config增加实体类别名
<typeAliases>
<typeAlias type="com.boss.learning.domain.User" alias="User"/>
</typeAliases>
//起别名的操作,方便后续在写全限名的地方直接写别名代替
-
定义与实体类构造一致的表
-
定义dao接口
-
实现mapper,并注册到配置文件当中
//固定部分,mapper.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.boss.learning.mapper.UserMapper"> //中间部分对应相应的接口中各个方法的实现 </mapper>
-
配置文件的总体结构
<!--固定部分--> <?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="cacheEnabled" value="false"/> <!-- 全局启用或禁用延迟加载。当禁用时,所有关联对象都会即时加载 --> <setting name="lazyLoadingEnabled" value="true"/> <!--true 积极加载 false 消极加载及按需加载 --> <setting name="aggressiveLazyLoading" value="false"/> <!--允许和不允许单条语句返回多个数据集(取决于驱动需求)默认true--> <setting name="multipleResultSetsEnabled" value="true"/> <!--使用列标签代替列名称。默认true--> <setting name="useColumnLabel" value="true"/> <!--允许JDBC 生成主键。需要驱动器支持。如果设为了true,这个设置将强制使用被生成的主键,//有一些驱动器不兼容不过仍然可以执行,默认false--> <setting name="useGeneratedKeys" value="false"/> <!--自动驼峰命名转换 --> <setting name="mapUnderscoreToCamelCase" value="true"/> <!--配置和设定执行器, SIMPLE 执行器执行其它语句; REUSE 执行器可能重复使用prepared statements 语句; BATCH 执行器可以重复执行语句和批量更新。默认为SIMPLE--> <setting name="defaultExecutorType" value="SIMPLE"/> <!--驱动器等待数据库响应超时时间--> <setting name="defaultStatementTimeout" value="25000"/> <!--查询结果日志打印--> <setting name="logImpl" value="STDOUT_LOGGING" /> </settings> <!--起别名--> <typeAliases> <typeAlias type="com.boss.learning.domain.User" alias="User"/> <typeAlias type="com.boss.learning.domain.Condition" alias="Condition"/> </typeAliases> <!-- 配置运行环境 --> <environments default="development"> <environment id="development"> <!-- 配置 JDBC 事务管理器 --> <transactionManager type="JDBC"/> <!-- POOLED 配置 JDBC 数据源连接池 --> <dataSource type="POOLED"> <property name="driver" value="com.mysql.cj.jdbc.Driver"/> <property name="url" value="jdbc:mysql:///user?serverTimezone=Asia/Shanghai"/> <property name="username" value="root"/> <property name="password" value="root"/> </dataSource> </environment> </environments> <!-- 注册 UserMapper.xml --> <!-- 默认是classpath路径如果直接放在resource下就直接写UserMapper.xml即可--> <mappers> <mapper resource="com/boss/learning/mapper/UserMapper.xml"/> </mappers> </configuration>
-
-
调用Mybatis的api进行使用
//可以创建为一个工具类 @Slf4j public class MyBatisUtil { private MyBatisUtil() { } //获取sql会话工厂对象 private static final SqlSessionFactory sqlSessionFactory; static { //读入配置文件 String resource = "mybatis-config.xml"; Reader reader = null; try { reader = Resources.getResourceAsReader(resource); } catch (IOException e) { log.info(e.getMessage()); } //绑定配置文件 sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader); } public static SqlSessionFactory getSqlSessionFactory() { return sqlSessionFactory; } } 使用: SqlSessionFactory factory = MyBatisUtil.getSqlSessionFactory();//获取会话工厂 SqlSession sqlSession = factory.openSession(); //构建SqlSession UserMapper userMapper = sqlSession.getMapper(UserMapper.class);//绑定指定的mapper List<User> users = userMapper.selectByName(null);//使用方法 log.info("ths result is {} ",users.toString());
Mybatis使用过程存在的问题
1.配置繁琐,例如起别名和注册mapper的操作
2.使用过程代码冗余度高
spring整合思路分析
开发步骤
-
环境配置(整合需要使用的jar包)
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>5.2.8.RELEASE</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.20</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.1.21</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>2.0.5</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.4</version> <scope>compile</scope> </dependency>
-
配置文件的编写
<!--连接池--> <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"></property> <property name="url" value="jdbc:mysql///stu?serverTimezone=Asia/Shanghai""></property> <property name="username" value="root"></property> <property name="password" value="root"></property> </bean> <!--sqlSessionFactory sqlSessionFactoryBean--> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"></property> <property name="typeAliasesPackage" value="com.boss.entity"></property> <property name="mapperLocations" > <list> <!--这里的classpath指的是resource文件夹不包含java--> <value>classpath:mapper/*Mapper.xml</value> </list> </property> </bean> <!--创建DAO对象--> <bean id="scanner" class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property> <property name="basePackage" value="com.boss.dao"></property> </bean>
-
使用:
@Test public void test1(){ ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("/applicationContext.xml"); UserDAO userDAO = (UserDAO)ctx.getBean("userDAO");//直接通过Mapper的名字改下首字母为小写 User user = new User(); user.setName("skt"); user.setPassword("123456"); userDAO.save(user);
SpringMVC
1.搭建环境:
新建一个web工程的模块
2.导入相应的依赖jar包
<!-- jsp start-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>javax.servlet.jsp-api</artifactId>
<version>2.3.3</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<!-- jsp end-->
<!-- spring start-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.2.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.2.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>5.2.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>5.2.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>5.2.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>5.2.8.RELEASE</version>
</dependency>
<!-- spring end-->
<!--整合mybatis需要使用到的jar包-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.8.RELEASE</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.20</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.21</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.5</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.4</version>
<scope>compile</scope>
</dependency>
<!--end-->
spring整合MVC框架的思路
1.准备工厂
-
在web开发过程中如何创建工厂
ApplicationContext ctx = new ClassPathXMLApplicationContext("/applicationContext.xml");
WebXmlApplicationContext()
-
如何保证工厂唯一同时被共用
存在共用域当中:web当中的可存储域:request|session|ServletContext(application)
选择将工厂存储在SerletContext当中:ServletContext.setAttribute("xxxx",ctx);
保证唯一性:在ServletContext对象创建的同时---->ApplicationContext ctx = new ClassPathXMLApplicationContext("/applicationContext.xml");
-
spring封装了一个ContextLoaderListener//监听器,通过监听器监听ServletContext对象创建
ContextLoaderListener使用方式 web.xml当中进行配置 <listenner> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listenner> <context-param> <param-name>contextConfigLocation</param-name>//写死的 <param-value>classpath:applicationContext.xml</param-value> </context-param>spring多配置
spring多配置文件
spring注解编程
spring基础注解
-
对象创建的相关注解 @Component 默认的名字:更改首字母为小写 更改名字:@Component("u")//更改名字为u @Repostory//用于DAO层的注解,默认命名与更改名字方式与上相同 @Service//用于Service层 @Controller//用于Controller层 以上的三个注解本质上都是Component类型的,只是使用的对象更加精准化
-
@Lazy:用于在创建单例对象时候的懒初始化,在工厂创建时不进行该对象的创建,只有在这个对象被使用的时候才进行创建
-
有关对象生命周期的注解:
1.@PostConstruct:初始化方法的注解,意思就是在创建之后应该进行的方法
2.@Predestory:销毁方法的注解,在销毁之前进行的方法。
-
注入的自定义类型注解:@Autoware等注解参见课件中的javaweb的spring笔记
-
@Value:为属性赋值
注意:1.该注解不能应用在静态成员进行赋值,赋值将失败。
2.不能给集合类型的成员变量进行注入----->spring提供了新方式yml
-
@PropertySource:替换配置文件当中的
<context:property-placeholder location="classpath:/init.properties"></context:property-placeholder>
注解扫描策略
1.排除方式
2.包含方式
何时使用注解
@Componet--->bean
* 只有我们自己写的类才能够进行基本注解的使用,也就是你才有机会加上注解
* 对于外部提供的类例如:SqlSessionFactoryBean,MapperScannerCongigure等不适合进行注解配置
spring高级注解
- .配置Bean注解:@Configuration用于代替xml配置文件的功能
获取工厂方式:
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(Config.class);//此参数为配置类的class文件
//可以引入不止一个配置类(Config1.class,Config2.class)用逗号进行分隔开即可
//也可以使用重载方式,直接写配置类所在的包(com.xxx.xxx)
-
@Bean注解
默认的名字:就是方法名
更改名字:@Bean("新的id值")
控制对像的创建次数:
@Bean注解的注入:
1.自定义类型的注入
方式一: 在UserService当中注入自定义类型UserDao---->将待注入属性作为形参传入,方法内调用其set方法
方式二:在内部调用自定义的UserDao的创建方法
2.jdk类型的注入
直接在方法内部调用set方法,缺点:存在耦合
解决耦合的方法:利用properties文件+@Value注解进行赋值
-
@ComponetScan:定义要扫描的注解所在的包位置
basePackages="定义扫描的包及其子包"
扫描排除策略
扫描包含策略
配置优先级
优先级:bean标签>@bean>@component及其衍生注解
在id相同的情况下优先级高的方式会覆盖优先级低的方式,配置之间进行覆盖。
在利用配置类,同时辅助配置文件,在配置文件中去添加你想覆盖的旧的Bean
多配置Bean
目的:按照功能模块进行划分,有利于后续维护。
整合方式:
1.通过包扫描
2.通过@Import注解
将配置类2整合到配置类1 中
3.同时指定多个class文件
跨配置注入(可使用多种场景的方式)
纯注解版AOP编程
细节:
更改动态代理的创建方式:
@EnableAspectJAutoProxy(proxyTargetClass = true)
//spring 默认采用jdk动态代理实现
//spring-boot默认采用cglib动态代理实现
纯注解版Spring与Mybatis整合
//1.定义user类,并注册
@Data
@Component
public class User {
private int id;
private String name;
private String password;
}
//定义UserDao接口,并注册
@Repository
public interface UserDao {
public void save(User user);
}
//定义UserDaoMapper.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.boss.learning.dao.UserDao">
<insert id="save" parameterType="User">
insert into t_user(name,password) values(#{name},#{password})
</insert>
</mapper>
//定义配置类
@Configuration
@ComponentScan( basePackages="com.boss.learning")//定义注解扫描包
@MapperScan(basePackages = {"com.boss.learning.dao"})//定义mapper接口包
public class AppConfig {
//连接池对象
@Bean
public DataSource dataSource(){
DruidDataSource dataSource = new DruidDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost:3306/stu?serverTimezone=Asia/Shanghai");
dataSource.setUsername("root");
dataSource.setPassword("root");
return dataSource;
}
//SqlSessionFactoryBean对象
@Bean
public SqlSessionFactoryBean sqlSessionFactoryBean(){
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(dataSource());
sqlSessionFactoryBean.setTypeAliasesPackage("com.boss.learning.domain");
try {
PathMatchingResourcePatternResolver patternResolver = new PathMatchingResourcePatternResolver();
Resource[] resource = patternResolver.getResources("mapper/*Mapper.xml");
sqlSessionFactoryBean.setMapperLocations(resource);
} catch (IOException e) {
e.printStackTrace();
}
return sqlSessionFactoryBean;
}
}
//测试
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
User user = new User();
user.setName("skkkkkt");
user.setPassword("2222222");
UserDao userDao = (UserDao)applicationContext.getBean("userDao");
userDao.save(user);
}
spring框架中yml的使用
-
properties存在的问题:
1.无法表达集合或者数组等复杂对象。
2.没有办法指出数据与数据的类之间的关系
-
yml语法
1.文件定义方式 xxxx.yml xxx.yaml 2.基础语法 name: katy//注意key和value之间有一个空格 3.存在对象概念: account: id: 1 name: skt 4.定义集合 service: - 11111 - 00000 //多了一个横线
对于集合