Mybatis和Spring整合高级系列知识学习之手动@Bean2
1概述
我们知道MyBatis的Mapper Bean注入是通过MapperFactoryBean完成的,xml配置的方式如下:
Xml的方式:
<!--1.单个bean注入-->
<bean id="userMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
<property name="mapperInterface" value="com.kikop.mybatisaspring.mapper.UsersMapper"></property>
</bean>
本节来模仿MapperFactoryBeann方式手动实现,将动态代理创建的Bean对象交给spring容器管理。
2 单个Bean注入(手动@Bean)
2.1 config
package com.kikop.myspringstudy.mybatislinkspring2.config;
import com.kikop.myspringstudy.mycommon.mapper.UsersMapper;
import com.kikop.myspringstudy.mycommon.sqlsession.MySqlSession;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import javax.sql.DataSource;
/**
* @author kikop
* @version 1.0
* @project Name: javawebinaction
* @file Name: AppConfig
* @desc 功能描述
* @date 2020/6/22
* @time 8:43
* @by IDE: IntelliJ IDEA
*/
@Configuration
// service、bean、controller 把类交给 spring管理
@ComponentScan("com.kikop.myspringstudy.mybatislinkspring2")
public class AppConfig {
@Bean
public DataSource dataSource() {
// 基于 Spring-jdbc
DriverManagerDataSource drivermanagerDataSource = new DriverManagerDataSource();
drivermanagerDataSource.setDriverClassName("com.mysql.jdbc.Driver");
drivermanagerDataSource.setUrl("jdbc:mysql://localhost:3306/mybatis?userUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true");
drivermanagerDataSource.setUsername("root");
drivermanagerDataSource.setPassword("123456");
return drivermanagerDataSource;
}
@Bean
public SqlSessionFactoryBean sqlSessionFactoryBean(DataSource dataSource) {
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(dataSource);
return sqlSessionFactoryBean;
}
/**
* 将动态创建的类交给spring管理
*
* @return
*/
@Bean
public UsersMapper usersMapper() {
UsersMapper usersMapper = (UsersMapper) MySqlSession.getMapper(UsersMapper.class);
return usersMapper;
}
}
2.2 service
package com.kikop.myspringstudy.mybatislinkspring1.service;
import com.kikop.myspringstudy.mycommon.mapper.UsersMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
/**
* @author kikop
* @version 1.0
* @project Name: javawebinaction
* @file Name: UsersService
* @desc 功能描述
* @date 2020/6/22
* @time 9:16
* @by IDE: IntelliJ IDEA
*/
@Service // appconfig 就可以扫描到
public class UsersService {
/**
* 这里注入是关键
*/
@Autowired
UsersMapper usersMapper;
public List<Map<String, Object>> list() {
return usersMapper.list();
}
}
2.3 test
package com.kikop.myspringstudy.mybatislinkspring2.test;
import com.kikop.myspringstudy.mybatislinkspring2.config.AppConfig;
import com.kikop.myspringstudy.mybatislinkspring2.service.UsersService;
import com.kikop.myspringstudy.mycommon.mapper.UsersMapper;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
/**
* @author kikop
* @version 1.0
* @project Name: javawebinaction
* @file Name: UsersServiceTest
* @desc 功能描述
* @date 2020/6/22
* @time 9:17
* @by IDE: IntelliJ IDEA
*/
public class BeanToSpringByAtBeanTest {
/**
* 借用 mybatis内置功能 进行动态代理Mapper的创建
*/
public static void createProxyMapperClsTest() {
// 1.初始化spring容器(通过AppConfig进行 依赖注入、对象创建、service\bean\controller注解的扫描
// 类似web.xml中配置的ContextLoaderListener
AnnotationConfigApplicationContext annotationConfigWebApplicationContext =
new AnnotationConfigApplicationContext(AppConfig.class);
// AppConfig必须开始:
// mybatis
// @MapperScan("com.kikop.myspringstudy.mybatislinkspring1.mapper")
System.out.println("--------------by bean----------------");
System.out.println(annotationConfigWebApplicationContext.getBean(UsersMapper.class).list());
System.out.println("--------------by service----------------");
System.out.println(annotationConfigWebApplicationContext.getBean(UsersService.class).list());
}
public static void main(String[] args) {
createProxyMapperClsTest();
}
}
3框架说明
3.1 项目依赖
Spring core:
Spring-context、spring-webmvc
Spring自带连接池:
Spring-JDBC(对标:c3p0 druid(德鲁伊)
Mybatis core :
Mybatis(v3.5.0)
Spring-mybatis 插件包
Mybatis-spring(v2.0.0)
mysql-connector-java v6.0.6驱动
![](https://img.haomeiwen.com/i13945242/ec3a6a6ab17b1c6c.png)
图 1 公共部分
3.2 Users
package com.kikop.myspringstudy.mycommon.model;
/**
* @author kikop
* @version 1.0
* @project Name: mybatis
* @file Name: User
* @desc 功能描述
* @date 2020/6/21
* @time 16:41
* @by IDE: IntelliJ IDEA
*/
public class Users {
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getRemark() {
return remark;
}
public void setRemark(String remark) {
this.remark = remark;
}
private int id;
private String name;
private int age;
private String remark;
}
3.3 UsersMapper
package com.kikop.myspringstudy.mycommon.mapper;
import org.apache.ibatis.annotations.Select;
import java.util.List;
import java.util.Map;
/**
* @author kikop
* @version 1.0
* @project Name: mybatis
* @file Name: UserMapper(IUserDao)
* @desc 功能描述
* @date 2020/6/21
* @time 16:40
* @by IDE: IntelliJ IDEA
*/
public interface UsersMapper {
@Select("select * from users")
public List<Map<String, Object>> list();
}
3.4 MyInvocationHandler
package com.kikop.myspringstudy.mycommon.handler;
import org.apache.ibatis.annotations.Select;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
/**
* @author kikop
* @version 1.0
* @project Name: javawebinaction
* @file Name: MyInvocationHandler
* @desc 功能描述
* @date 2020/6/22
* @time 10:03
* @by IDE: IntelliJ IDEA
*/
public class MyInvocationHandler implements InvocationHandler {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (Object.class.equals(method.getDeclaringClass())) {
return method.invoke(this, args);
} else {
Select selectAnnotation = method.getAnnotation(Select.class);
if (selectAnnotation != null) {
String strSql = selectAnnotation.value()[0];
// 模拟执行 jdbc 数据查询,并返回数据
System.out.println(strSql);
if (method.getName().equals("toString")) {
// proxy.getClass()--> userMapper,返回被代理类的名称
return proxy.getClass().getInterfaces()[0].getName();
}
}
return null;
}
}
}
3.5 MySqlSession
package com.kikop.myspringstudy.mycommon.sqlsession;
import com.kikop.myspringstudy.mycommon.handler.MyInvocationHandler;
import java.lang.reflect.Proxy;
/**
* @author kikop
* @version 1.0
* @project Name: javawebinaction
* @file Name: MySqlSession
* @desc 功能描述 模拟Mapper接口代理类的创建
* @date 2020/6/22
* @time 9:57
* @by IDE: IntelliJ IDEA
*/
public class MySqlSession {
/**
* 模拟Mapper接口代理类的创建
*
* @return
*/
public static Object getMapper(Class<?> clazz) {
// 第1个参数:AppClassLoader
// 第2个参数:数组,因为java单继承,多实现,所以要定义为数组
// 第3个参数:invaocationHandler
Class<?> classArray[]=new Class<?>[]{clazz};
Object proxy = Proxy.newProxyInstance(MySqlSession.class.getClassLoader(),classArray,
new MyInvocationHandler());
return proxy;
}
}
网友评论