[MyBatis] 通过代码配置+XML文件构建SqlSessionFactory

问题描述

最近由于项目中的特殊需求,在构建SqlSessionFactory时,数据库连接参数需要在代码中动态获取,同时也需要在XML文件(mybatis-config.xml)中配置映射文件信息(借助XMLConfigBuilder 类读取配置)。在此作为笔记记录。示例代码的目录结构如下:

/src
	/main
		/java
			/**
				/configuration
					/MyBatisConfigure.java	# 构建SqlSessionFactory
				/mapper
					/FbPlayerMapper.java	# 映射接口
				/entity
					/FbPlayer.java			# 实体类
				/App.java					# 测试主程序
		/resources
			/mapper/FbPlayer.xml
			/mybatis-config.xml

数据表为:fb_players,其数据如下:
Chelsea-Players

版本说明

数据库

MariaDB:10.4.16

依赖

mybatis:3.5.6
mysql-connector-java:8.0.23

数据源为:

HikariCP:4.0.2

相关代码

XML文件:

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>
	<settings>
        <!-- 开启驼峰自动映射 -->
        <setting name="mapUnderscoreToCamelCase" value="true"/>
    </settings>
    <mappers>
        <mapper resource="mapper/FbPlayerMapper.xml"/>
    </mappers>
</configuration>

FbPlayerMapper.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.gavin11.action.mybatis.mapper.FbPlayerMapper">
    <select id="selectCount" resultType="java.lang.Long">
        select count(1) from fb_players
    </select>

    <select id="getAllPlayers" resultType="com.gavin11.action.mybatis.entity.FbPlayer">
        select id,name,gender,age,uniform_number,height,weight,habitual_foot,team_id from fb_players
    </select>
</mapper>

Java代码

MyBatisConfigure.java

import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import org.apache.ibatis.builder.xml.XMLConfigBuilder;
import org.apache.ibatis.mapping.Environment;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.apache.ibatis.transaction.TransactionFactory;
import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory;

import javax.sql.DataSource;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.Objects;

/**
 * @project ActionInMyBatis
 * @package com.gavin11.action.mybatis.configuration
 * @description: MyBatisConfigure <br>
 * @date: 2021/3/4 20:13 <br>
 * @author: Gavin <br>
 * @version: 1.0 <br>
 */
public class MyBatisConfigure {

    private static SqlSessionFactory sqlSessionFactory = null;

    private MyBatisConfigure() {}

    static {
        HikariConfig config = new HikariConfig();
        // 在代码中配置连接参数
        config.setDriverClassName("com.mysql.cj.jdbc.Driver");
        config.setJdbcUrl("jdbc:mysql://192.168.0.101:3306/football?useUnicode=true&characterEncoding=utf8");
        config.setUsername("root");
        config.setPassword("123456");
        config.setConnectionTimeout(60000);
        config.setIdleTimeout(5000);
        config.setMaximumPoolSize(10);
        DataSource dataSource = new HikariDataSource(config);

        TransactionFactory transactionFactory = new JdbcTransactionFactory();
        Environment environment = new Environment("development", transactionFactory, dataSource);

        // 以下为从mybatis-config.xml中载入映射文件的相关信息
        try (
                InputStream is = MyBatisConfigure.class.getClassLoader().getResourceAsStream("mybatis-config.xml");
                InputStreamReader isr = new InputStreamReader(Objects.requireNonNull(is), StandardCharsets.UTF_8)
                ) {
            // 借助XMLConfigBuilder类载入mybatis-config.xml中的相关配置
            XMLConfigBuilder configBuilder = new XMLConfigBuilder(isr);
            Configuration configuration = configBuilder.parse();
            // 将连接参数写入configuration中
            configuration.setEnvironment(environment);

            // 构建
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(configuration);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static SqlSessionFactory getSqlSessionFactory() {
        return sqlSessionFactory;
    }
}

FbPlayerMapper.java

import java.util.List;

/**
 * @project ActionInMyBatis
 * @package com.gavin11.action.mybatis.mapper
 * @description: FbPlaerMapper <br>
 * @date: 2021/3/4 20:01 <br>
 * @author: Gavin <br>
 * @version: 1.0 <br>
 */
@Mapper
public interface FbPlayerMapper {

    long selectCount();

    List<FbPlayer> getAllPlayers();
}

FbPlayer.java


```java
import java.io.Serializable;

/**
 * @project ActionInMyBatis
 * @package com.gavin11.action.mybatis.entity
 * @description: FbPlayer <br>
 * @date: 2021/3/4 19:58 <br>
 * @author: Gavin <br>
 * @version: 1.0 <br>
 */
public class FbPlayer implements Serializable {

    private static final long serialVersionUID = 3L;
    private long id;
    private String name;
    private String gender;
    private int age;
    private int uniformNumber;
    private double height;
    private double weight;
    private String habitualFoot;
    private long teamId;
   
   // 省略getter/setter
}

App.java

import com.gavin11.action.mybatis.configuration.MyBatisConfigure;
import com.gavin11.action.mybatis.entity.FbPlayer;
import com.gavin11.action.mybatis.mapper.FbPlayerMapper;
import org.apache.ibatis.session.SqlSession;

import java.util.List;

/**
 * Hello world!
 *
 */
public class App 
{
    public static void main( String[] args )
    {
        try (
                SqlSession sqlSession = MyBatisConfigure.getSqlSessionFactory().openSession()
                ) {
            FbPlayerMapper mapper = sqlSession.getMapper(FbPlayerMapper.class);
            long count = mapper.selectCount();
            List<FbPlayer> allPlayers = mapper.getAllPlayers();

            System.out.printf("total: %d\n", count);

            if (allPlayers != null) {
                allPlayers.forEach(System.out::println);
            }

            System.out.println("complete!");
        }
    }
}

运行结果

total: 28
FbPlayer{id=85, name='Antonio Rüdiger', gender='male', age=27, uniformNumber=2, height=190.0, weight=85.0, habitualFoot='right', teamId=1}
FbPlayer{id=86, name='Reece James', gender='male', age=20, uniformNumber=24, height=182.0, weight=87.0, habitualFoot='right', teamId=1}
FbPlayer{id=87, name='Benjamin Chilwell', gender='male', age=23, uniformNumber=21, height=178.0, weight=77.0, habitualFoot='left', teamId=1}
FbPlayer{id=88, name='Olivier Giroud', gender='male', age=34, uniformNumber=18, height=193.0, weight=92.0, habitualFoot='left', teamId=1}
FbPlayer{id=89, name='Kurt Zouma', gender='male', age=26, uniformNumber=15, height=190.0, weight=95.0, habitualFoot='right', teamId=1}
FbPlayer{id=90, name='Ngolo Kante', gender='male', age=29, uniformNumber=7, height=168.0, weight=71.0, habitualFoot='right', teamId=1}
FbPlayer{id=91, name='Danny Drinkwater', gender='male', age=30, uniformNumber=0, height=177.0, weight=70.0, habitualFoot='right', teamId=1}
FbPlayer{id=92, name='Abdul Rahman Baba', gender='male', age=26, uniformNumber=0, height=179.0, weight=70.0, habitualFoot='left', teamId=1}
FbPlayer{id=93, name='César Azpilicueta', gender='male', age=31, uniformNumber=28, height=178.0, weight=77.0, habitualFoot='right', teamId=1}
FbPlayer{id=94, name='Marcos Alonso', gender='male', age=29, uniformNumber=3, height=188.0, weight=85.0, habitualFoot='left', teamId=1}
FbPlayer{id=95, name='Andreas Christensen', gender='male', age=24, uniformNumber=4, height=188.0, weight=82.0, habitualFoot='right', teamId=1}
FbPlayer{id=96, name='Wilfredo Caballero', gender='male', age=39, uniformNumber=13, height=186.0, weight=83.0, habitualFoot='right', teamId=1}
FbPlayer{id=97, name='Mateo Kovacic', gender='male', age=26, uniformNumber=17, height=177.0, weight=78.0, habitualFoot='right', teamId=1}
FbPlayer{id=98, name='Fikayo Tomori', gender='male', age=22, uniformNumber=14, height=184.0, weight=75.0, habitualFoot='right', teamId=1}
FbPlayer{id=99, name='Christian Pulisic', gender='male', age=22, uniformNumber=10, height=172.0, weight=63.0, habitualFoot='right', teamId=1}
FbPlayer{id=100, name='Thiago Emiliano da S', gender='male', age=36, uniformNumber=6, height=183.0, weight=79.0, habitualFoot='right', teamId=1}
FbPlayer{id=101, name='Kai Havertz', gender='male', age=21, uniformNumber=29, height=189.0, weight=77.0, habitualFoot='left', teamId=1}
FbPlayer{id=102, name='Kepa Arrizabalaga', gender='male', age=26, uniformNumber=1, height=186.0, weight=88.0, habitualFoot='right', teamId=1}
FbPlayer{id=103, name='Jorge Luiz Frello Fi', gender='male', age=28, uniformNumber=5, height=180.0, weight=67.0, habitualFoot='right', teamId=1}
FbPlayer{id=104, name='Emerson', gender='male', age=26, uniformNumber=33, height=181.0, weight=79.0, habitualFoot='left', teamId=1}
FbPlayer{id=105, name='Timo Werner', gender='male', age=24, uniformNumber=11, height=181.0, weight=75.0, habitualFoot='right', teamId=1}
FbPlayer{id=106, name='Edouard Mendy', gender='male', age=28, uniformNumber=16, height=196.0, weight=86.0, habitualFoot='right', teamId=1}
FbPlayer{id=107, name='Mason Mount', gender='male', age=21, uniformNumber=19, height=178.0, weight=65.0, habitualFoot='right', teamId=1}
FbPlayer{id=108, name='Billy Gilmour', gender='male', age=19, uniformNumber=23, height=170.0, weight=65.0, habitualFoot='right', teamId=1}
FbPlayer{id=109, name='Callum Hudson-Odoi', gender='male', age=19, uniformNumber=20, height=177.0, weight=74.0, habitualFoot='right', teamId=1}
FbPlayer{id=110, name='Tammy Abraham', gender='male', age=23, uniformNumber=9, height=191.0, weight=81.0, habitualFoot='right', teamId=1}
FbPlayer{id=111, name='Charly Musonda Jr.', gender='male', age=24, uniformNumber=0, height=173.0, weight=0.0, habitualFoot='right', teamId=1}
FbPlayer{id=112, name='Hakim Ziyech', gender='male', age=27, uniformNumber=22, height=181.0, weight=70.0, habitualFoot='left', teamId=1}
complete!

参考:
1、HikariCP连接示例
2、MyBatis相关构建
3、数据来源

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值