玄子Share - spring-framework 6.0.9 学习笔记
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UA2E1zOO-1684946000258)(./assets/spring.jpg)]
官网
官网 https://spring.io/
参考文档 https://docs.spring.io/spring-framework/reference/core/beans/factory-scopes.html
API 文档 https://docs.spring.io/spring-framework/docs/current/javadoc-api/
Maven
Spring Maven 地址 https://mvnrepository.com/artifact/org.springframework/spring-webmvc
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>6.0.9</version>
</dependency>
运行环境
-
JDK:Java17+(Spring6 要求JDK最低版本是 Java17 需要配置好环境变量)
-
Maven:3.9+
-
Spring:6.0.9
-
开发工具:IDEA 2023.1
IOC
ioc 是 Spring 的核心,控制反转,即为把实际调用权限交给用户
package com.xuanzi;
import com.xuanzi.dao.impl.UserDaoImplMySQL;
import com.xuanzi.dao.impl.UserDaoImplSqlServer;
import com.xuanzi.services.UserService;
import com.xuanzi.services.impl.UserServiceImpl;
public class Main {
public static void main(String[] args) {
UserServiceImpl userService = new UserServiceImpl();
userService.setUserDao(new UserDaoImplMySQL());
userService.setUserDao(new UserDaoImplSqlServer());
userService.selectUser();
}
}
package com.xuanzi.services.impl;
import com.xuanzi.dao.UserDao;
import com.xuanzi.entity.User;
import com.xuanzi.services.UserService;
import java.util.List;
public class UserServiceImpl implements UserService {
// UserDao daoImplMySQL = new UserDaoImplMySQL();
// UserDao daoImplSqlServer = new UserDaoImplSqlServer();
// 不再使用传统的 方法 固定实现,而是通过 set 方法 把这个权限交给用户
UserDao userDao;
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
@Override
public List<User> selectUser() {
return userDao.selectUserInfo();
}
}
beans.xml
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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
</beans>
IDEA 可以直接右键新建 XML配置文件 ==> Spring 配置 可以直接生成 Spring 专属 xml 文件
alias 别名
<bean id="user" class="com.xuanzi.spring.User"/>
<alias name="user" alias="user2"/>
<!--类别名-->
- name:对应类 ID
- alias:别名
import 导入
<import resource="beans.xml"/>
- import:导入外部 xml
- resource:文件名
bean 对象创建
基础 User 类(带有,封装,构造)
package com.xuanzi.spring;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
String name;
}
package com.xuanzi.spring;
import org.junit.jupiter.api.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestUser {
@Test
public void testUser() {
ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");
// xml 的文件名
User user = ac.getBean("user", User.class);
// getBean 类名称,即 id 的名称 User.class 类的类型
System.out.println(user);
}
}
<?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="user" class="com.xuanzi.spring.User"/>
</beans>
- bean:实例类
- id:类名称(变量名)
- class:类文件的全限定位置
有参构造
package com.xuanzi.spring;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
String name;
public User(String name) {
this.name = name;
}
}
<bean id="user" class="com.xuanzi.spring.User">
<constructor-arg index="0" value="玄子"/>
<!-- 下标赋值 -->
<constructor-arg type="java.lang.String" value="玄子"/>
<!-- 类型赋值 -->
<constructor-arg name="name" value="玄子"/>
<!-- 直接通过参数名赋值 -->
</bean>
- constructor-arg:构造函数参数
- index:参数下标(从0开始)
- value:参数值
- type:参数类型
- name:参数名称
name 别名
在 bean 标签内可以直接使用 name 属性指定别名
<bean id="user" class="com.xuanzi.spring.User" name="user2,user3"/>
- name:类的别名(可以有多个别名,使用空格或者
,
分隔)
P / C 命名空间
在 beans 标签内插入下方两条属性
xmlns:p="http://www.springframework.org/schema/p"
xmlns:c="http://www.springframework.org/schema/c"
使用 IDEA 打出
xmlns:p=""
会带有提示
<?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:p="http://www.springframework.org/schema/p"
xmlns:c="http://www.springframework.org/schema/c"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="user2" class="com.xuanzi.spring.User" p:name="玄子"/>
<!-- p:命名空间:属性-->
<bean id="user3" class="com.xuanzi.spring.User" c:name="玄子"/>
<!-- c:命名空间:构造器-->
</beans>
- xmlns:p:属性的语法规范(property)
- xmlns:c:构造器的语法规范(constructor)
- p: :属性名称是name 直接设置值
- c: :构造参数是name 直接设置值
依赖注入
set 方法注入
不论是,类或是属性都需要依赖于 set 方法进行注入,所以要提前写好 get 和 set 方法
接下来都使用这个 User 类演示(这里使用了lombok)三个注解包含了,有参构造,无参构造,以及所有属性的 get 和 set 方法
package com.xuanzi.spring;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private String name;
private String wife;
private Address address;
private String[] books;
private List<String> hobbies;
private Set<String> games;
private Map<String, String> cards;
private Properties info;
public User(String name) {
this.name = name;
}
}
package com.xuanzi.spring;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Address {
String address;
}
<bean id="user" class="com.xuanzi.spring.User"></beans>
基本数据类型
<property name="name" value="玄子"/>
- name:属性名称
- value:属性值
引用数据类型
User 类中的 Address 是别的类属性引用类型
<bean id="address" class="com.xuanzi.spring.Address">
<property name="address" value="漯河"/>
</bean>
<property name="address" ref="address"/>
- name:属性名
- ref:引用数据类型
- 这里 ref 的值即为 Address 类 bean 的 id 值
array
<property name="books">
<array>
<value>红楼梦</value>
<value>三国演义</value>
<value>水浒传</value>
</array>
</property>
- array:数组类型
- value:属性值
- 顺序即为下标
list
<property name="hobbies">
<list>
<value>唱</value>
<value>跳</value>
<value>rap</value>
<value>篮球</value>
</list>
</property>
- list:集合类型
- value:属性值
- 顺序即为下标
map
<property name="cards">
<map>
<entry key="身份证" value="23131323141"/>
<entry key="手机号" value="5453453454"/>
<entry key="学号" value="534534634634"/>
</map>
</property>
- map:类型
- entry:键值对
- key:键
- value:值
set
<property name="games">
<set>
<value>aa</value>
<value>bb</value>
<value>cc</value>
<value>dd</value>
</set>
</property>
- set:set 集合
- value:值
null
属性值为空
<property name="wife" value=""/>
<property name="wife">
<null/>
</property>
- 可直接设置 value 为
""
表示字符串的空值 - 如果表示为 null 可直接使用
<null/>
标签
props
配置 可有多个 类似于 map
<property name="info">
<props>
<prop key="身高">180</prop>
<prop key="体重">130</prop>
</props>
</property>
- props:配置表示多个
- prop:单个配置
- key:键
- 值写在标签里面
这个属于特殊类型 类似于 Mybatis 连接数据的 property 配置
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
bean 作用域
范围 | 描述 |
---|---|
singleton | (默认)对于每个 Spring IoC 容器,将单个 bean 定义限定为单个对象实例。 |
prototype | 将单个 bean 定义的范围限定为任意数量的对象实例。 |
request | 将单个 bean 定义的范围限定为单个 HTTP 请求的生命周期。也就是说,每个 HTTP 请求都有自己的 bean 实例,该实例是在单个 bean 定义的基础上创建的。仅在 web 感知Spring 的上下文中有效。ApplicationContext |
session | 将单个 bean 定义的范围限定为 HTTP 的生命周期。仅在 web 感知 Spring 的上下文中有效。Session ApplicationContext |
applicatio | 将单个 bean 定义的范围限定为的生命周期。仅在支持 web 的 Spring 的上下文中有效。ServletContext ApplicationContext |
nwebsocket | 将单个 bean 定义的范围限定为的生命周期。仅在支持 web 的 Spring 的上下文中有效。WebSocket ApplicationContext |
单例模式
不管创建几个对象始终指向一个对象
<bean id="user" class="com.xuanzi.spring.User" p:name="玄子"/>
- 默认即为 单例模式
原型模式
每次创建对象,都会产生一个新的对象
<bean id="user" class="com.xuanzi.spring.User" p:name="玄子" scope="prototype"/>
<!-- 原型模式 -->
- scope:范围
- prototype:原型模式
其他
其他的 request,session,applicatio,nwebsocket 这些只能在 web 开发中使用
自动装配
package com.xuanzi.spring;
import org.junit.jupiter.api.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestUser {
@Test
public void testUser() {
ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");
User user = ac.getBean("user", User.class);
// User user2 = ac.getBean("user3", User.class);
// System.out.println(user.hashCode());
// System.out.println(user2.hashCode());
// System.out.println(user==user2);
user.getXiaoHong().say();
user.getXiaoMing().say();
}
}
package com.xuanzi.spring;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
String name;
XiaoHong xiaoHong;
XiaoMing xiaoMing;
public User(String name) {
this.name = name;
}
}
package com.xuanzi.spring;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class XiaoHong {
String name;
public void say() {
System.out.println(this.name + ":说话了");
}
}
package com.xuanzi.spring;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class XiaoMing {
String name;
public void say() {
System.out.println(this.name + ":说话了");
}
}
<?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:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="user" class="com.xuanzi.spring.User" autowire="byType">
<property name="name" value="人"/>
<!-- <property name="xiaoHong" ref="xiaoHong"/>-->
<!-- <property name="xiaoMing" ref="xiaoMing"/>-->
</bean>
<bean id="xiaoHong" class="com.xuanzi.spring.XiaoHong" p:name="小红"/>
<bean id="xiaoMing" class="com.xuanzi.spring.XiaoMing" p:name="小明"/>
</beans>
- autowire:自动装配
- byType:需要保证所有的 bean 的 class 唯一,并且这个 bean 需要和自动注入的属性类型一致
- byName:需要保证所有的 bean 的 id 唯一,并且这个 bean 需要和自动注入的属性的 set 方法值一致
注解自动装配
需要提前引入,命名空间与约束
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/context"
xsi:schemaLocation="https://www.springframework.org/schema/context/spring-context.xsd"
<context:annotation-config/>
IDEA 可以只打最后面的标签 会自动补全命名空间
<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/>
</beans>
package com.xuanzi.spring;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
String name;
@Autowired
@Qualifier("xiaoHong2")
XiaoHong xiaoHong;
@Autowired(required = false)
XiaoMing xiaoMing;
public User(String name) {
this.name = name;
}
}
- @Autowired:使用这个注解 可忽略 set 方法
- 当注入在IoC容器中该类型只有一个时,就通过byType进行装配
- 当注入容器存在多个同一类型的对象时,就是根据byName进行装配
- @Qualifier( ):相当于预设指定唯一 bean id,里面填写对应 bean id
- @Nullable:属性可为 null
- @Autowired(required = false):与 @Nullable 一样允许属性为 null
public @interface Autowired {
boolean required() default true;
}
使用注解开发
同样需要引入 命名空间与约束
<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/>
</beans>
<context:component-scan base-package="com.xuanzi.entity"/>
<!-- 扫描包下的所有类(组件),生效注解
package com.xuanzi.entity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Component
public class User {
@Value("玄子")
String name;
}
- @Component:组件(生效配置)等于 bean 标签
- @Value( ):属性值,等于 property 标签 set 方法上的 value 高于属性
衍生注解
@Component 有几个衍生注解,我们在web开发中,会按照mvc三层架构分层!
- dao【@Repository】
- service【@Service】
- controller【@Controller】
这四个注解功能都是一样的,都是代表将某个类注册到Spring中,装配 Bean
作用域注解
@Scope("singleton")
public class User {
@Value("玄子")
String name;
}
- @Scope:作用域,prototype 原型模式
xml与注解:
- xml更加万能,适用于任何场合!维护简单方便。
- 注解不是自己类使用不了,维护相对复杂!
xml 与注解最佳实践:
- xml用来管理bean;
- 注解只负责完成属性的注入;
- 我们在使用的过程中,只需要注意一个问题:必须让注解生效,就需要开启注解的支持
使用 java 配置 Spring
package com.xuanzi.config;
import com.xuanzi.entity.User;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
@Configuration
// 被注册到 Spring 容器中 @Component 本身就是一个 组件
@ComponentScan("com.xuanzi.entity")
// 扫描包
@Import(BeanConfig2.class)
// 导入其他 配置文件
public class BeanConfig {
// 相当于 bean 标签 方法名相当于 id 返回值相当于 class
public User user() {
return new User();
}
}
- @Configuration:表示当前类为配置文件;相当于
beans.xml
- @ComponentScan(“com.xuanzi.entity”):扫描包下的类,生效注解;相当于
<context:component-scan base-package="com.xuanzi.entity"/>
- @Import(BeanConfig2.class):导入其他配置文件;相当于
<import resource="applicationContext.xml"/>
- @Bean:表示当前类被注册到 Spring 容器中;相当于
<bean class="com.xuanzi.entity.User" id="user"/>
- 方法名相当于 id
- 返回值相当于 class
代理模式
静态代理
package com.xuanzi.spring;
public interface Rent {
// 租房接口
void rent();
}
package com.xuanzi.spring;
public class Host implements Rent {
@Override
public void rent() {
System.out.println("房东租房子");
}
// 房东 被代理
}
package com.xuanzi.spring;
public class Proxy implements Rent {
// 代理 中介
Host host;
public Proxy(Host host) {
this.host = host;
}
public Proxy() {
}
@Override
public void rent() {
setHouse();
host.rent();
heTong();
}
public void setHouse() {
System.out.println("看房子");
}
public void heTong() {
System.out.println("签合同");
}
}
package com.xuanzi;
import com.xuanzi.spring.Host;
import com.xuanzi.spring.Proxy;
public class Main {
public static void main(String[] args) {
Host host = new Host();
// host.rent();
Proxy proxy = new Proxy(host);
proxy.rent();
}
}
- 接口
- 真实角色
- 代理角色
- 客户端访问代理角色
动态代理
package com.xuanzi.xuanzi_2;
public interface Rent {
// 租房接口
void rent();
}
package com.xuanzi.xuanzi_2;
public class Client {
// 客户
public static void main(String[] args) {
Host host = new Host();
// 真实角色
ProxyInvocationHandler proxy = new ProxyInvocationHandler();
// 代理角色现在没有
proxy.setRent(host);
// 设置代理角色
Rent proxy1 = (Rent) proxy.getProxy();
// 动态生成
proxy1.rent();
}
}
package com.xuanzi.xuanzi_2;
public class Host implements Rent {
@Override
public void rent() {
System.out.println("房东租房子");
}
// 房东 被代理
}
package com.xuanzi.xuanzi_2;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class ProxyInvocationHandler implements InvocationHandler {
// 实现 代理调用处理器
Rent rent;
//被代理的接口
public Object getProxy() {
return Proxy.newProxyInstance(this.getClass().getClassLoader(), rent.getClass().getInterfaces(), this);
}
// 生成得到代理类
public void setRent(Rent rent) {
this.rent = rent;
}
// set 传参
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
seehouse();
return method.invoke(rent, args);
}
// 生成代理示例 返回结果
public void seehouse() {
System.out.println("中介带看房子");
}
}
package com.xuanzi.xuanzi_2;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class ProxyTemplate implements InvocationHandler {
// 实现 调用 代理处理器
Object target;
//被代理的接口
public Object getProxy() {
return Proxy.newProxyInstance(this.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
// 生成得到代理类
}
public void setRent(Object target) {
this.target = target;
// set 传参
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
return method.invoke(target, args);
// 生成代理示例 返回结果
}
}
AOP
里面用的命名空间都可以使用 IDEA 自动导入
方式一
package com.xuanzi.service;
public class UserServiceImpl implements UserService{
@Override
public void addUser() {
System.out.println("执行添加");
}
@Override
public void delUser() {
System.out.println("执行删除");
}
@Override
public void updUser() {
System.out.println("执行修改");
}
@Override
public void selUser() {
System.out.println("执行查询");
}
}
package com.xuanzi;
import org.springframework.aop.AfterReturningAdvice;
import java.lang.reflect.Method;
public class LogAfter implements AfterReturningAdvice {
@Override
public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
System.out.println(target.getClass().getName() + "的" + method.getName() + "被执行了,返回了" + returnValue);
}
}
package com.xuanzi;
import org.springframework.aop.MethodBeforeAdvice;
import java.lang.reflect.Method;
public class LogBefore implements MethodBeforeAdvice {
@Override
public void before(Method method, Object[] args, Object target) throws Throwable {
System.out.println(target.getClass().getName() + "的" + method.getName() + "被执行了");
}
}
<bean class="com.xuanzi.service.UserServiceImpl" id="service"/>
<bean class="com.xuanzi.LogBefore" id="logBefore"/>
<bean class="com.xuanzi.LogAfter" id="logAfter"/>
<aop:config>
<aop:pointcut id="pointcut" expression="execution(* com.xuanzi.service.UserServiceImpl.*(..))"/>
<aop:advisor advice-ref="logAfter" pointcut-ref="pointcut"/>
<aop:advisor advice-ref="logBefore" pointcut-ref="pointcut"/>
</aop:config>
方式二
package com.xuanzi;
public class LogDiy {
public void before(){
System.out.println("方法执行前");
}
public void after(){
System.out.println("方法执行后");
}
}
<bean class="com.xuanzi.LogDiy" id="logCustom"/>
<aop:config>
<aop:aspect ref="logCustom">
<aop:pointcut id="pointcut" expression="execution(* com.xuanzi.service.UserServiceImpl.*(..))"/>
<aop:after method="after" pointcut-ref="pointcut"/>
<aop:before method="before" pointcut-ref="pointcut"/>
</aop:aspect>
</aop:config>
注解
package com.xuanzi;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
@Aspect
public class LogAnnotate {
@Before("execution(* com.xuanzi.service.UserServiceImpl.*(..))")
public void before() {
System.out.println("方法执行前");
}
@After("execution(* com.xuanzi.service.UserServiceImpl.*(..))")
public void after() {
System.out.println("方法执行后");
}
@Around("execution(* com.xuanzi.service.UserServiceImpl.*(..))")
public void around(ProceedingJoinPoint point) throws Throwable {
System.out.println("环绕前");
Object proceed = point.proceed();
Signature signature = point.getSignature();
System.out.println(signature);
System.out.println("环绕后");
}
}
<bean class="com.xuanzi.LogAnnotate" id="logAnnotate"/>
<aop:aspectj-autoproxy/>
整合 Mybatis
依赖
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.26</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>6.0.9</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.10.0-M1</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.13</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.33</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.20.0</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.20.0</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.19</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>3.0.2</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>6.0.9</version>
</dependency>
</dependencies>
方式一
package com.xuanzi.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.apache.ibatis.type.Alias;
@Alias("patient")
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Patient {
private int patientId;
private String password;
private String birthDate;
private String gender;
private String patientName;
private String phoneNum;
private String email;
private String identityNum;
private String address;
}
package com.xuanzi.mapper;
import com.xuanzi.entity.Patient;
import java.util.List;
public interface PatientMapper {
List<Patient> selectpatient();
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xuanzi.mapper.PatientMapper">
<select id="selectpatient" resultType="patient">
select *
from hospital.patient;
</select>
</mapper>
package com.xuanzi.mapper;
import com.xuanzi.entity.Patient;
import org.mybatis.spring.SqlSessionTemplate;
import java.util.List;
public class PatientMapperImpl implements PatientMapper {
SqlSessionTemplate sqlSessionTemplate;
public void setSqlSessionTemplate(SqlSessionTemplate sqlSessionTemplate) {
this.sqlSessionTemplate = sqlSessionTemplate;
}
@Override
public List<Patient> selectpatient() {
PatientMapper patientMapper = sqlSessionTemplate.getMapper(PatientMapper.class);
return patientMapper.selectpatient();
}
}
<?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-mapper.xml"/>
<bean id="patientManager" class="com.xuanzi.mapper.PatientMapperImpl">
<property name="sqlSessionTemplate" ref="sqlSessionTemplate"/>
</bean>
</beans>
dataSource=org.springframework.jdbc.datasource.DriverManagerDataSource
driverClassName=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/hospital?useUnicode=TRUE&characterEncoding=UTF-8&serverTimezone=GMT-8
username=root
password=root
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<typeAliases>
<package name="com.xuanzi.entity"/>
</typeAliases>
</configuration>
<?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 http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<context:property-placeholder location="classpath:database.properties"/>
<!-- DataSource-->
<bean id="dataSource" class="${dataSource}">
<property name="driverClassName" value="${driverClassName}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</bean>
<!-- sqlsessionFactory-->
<bean id="sqlsessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<!-- 绑定 Mybatis 配置文件-->
<property name="configLocation" value="classpath:mybatis-config.xml"/>
<property name="mapperLocations" value="classpath:com/xuanzi/mapper/*.xml"/>
</bean>
<!-- sqlSessionTemplate-->
<bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg name="sqlSessionFactory" ref="sqlsessionFactory"/>
</bean>
</beans>
import com.xuanzi.entity.Patient;
import com.xuanzi.mapper.PatientMapper;
import com.xuanzi.mapper.PatientMapperImpl;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.util.List;
public class Main {
public static void main(String[] args) {
// SqlSession sqlSession = MybatisUtil.getSqlSession();
// PatientMapper patientMapper = sqlSession.getMapper(PatientMapper.class);
// for (Patient patient : patientMapper.selectpatient()) {
// System.out.println(patient);
// }
// sqlSession.close();
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
PatientMapper patientMapper = context.getBean("patientManager", PatientMapper.class);
List<Patient> selectpatient = patientMapper.selectpatient();
for (Patient patient : selectpatient) {
System.out.println(patient);
}
}
}
方式二
package com.xuanzi.mapper;
import com.xuanzi.entity.Patient;
import org.apache.ibatis.session.SqlSession;
import org.mybatis.spring.support.SqlSessionDaoSupport;
import java.util.List;
public class PatientMapperImpl2 extends SqlSessionDaoSupport implements PatientMapper {
@Override
public List<Patient> selectpatient() {
SqlSession sqlSession = getSqlSession();
PatientMapper patientMapper = sqlSession.getMapper(PatientMapper.class);
return patientMapper.selectpatient();
}
}
<?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-mapper.xml"/>
<bean id="patientManager2" class="com.xuanzi.mapper.PatientMapperImpl2">
<property name="sqlSessionFactory" ref="sqlsessionFactory"/>
</bean>
</beans>
import com.xuanzi.entity.Patient;
import com.xuanzi.mapper.PatientMapper;
import com.xuanzi.mapper.PatientMapperImpl;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.util.List;
public class Main {
public static void main(String[] args) {
// SqlSession sqlSession = MybatisUtil.getSqlSession();
// PatientMapper patientMapper = sqlSession.getMapper(PatientMapper.class);
// for (Patient patient : patientMapper.selectpatient()) {
// System.out.println(patient);
// }
// sqlSession.close();
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
PatientMapper patientMapper = context.getBean("patientManager", PatientMapper.class);
List<Patient> selectpatient = patientMapper.selectpatient();
for (Patient patient : selectpatient) {
System.out.println(patient);
}
}
}import com.xuanzi.entity.Patient;
import com.xuanzi.mapper.PatientMapper;
import com.xuanzi.mapper.PatientMapperImpl;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.util.List;
public class Main {
public static void main(String[] args) {
// SqlSession sqlSession = MybatisUtil.getSqlSession();
// PatientMapper patientMapper = sqlSession.getMapper(PatientMapper.class);
// for (Patient patient : patientMapper.selectpatient()) {
// System.out.println(patient);
// }
// sqlSession.close();
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
PatientMapper patientMapper = context.getBean("patientManager2", PatientMapper.class);
List<Patient> selectpatient = patientMapper.selectpatient();
for (Patient patient : selectpatient) {
System.out.println(patient);
}
}
}
声明式事务
里面用的命名空间都可以使用 IDEA 自动导入
<!-- 配置声明式事务-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<constructor-arg name="dataSource" ref="dataSource"/>
</bean>
<!-- 结合AOP实现事务织入-->
<tx:advice id="advice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="selectpatient" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
<!-- 设置切入-->
<aop:config>
<aop:pointcut id="po" expression="execution(* com.xuanzi.mapper..*.*(..))"/>
<aop:advisor advice-ref="advice" pointcut-ref="po"/>
</aop:config>
package com.xuanzi.mapper;
import com.xuanzi.entity.Patient;
import com.xuanzi.entity.Test;
import java.util.List;
public interface PatientMapper {
List<Patient> selectpatient();
int insertTest(Test test);
int deleteTestByTestId(int testId);
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xuanzi.mapper.PatientMapper">
<insert id="insertTest" parameterType="test">
insert into hospital.test (val)
values (#{val})
</insert>
<delete id="deleteTestByTestId" parameterType="int">
delete
from hospital.test
where TestID = #{testID}
</delete>
<select id="selectpatient" resultType="patient">
select *
from hospital.patient;
</select>
</mapper>
package com.xuanzi.mapper;
import com.xuanzi.entity.Patient;
import com.xuanzi.entity.Test;
import org.apache.ibatis.session.SqlSession;
import org.mybatis.spring.support.SqlSessionDaoSupport;
import java.util.List;
public class PatientMapperImpl2 extends SqlSessionDaoSupport implements PatientMapper {
@Override
public List<Patient> selectpatient() {
SqlSession sqlSession = getSqlSession();
Test test = new Test("233");
int i = 2;
insertTest(test);
deleteTestByTestId(i);
PatientMapper patientMapper = sqlSession.getMapper(PatientMapper.class);
return patientMapper.selectpatient();
}
@Override
public int insertTest(Test test) {
return getSqlSession().getMapper(PatientMapper.class).insertTest(test);
}
@Override
public int deleteTestByTestId(int testId) {
return getSqlSession().getMapper(PatientMapper.class).deleteTestByTestId(testId);
}
}