Mybatis整合Spring与Spingboot的整合--个人笔记

@ConfigurationProperties

ConfigurationProperties(prefix="nxj")

ignoreInvalidFields

@Value

@Value("${person.name}")
@Value("#{11*2+1}")
@Value("你好")
@Value("true")
@ConfigurationProperties @Value
松散绑定 支持 不支持
全部赋值 支持 不支持(只能一个个赋值)
JSR303 支持 不支持
SPLE 不支持 支持

@ImportResource

@ImportResource(value={"classpath:applicationContext.xml"})

导入Spring的配置文件,让其生效

还有一些注解比如说@Configuration,@Bean等等等等,这些在Spring注解版中都很清楚了,这里就不需要再记录出来了。

配置文件中:

在application.yml或者properties中直接使用${}取值,`name: ${person.name1:hello} `意思就是如果能取到person.name1则取,否则赋值为hello【就是hello字符串】

Profiles

多环境之间需要切换的时候
	1.使用application-xxx.properties
	2.直接在application.yml中使用 '---' 多文档块分割
	
	
使用 spring.profiles.active=dev 进行切换
spring:
  profiles:
    active: dev
#最上面文档快指定激活那个哪个文档块
server:
  port: 8081
---
spring:
  config:
    activate:
      on-profile: dev
server:
  port: 8082

🐾自动配置原理

起源:

@SpringBootApplication
	@EnableAutoConfiguration
		@Import(AutoConfigurationImportSelector.class)
		其中AutoConfigurationImportSelector是一个selector,为我们加载了类路径下:META-INF、spring.factories
		这就是自动配置的起源,正因为把这些AutoConfiguration自动加入到了容器中,后面的自动配置才会开始。

示例:

以其中的一个HttpEncodingAutoConfiguration为例进行说明

//这是一个springboot的配置类【代理设置成false,这样在内部调用@Bean的方法去赋值的时候,直接就创建一个新的对象了,如果设置成true,则会先到ioc中去寻找】
@Configuration(proxyBeanMethods = false)

//将ServerProperties加入到ioc容器中,并且这个类是绑定springboot的配置文件的
@EnableConfigurationProperties(ServerProperties.class)

//判断当前是不是一个Web应用,如果是则导入,否则不
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)

//判断当前是否存在CharacterEncodingFilter这个类【是mvc中用于字符编码的】,如果是则导入,否则不
@ConditionalOnClass(CharacterEncodingFilter.class)

//判断配置文件中是否存在server.servlet.encoding.enabled=true,当然我们指定如果配置文件中没有指定server.servlet.encoding.enabled,我们默认为true
@ConditionalOnProperty(prefix = "server.servlet.encoding", value = "enabled", matchIfMissing = true)
public class HttpEncodingAutoConfiguration {
    private final Encoding properties;

    //我们只有一个有参构造器,因此,properties会自动从ioc容器中取值(也就是隐式调用@Autowired,这个在Spring注解版中了解的已经很清楚了)
	public HttpEncodingAutoConfiguration(ServerProperties properties) {
		this.properties = properties.getServlet().getEncoding();
	}

    //其中方法体中的properties就是上方的属性
	@Bean
    //如果容器中没有这个组件则加载
	@ConditionalOnMissingBean
	public CharacterEncodingFilter characterEncodingFilter() {
		CharacterEncodingFilter filter = new OrderedCharacterEncodingFilter();
		filter.setEncoding(this.properties.getCharset().name());
				filter.setForceRequestEncoding(this.properties.shouldForce(Encoding.Type.REQUEST));
			filter.setForceResponseEncoding(this.properties.shouldForce(Encoding.Type.RESPONSE));
		return filter;
	}
//绑定配置文件
@ConfigurationProperties(prefix = "server", ignoreUnknownFields = true)
public class ServerProperties {

所以我们能在配置文件中配置的,都是来自于**Properties这些。

精髓:

  1. springboot在启动的时候会加载大量的自动配置类
  2. 我们看我们需要的功能springboot有没有默认写好的自动配置类
  3. 如果有的话,我们看下自动配置类中配置了那些组件,有没有我们需要的,如果有且满足我们的要求,我们就不需要再来自动配置了
  4. 自动配置类在添加组件的时候,会从properties中获取属性,我们可以在配置文件中指定这些属性

xxxAutoConfiguration:自动配置类

xxxProperties:封装配置文件中相关属性

日志

在springboot中,日志接口统一为slf4j,其他的接口通过通过适配层适配,具体实现类使用logback,其他的实现通过适配层适配logback

使用示例:

//import org.slf4j.Logger;
Logger logger = LoggerFactory.getLogger(getClass());

@Test
void test01(){
    //优先级由低到高
    logger.trace("这是trace");
    logger.debug("这是debug");
    //info是默认级别(可在配置文件中修改)logging.level.com.jd.nxj=debug
    logger.info("这是info");
    logger.warn("这是warn");
    logger.error("这是error");

    //logging.file.name= E:\Code\2020\inJDstudy\my-springboot\03-spring-boot-logging\src\main\java\com\jd\nxj\a.txt
    //如果设置,则写入文本,否则只在控制台输出
}
logging:
  level:
    com:
      jd:
        nxj: debug
  #配置了logging.file.name则输出到指定文件(也会在控制台打印),否则仅仅在控制台打印
  file:
    name: E:\Code\2020\inJDstudy\my-springboot\a.txt

整合Mybatis

Mybatis注解版
  1. springboot配置数据源(spring.datasource等)
  2. 创建mapper,其中mapper上方标注执行sql方法,并将其加入到容器中@Compent
  3. 然后在ioc容器中获取【@Autowired】即可使用
//这是一个操作数据库的mapper
@Mapper //或者在启动类上标注@MapperScan("")
@Component
public interface UserMapper {
    @Select("select * from z1")
    public List<User> queryAllUser();

    @Select("select * from z1 where id=#{id}")
    public User queryUserById(Integer id);
	
    //@Options用来设置id是我的自增主键,我插入的时候,直接返回给我的带自增主键的,否则不写的话,就返回给我null
    @Options(useGeneratedKeys = true,keyProperty = "id")
    @Insert("insert into z1 (name,age) values (#{name},#{age})")
    public int insertUser(User user);
}
//这是controller类里面的内容
@Autowired
UserMapper userMapper;

@ResponseBody
@GetMapping("/user")
public List<User> queryAllUser(){
    return userMapper.queryAllUser();
}

@ResponseBody
@GetMapping("/use/{id}")
public User queryAllUser(@PathVariable("id") Integer id){
    return userMapper.queryUserById(id);
}

@ResponseBody
@GetMapping("/userinsert")
public User insertUser(User user){
    userMapper.insertUser(user);
    return user;
}
Mybatis配置文件版
  1. springboot配置数据源(spring.datasource等)
  2. 创建mapper
  3. 可以创建mybatis的配置文件
  4. 创建mapper对应实现的xml
  5. 在springboot的配置文件中绑定mabatis的配置文件与mapper.xml文件
  6. 从ioc中获取即可调用

1.springboot配置数据源(spring.datasource等)

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/test?serverTimezone=GMT%2B8
    username: root
    password: 123456
    driver-class-name: com.mysql.cj.jdbc.Driver

2.创建mapper

@Component
@Mapper
public interface UserXmlMapper {
    public List<User> queryAllUser();

    public User queryUserById(Integer id);

    public int insertUser(User user);
}

3.可以创建mybatis的配置文件

<?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>
	<!--这是mybatis的主配置文件-->
</configuration>

4.创建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.example.springmybtis.mapper.UserXmlMapper">
    <!--这里就是让这个xml配置文件绑定UserXmlMapper,作为它的实现,我只要把它与Mybatis的配置文件加入到ioc中即可使用了-->

    <select id="queryAllUser" resultType="com.example.springmybtis.bean.User">
        select * from z1
    </select>

    <select id="queryUserById" resultType="com.example.springmybtis.bean.User">
        select * from z1 where id=#{id}
    </select>

    <insert id="insertUser">
        insert into z1 (name,age) values (#{name},#{age});
    </insert>
</mapper>

5.在springboot的配置文件中绑定mabatis的配置文件与mapper.xml文件

mybatis:
  config-location: classpath:mybatis/mybatis-config.xml  #指定全局配置文件的位置
  mapper-locations: classpath:mybatis/mapper/*.xml	#指定sql映射文件的位置

6.从ioc中获取即可调用

@Controller
public class UserXmlController {
    @Autowired
    UserXmlMapper userXmlMapper;

    @GetMapping("/all")
    @ResponseBody
    public List<User> getAllUser(){
        return userXmlMapper.queryAllUser();
    }
}
整合Mybatis-plus版

1.实体类

@Data
@ToString
@NoArgsConstructor
@AllArgsConstructor
//@Entity
//@Table(name = "t_type")
@TableName(value = "t_type") // 指定表明
public class Type {

    private Long id;

    private String name;

    @TableField(exist = false)
    private List<Blog> blogs;
}

2.Dao层

public interface TypeDao  extends BaseMapper<Type> {

    int saveType(Type type);

    Type getTypeById(Long id);
}

3.如果想实现自定义sql则编写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.blog.nxj.dao.TypeDao">
    <!--这里就是让这个xml配置文件绑定Mapper,作为它的实现,我只要把它与Mybatis的配置文件加入到ioc中即可使用了-->

    <sql id="t_types_column">
        name
    </sql>

    <insert id="saveType">
        insert into t_type (name) values (#{name});
    </insert>

    <select id="getTypeById" resultType="com.blog.nxj.po.Type">
        select * from t_type where id = #{id}
    </select>
</mapper>

4.编写Service

public interface TypeService extends IService<Type> {

    int saveType(Type type);

    Type getTypeById(Long id);

    Page<Type> listType(Pageable pageable);

    Type updateType(Type type);

    void deleteType(Type type);
}

5.编写实现类

@Service
/*mybatis-plus查询表明如何变化*/
public class TypeServiceImpl extends ServiceImpl<TypeDao, Type> implements TypeService {

    @Autowired
    TypeDao typeDao;

    @Override
    public int saveType(Type type) {
        int saveCount = typeDao.saveType(type);
        return saveCount;
    }

    @Override
    public Type getTypeById(Long id) {
        Type typeById = typeDao.getTypeById(id);
        return typeById;
    }

    @Override
    public Page<Type> listType(Pageable pageable) {
        return null;
    }

    @Override
    public Type updateType(Type type) {
        return null;
    }

    @Override
    public void deleteType(Type type) {

    }
}

7.配置文件
mybatis-plus则所有代码在mybatis-plus开头的地方书写

mybatis-plus:
  # xml扫描,多个目录用逗号或者分号分隔(告诉 Mapper 所对应的 XML 文件位置)
  mapper-locations: classpath:mybatis/mapper/*.xml
  configuration:
    # 是否开启自动驼峰命名规则映射:从数据库列名到Java属性驼峰命名的类似映射
    map-underscore-to-camel-case: true

这样后,就可以直接使用了!

springboot启动配置原理

只要看到getSpringFactoriesInstances这个方法,它就是从类路径下META-INF/spring.factories下获取相关信息

Bootstrapper
ApplicationContextInitializer
ApplicationListener

1.创建SpringApplication对象

public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources){
	
     this.resourceLoader = resourceLoader;
     Assert.notNull(primarySources, "PrimarySources must not be null");

     this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
     //推断是是一个WebApplicationType什么类型的
     this.webApplicationType = WebApplicationType.deduceFromClasspath();

     this.bootstrappers = new ArrayList<>(getSpringFactoriesInstances(Bootstrapper.class));
     //获取类路径下META-INF/spring.factories下ApplicationContextInitializer配置的Initializer
        setInitializers((Collection) 				getSpringFactoriesInstances(ApplicationContextInitializer.class));
    //获取类路径下META-INF/spring.factories下ApplicationListener配置的相关的Listener
     setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
     this.mainApplicationClass = deduceMainApplicationClass();
}

2.执行run方法

public ConfigurableApplicationContext run(String... args) {
    StopWatch stopWatch = new StopWatch();
    stopWatch.start();
    DefaultBootstrapContext bootstrapContext = createBootstrapContext();
    ConfigurableApplicationContext context = null;
    
    //设置java.awt相关的,一般我们也不用
    configureHeadlessProperty();
    
    //从类路径下的META-INF/spring.factories中获取所有的SpringApplicationRunListener
    SpringApplicationRunListeners listeners = getRunListeners(args);
    
    //回调所有SpringApplicationRunListeners的starting方法
    listeners.starting(bootstrapContext, this.mainApplicationClass);
    try {
        
        //封装命令行参数
        ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
        
        //准备环境
        ConfigurableEnvironment environment = prepareEnvironment(listeners, bootstrapContext, applicationArguments);
        	//获取或者创建环境,然后配置管径
        	//回调SpringApplicationRunListener的environmentPrepared方法
        
        //设置环境中需要忽略的组件信息
        configureIgnoreBeanInfo(environment);
        
        Banner printedBanner = printBanner(environment);
        
        //创建ioc容器
        context = createApplicationContext();
        
        //设置context的applicationStartup属性
        context.setApplicationStartup(this.applicationStartup);
        
        //准备上下文
        prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);
        	//设置环境
        	//注册一些内部组件
        	//获取所有的ApplicationContextInitializer【上方】,并调用其initialize方法
        	//回调SpringApplicationRunListener的contextPrepared方法
        	//全部执行完最后回调SpringApplicationRunListener的contextLoaded方法
        
        //刷新容器,这里就是和spring原理一样,BeanPostProcessors或者组件注册等都在这里
        refreshContext(context);
        
        //内部无任何实现,留给子类扩充
        afterRefresh(context, applicationArguments);
        
        stopWatch.stop();
        
        if (this.logStartupInfo) {
            new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), stopWatch);
        }
        
        //回调SpringApplicationRunListener的started方法
        listeners.started(context);
        
        //从ioc容器中获取ApplicationRunner与CommandLineRunner组件
        //然后将获取出来这两类组件排序后
        //先调用ApplicationRunner的run方法
        //再调用CommandLineRunner的run方法
        callRunners(context, applicationArguments);
    }
    catch (Throwable ex) {
        handleRunFailure(context, ex, listeners);
        throw new IllegalStateException(ex);
    }

    try {
        //回调SpringApplicationRunListener的running方法
        listeners.running(context);
    }
    catch (Throwable ex) {
        handleRunFailure(context, ex, null);
        throw new IllegalStateException(ex);
    }
    //将创建好的ioc容器返回
    return context;
}

上方小结

可以看出以下需要在类路径下:META-INF/spring.factories中配置

Bootstrapper

*ApplicationContextInitializer

ApplicationListener

*SpringApplicationRunListener

*ApplicationRunner

*CommandLineRunner

是从ioc容器中取得【也就是对象创建完了,我们去拿】

应用测试

1.分别创建ApplicationContextInitializerSpringApplicationRunListenerApplicationRunnerCommandLineRunner的实现类

public class MyApplicationContextInitializer implements ApplicationContextInitializer {

    @Override
    public void initialize(ConfigurableApplicationContext configurableApplicationContext) {
        System.out.println("MyApplicationContextInitializer...initialize"+configurableApplicationContext.getApplicationName());
    }
}
public class MySpringApplicationRunListener implements SpringApplicationRunListener {

    public MySpringApplicationRunListener(SpringApplication application, String[] args) {
        System.out.println("chushihua");
    }

    @Override
    public void starting(ConfigurableBootstrapContext bootstrapContext) {
        System.out.println("starting");
    }

    @Override
    public void environmentPrepared(ConfigurableBootstrapContext bootstrapContext, ConfigurableEnvironment environment) {
        System.out.println("environmentPrepared");
    }

    @Override
    public void contextPrepared(ConfigurableApplicationContext context) {
        System.out.println("contextPrepared");
    }

    @Override
    public void contextLoaded(ConfigurableApplicationContext context) {
        System.out.println("contextLoaded");
    }

    @Override
    public void started(ConfigurableApplicationContext context) {
        System.out.println("started");
    }

    @Override
    public void running(ConfigurableApplicationContext context) {
        System.out.println("running");
    }

    @Override
    public void failed(ConfigurableApplicationContext context, Throwable exception) {
        System.out.println("failed");
    }
}
@Component
public class MyApplicationRunner implements ApplicationRunner {
    @Override
    public void run(ApplicationArguments args) throws Exception {
        System.out.println("MyApplicationRunner...run"+ Arrays.asList(args));
    }
}
@Component
public class MyCommandLineRunner implements CommandLineRunner {
    @Override
    public void run(String... args) throws Exception {
        System.out.println("MyCommandLineRunner...run"+ Arrays.asList(args));
    }
}

2.在类路径下META-INF下创建spring.factories,内容如下:

org.springframework.context.ApplicationContextInitializer=\
com.example.springmybtis.test.MyApplicationContextInitializer

org.springframework.boot.SpringApplicationRunListener=\
com.example.springmybtis.test.MySpringApplicationRunListener

启动主程序,输出顺序如下:

chushihua
starting
environmentPrepared

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::                (v2.4.0)

MyApplicationContextInitializer...initialize
contextPrepared

contextLoaded

started
MyApplicationRunner...run[org.springframework.boot.DefaultApplicationArguments@f446158]
MyCommandLineRunner...run[]
running

自定义starter

@Configuration //指定这是一个配置类
@ConditionalOnXXX //指定条件生效时自动配置类才生效
@AutoConfigureAfter //指定自动配置类的顺序(这里是在这些写自动配置加载完后,这个类再加载)
@Bean //给容器中添加组件

@ConditionalOnProperty //结合xxProperties来绑定属性赋值
@EnableConfigurationProperties //让xxProperties生效并加入到ioc容器中

自动配置类要能生效,源于我们在META-INF/spring.factories下的自动配置,如:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration
命名时,我们最好xxx-spring-boot-starter

【启动器只用于一来到日,专门写一个自动配置模块】(这是spring在书写时stater时的规范)
1.我们得代码写在xxx-spring-boot-starter-configure下
2.xxx-spring-boot-starter依赖xxx-spring-boot-starter-configure
3.我们使用xxx-spring-boot-starter

1.创建pom工程起名为nxj-spring-boot-starter

​ 注意这里千万不要因为在其他文件夹下,从而出现parent节点,很容易出问题,导致其他pom引入出错。

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <artifactId>nxj-spring-boot-starter</artifactId>
    <groupId>org.jd.nxj</groupId>
    <version>1.0.0</version>
    <dependencies>
        <!--引入我的自动配置模块-->
        <dependency>
            <groupId>com.jd.nxj</groupId>
            <artifactId>nxj-spring-boot-starter-configure</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>
    </dependencies>

</project>

2.编写nxj-spring-boot-starter-configure

和配置文件属性赋值绑定的XXXProperties

@ConfigurationProperties(prefix = "nxj")
public class NxjProperties {
    private String prefix;
    private String suffix;

    public String getPrefix() {
        return prefix;
    }

    public void setPrefix(String prefix) {
        this.prefix = prefix;
    }

    public String getSuffix() {
        return suffix;
    }

    public void setSuffix(String suffix) {
        this.suffix = suffix;
    }
}

3.写一个NxjService

public class NxjService {

    private NxjProperties nxjProperties;

    public NxjProperties getNxjProperties() {
        return nxjProperties;
    }

    public void setNxjProperties(NxjProperties nxjProperties) {
        this.nxjProperties = nxjProperties;
    }

    public String sayHello(String name){
        return nxjProperties.getPrefix()+"-"+name+"-"+nxjProperties.getSuffix();
    }
}

4.自动配置类

@Configuration
@ConditionalOnWebApplication
@EnableConfigurationProperties(NxjProperties.class)
public class NxjServiceAutoConfig {
    @Autowired
    NxjProperties nxjProperties;
    @Bean
    public NxjService nxjService(NxjProperties nxjProperties){
        NxjService nxjService = new NxjService();
        nxjService.setNxjProperties(nxjProperties);
        return nxjService;
    }
}

5.要让自动配置类能生效,必须在类路径下:META-INF/spring.factories中配置

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.jd.nxj.autoconfig.NxjServiceAutoConfig

引入:

1.pom文件引入

<dependency>
    <artifactId>nxj-spring-boot-starter</artifactId>
    <groupId>org.jd.nxj</groupId>
    <version>1.0.0</version>
</dependency>

2.配置文件中写值,我们可以赋予上去

nxj.prefix=前缀
nxj.suffix=后缀

3.编写controller测试

@Controller
public class HelloController {
    @Autowired
    NxjService nxjService;

    @GetMapping("/nxj")
    @ResponseBody
    public String hello(){
        return nxjService.sayHello("nxj");
    }
}

结果:前缀-nxj-后缀

Spring整合Mybatis

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"
       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">

    <!--
    读取 jdbc.properties 中的内容
         property-placeholder: 占位符
         location: 属性文件的位置

         这个不太好用,可能读的不全【我自己粘贴过来可以,读取它的就报错密码不对...】
    -->
    <context:property-placeholder location="classpath:db.properties"/>
    <!-- 1) 获得数据库连接池对象,并交由 spring 同一管理 -->
    <!--数据源-->
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="username" value="root"/>
        <property name="password" value="123456"/>
        <property name="url" value="jdbc:mysql://mysql-cn-north-1-3a9ad9cdc01f4821.rds.jdcloud.com:3358/b2b_center"/>
    </bean>

    <!-- 2) 获取 SqlSessionFactory 对象,并交由 spring 管理-->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <!-- 注入连接池
         给 sqlsessionFactory 的属性 dataSource 赋值
            ref="引用该 spring容器 中的另一个 bean的id"
        -->
        <property name="dataSource" ref="dataSource"/>
        <!-- 注入 映射文件 mapper
         给 sqlsessionFactory 的属性 mapperLocation 赋值
           value="映射文件 XXXmapper.xml 的相对路径"
          -->
        <property name="mapperLocations" value="classpath:mapper/*.xml"/>
        <!--<property name="configLocation" value="写mybatis配置文件的位置"/>-->
    </bean>

    <!-- 3) 获取 SqlSession 对象,并交由 spring 管理  用SqlSessionTemplate得到的SqlSession可以不用我们自己操心事务的管理,以及关闭操作-->
    <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
        <!-- 给 SqlSessionTemplate 的构造函数赋值-->
        <constructor-arg index="0" ref="sqlSessionFactory" />
    </bean>

    <!--自己写写实现类(一般不会这样写的,写了下方这个就注释掉!!)-->
    <bean id="studentMapperImpl" class="com.nxj.impl.StudentMapperImpl">
        <constructor-arg name="sessionTemplate" ref="sqlSession"/>
    </bean>

    <!--mybatis封装了这个,不需要写实现类就可以借助这个工厂生成相应的bean(这个是真的强!(底部用到动态代理等))-->
    <bean id="studentMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
        <property name="targetInterface" value="com.nxj.mapper.StudentMapper"/>
        <property name="proxy" ref="sqlSession" />
    </bean>

</beans>

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>
  <!--mybatis核心配置文件-->

   <!--加载mapper映射配置文件-->
   <mappers>
       <mapper resource="mapper/Student.xml"/>
   </mappers>

</configuration>

Student

@Data
public class Student {
    private String name;
    private Date createTime;
}

StudentMapper

public interface StudentMapper {
     public static final String NAMESPACE = "com.nxj.mapper.StudentMapper";

     // 注解也是和jd封装使用
     @Statement(namespace = NAMESPACE, sqlId = "getStudentById")
     @ProxyMethod(name = "selectOne", parameterTypes = { String.class,Object.class})
     Student getStudentById(Integer id);
}

StudentMapper.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">
    <!-- namespace:命名空间,对sql进行一个分类管理 -->
    <!-- 注意:namespace在mapper代理时,具有重要且特殊的作用
  对应mapper接口的全限定名
-->

   <!--mybatis映射配置文件-->
<mapper namespace="com.nxj.mapper.StudentMapper">
    <sql id="user_column_noid">
        user_name,create_time
    </sql>

    <resultMap id="userMapPlus" type="com.nxj.pojo.Student">
        <result column="user_name" jdbcType="VARCHAR" property="name"/>
        <!--不写的话默认按名字匹配,如果开启驼峰命名,也会按照这个规则匹配-->
        <result column="create_time" jdbcType="DATE" property="createTime"/>
    </resultMap>
    
     <select id="getStudentById" parameterType="int" resultMap="userMapPlus">
         select
         <include refid="user_column_noid"></include>
         from z_user
         where id = #{id}
     </select>
</mapper>

如果是在找不到不写实现类的,那就自己写个实现类(很恶心,尽量不写这个)

StudentMapperImpl

public class StudentMapperImpl implements StudentMapper {
    SqlSessionTemplate sessionTemplate;

    public StudentMapperImpl() {
    }

    public StudentMapperImpl(SqlSessionTemplate sessionTemplate) {
        this.sessionTemplate = sessionTemplate;
    }


    @Override
    public Student getStudentById(Integer id) {
        StudentMapper mapper = sessionTemplate.getMapper(StudentMapper.class);
        return mapper.getStudentById(id);
    }
}

测试:

public class MyTest {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");

        StudentMapper studentMapper = context.getBean("studentMapper", StudentMapper.class);
        System.out.println(studentMapper.getStudentById(1));
    }
}

posted @ 2021-01-18 23:30  程序杰杰  阅读(166)  评论(0编辑  收藏  举报