[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
,其数据如下:
版本说明
数据库
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、数据来源。