学习依赖
导入依赖
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.6.RELEASE</version>
</dependency>
</dependencies>
- byName:会自动在容器上下文中查找,和自己对象set方法后面值对应的 beanid
- bytype:会自动在容器上下文中查找,和自己对象属性类型相同的bean
使用注解进行开发
开发之前需要引入头文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<context:annotation-config/>
有些是文件创建就自动生成的
@Autowired() 是按照类型自动装配的
@Resource()
- 如有指定的name属性,先按该属性进行byName方式查找装配
- 其次在进行默认的byName方式进行装配
- 如果以上都不成功,则按byType的方式自动装配
- 都不成功就报异常
属性注入
@Component("user")
public class User {
//相当于在配置文件中<property name="name" value="余浩"/>
@Value("余浩")
public String name;
如果提供了set方法,在set方法上添加@Valur("值")
@Component("user")
public class User {
public String name;
@Value("余浩")
public void setName(String name) {
this.name = name;
}
衍生注解
- @Controller:web层
- @Service:service层
- @Repository:dao层
它们功能都是一样的,写上这些注解,就是把这个类交给了Spring管理装配
xml和注解整合开发
- xml管理bean
- 注解完成属性注入
- context:annotation-config/
动态代理
核心:
- InvocationHandler 和 Proxy
public class ProxyInvocationHandler implements InvocationHandler {
private Rent rent;
public void setRent(Rent rent) {
this.rent = rent;
}
//生成代理类,获取要代理的抽象角色
public Object getProxy() {
return Proxy.newProxyInstance(this.getClass().getClassLoader(), rent.getClass().getInterfaces(), this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
log(method.getName());
Object result = method.invoke(rent, args);
return result;
}
public void log(String methodName) {
System.out.println("执行了" + methodName + "方法");
}
}
动态代理的好处:
- 公共的业务由代理来完成,实现了业务的分工
- 公共业务发生拓展时变得更加集中和方便
- 一个动态代理类可以代理多个类,代理的是接口
AOP切面编程
导入约束
<?xml version="1.0"encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd">
</beans>
实现aop切入
<!--注册bean-->
<bean id="userService"class="com.cqgs.service.UserServiceImpl"/>
<bean id="log"class="com.cqgs.log.Log"/>
<bean id="afterLog"class="com.cqgs.log.AfterLog"/>
<!--aop的配置-->
<aop:config>
<!--切入点 expression:表达式匹配要执行的方法-->
<aop:pointcut id="pointcut"expression="execution(* com.cqgs.service.UserServiceImpl.*(..))"/>
<!--执行环绕-->
<aop:advisor advice-ref="log"pointcut-ref="pointcut"/>
<aop:advisor advice-ref="afterLog"pointcut-ref="pointcut"/>
</aop:config>
自定义实现AOP
写入一个切入类
public class Diy {
public void before() {
System.out.println("方法执行前");
}
public void after() {
System.out.println("方法执行后");
}
}
配置
<!--注册bean-->
<bean id="userService"class="com.cqgs.service.UserServiceImpl"/>
<!--第二种自定义实现-->
<bean id="diy"class="com.cqgs.diy.Diy"/>
<aop:config>
<aop:aspect ref="diy">
<aop:pointcut id="diypointcut"expression="execution(* com.cqgs.service.UserServiceImpl.*(..))"/>
<aop:before pointcut-ref="diypointcut"method="before"/>
<aop:after pointcut-ref="diypointcut"method="after"/>
</aop:aspect>
</aop:config>
MyBatis整合
- 导入相关的jar包
junit
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13</version>
</dependency>
MyBatis
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.7</version>
</dependency>
mysql-connector-java
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.19</version>
</dependency>
spring相关
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.6.RELEASE</version>
</dependency>
mybatis-spring整合包
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.2</version>
</dependency>
ClassPathXmlApplicationContextBeans.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<context:annotation-config/>
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>
<properties resource="db.properties">
</properties>
<settings>
<setting name="mapUnderscoreToCamelCase" value="true"/>
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
<typeAliases>
<package name="com.cqgs.pojo"/>
</typeAliases>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="com/cqgs/dao/BlogMapper.xml"/>
</mappers>
</configuration>
log4j.properties
log4j.rootLogger=WARN, stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m%n
db.properties
driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/cqgs?characterEncoding=utf8&allowPublicKeyRetrieval=true&serverTimezone=UTC
username=root
password=root123
MyBatisUtils.java
public class MyBatisUtils {
private static SqlSessionFactory sqlSessionFactory;
static {
try {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
}
public static SqlSession getSqlSession() {
return sqlSessionFactory.openSession(true); //自动提交事务设置为true
}
}
<?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="">
</mapper>
配置静态资源过滤问题
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
</build>
spring-dao.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--配置数据源-->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
<property name="url"
value="jdbc:mysql://localhost:3306/cqgs?characterEncoding=utf8&allowPublicKeyRetrieval=true&serverTimezone=UTC"/>
<property name="username" value="root"/>
<property name="password" value="root123"/>
</bean>
<!--配置SqlSessionFactory-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<!--关联mybatis-->
<property name="configLocation" value="classpath:MyBatisConfig.xml"/>
<property name="mapperLocations" value="classpath:com/cqgs/dao/*.xml"/>
</bean>
<!--使用 SqlSessionFactory 作为构造方法的参数来创建 SqlSessionTemplate 对象。-->
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg index="0" ref="sqlSessionFactory"/>
</bean>
<!--声明事务-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<constructor-arg ref="dataSource" />
</bean>
<!--配置事务通知-->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="add" propagation="REQUIRED"/>
<tx:method name="delet" propagation="REQUIRED"/>
<tx:method name="update" propagation="REQUIRED"/>
<tx:method name="serach" propagation="REQUIRED"/>
<tx:method name="get" read-only="true"/>
<tx:method name="*" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
<!--配置事务的切入点-->
<aop:config>
<aop:pointcut id="txPointCut" expression="execution(* com.cqgs.dao.*.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut"/>
</aop:config>
</beans>
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<import resource="spring-dao.xml"/>
<!--注册bean实现-->
<bean id="userMapper" class="com.cqgs.dao.UserMapperImpl">
<property name="sqlSession" ref="sqlSession"/>
</bean>
</beans>
最后的mybatisConfig.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"/>-->
<!-- <setting name="logImpl" value="STDOUT_LOGGING"/>-->
<!-- </settings>-->
<typeAliases>
<package name="com.cqgs.pojo"/>
</typeAliases>
</configuration>
public class UserMapperImpl implements UserMapper {
private SqlSessionTemplate sqlSession;
public void setSqlSession(SqlSessionTemplate sqlSession) {
this.sqlSession = sqlSession;
}
@Override
public List<User> selectUser() {
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
return mapper.selectUser();
}
}
//第二种方式
public class UserServiceImpl2 extends SqlSessionDaoSupport implements UserMapper {
@Override
public List<User> selectUser() {
return getSqlSession().getMapper(UserMapper.class).selectUser();
}
}
为什么要配置事务:
- 如果不配置,就需要手动提交控制事务
- 设计到数据一致性问题,不容马虎!