🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
[TOC] # 配置 ~~~ mybatis.config-location=classpath:mybatis/mybatis-config.xml # 指定路径 mybatis.mapper-locations=classpath:mybatis/mapper/*.xml mybatis.type-aliases-package=com.jdxia.model spring.datasource.url=jdbc:mysql://localhost:3306/app?serverTimezone=PRC&useUnicode=true&characterEncoding=utf-8 spring.datasource.username=root spring.datasource.password=root spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver logging.level.com.jdxia.mapper=debug ~~~ * `mybatis.config-location`,配置 `mybatis-config.xml` 路径,`mybatis-config.xml` 中配置 MyBatis 基础属性; * `mybatis.mapper-locations`,配置 Mapper 对应的 XML 文件路路径; * `mybatis.type-aliases-package`,配置项⽬目中实体类包路径; * `spring.datasource.*`,数据源配置。 Spring Boot 启动时数据源会自动注入到 SqlSessionFactory 中,使用 SqlSessionFactory 构建 SqlSessionFactory,再自动注⼊到 Mapper 中,最后我们直接使用 Mapper 即可。 # 启动类 在启动类中添加对 Mapper 包扫描 @MapperScan,Spring Boot 启动的时候会自动加载包路径下的 Mapper. 或者直接在 Mapper 类上面添加注解 @Mapper,建议使用上面那种,不然每个 mapper 加个注解也挺麻烦的。 ~~~ @MapperScan("com.jdxia.mapper") @SpringBootApplication public class UserApplication { ~~~ # 例子 ## 准备表 ~~~ DROP TABLE IF EXISTS `users`; CREATE TABLE `users` ( `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键id', `userName` varchar(32) DEFAULT NULL COMMENT '用户名', `passWord` varchar(32) DEFAULT NULL COMMENT '密码', `user_sex` varchar(32) DEFAULT NULL, `nick_name` varchar(32) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; ~~~ ## 准备实体 **枚举属性** ~~~ public enum UserSexEnum { MAN, WOMAN } ~~~ **User实体** ~~~ @Data @AllArgsConstructor @NoArgsConstructor public class User implements Serializable { private static final long serialVersionUID = 1L; private Long id; private String userName; private String passWord; private UserSexEnum userSex; private String nickName; } ~~~ ## 分页查询 Web 层的参数会以 param 为后缀的对象进行传参,以 result 结尾的实体类封装返回的数据 **分页的基础类** ~~~ @Data public class PageParam { //起始行 private int beginLine; //默认每页3条 private Integer pageSize = 3; // 当前页 private Integer currentPage = 0; //自动计算起始行 public int getBeginLine() { return pageSize * currentPage; } } ~~~ user查询条件参数类继承分页基础类 ~~~ @Data public class UserParam extends PageParam{ private String userName; private String userSex; } ~~~ xml中要配置从分页对象中获取信息 ~~~ <!-- 从分页对象中,获取分页信息和查询条件 --> <select id="getList" resultMap="BaseResultMap" parameterType="com.jdxia.param.UserParam"> select <include refid="Base_Column_List" /> from users where 1=1 <include refid="Base_Where_List" /> order by id desc limit #{beginLine} , #{pageSize} </select> ~~~ ## 定义接口 ~~~ public interface UserMapper { //这里的⽅方法名需要和 XML配置中的id属性一致,不然会找不到方法去对应执行的sql List<User> getAll(); List<User> getList(UserParam userParam); int getCount(UserParam userParam); User getOne(Long id); void insert(User user); int update(User user); int delete(Long id); } ~~~ ## mybatis公共属性 mybatis-config.xml主要配置常用的typeAliases,设置类型别名,为java类型设置一短的名字. 它只和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> <typeAliases> <typeAlias alias="Integer" type="java.lang.Integer" /> <typeAlias alias="Long" type="java.lang.Long" /> <typeAlias alias="HashMap" type="java.util.HashMap" /> <typeAlias alias="LinkedHashMap" type="java.util.LinkedHashMap" /> <typeAlias alias="ArrayList" type="java.util.ArrayList" /> <typeAlias alias="LinkedList" type="java.util.LinkedList" /> </typeAliases> </configuration> ~~~ 这样我们在使用 Mapper.xml 的时候,需要引入可以直接这样写: ~~~ resultType="Integer" //或者 parameterType="Long" ~~~ ## map的配置文件 ~~~ <?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 类地址 --> <mapper namespace="com.jdxia.mapper.UserMapper" > <!--配置表结构和类的对应关系--> <resultMap id="BaseResultMap" type="com.jdxia.model.User" > <id column="id" property="id" jdbcType="BIGINT" /> <result column="userName" property="userName" jdbcType="VARCHAR" /> <result column="passWord" property="passWord" jdbcType="VARCHAR" /> <!-- 用枚举,插入此属性的数据会⾃动进行校验,如果不是枚举的内容会报错--> <result column="user_sex" property="userSex" javaType="com.jdxia.enums.UserSexEnum"/> <result column="nick_name" property="nickName" jdbcType="VARCHAR" /> </resultMap> <!-- sql复用--> <sql id="Base_Column_List" > id, userName, passWord, user_sex, nick_name </sql> <sql id="Base_Where_List"> <if test="userName != null and userName != ''"> and userName = #{userName} </if> <if test="userSex != null and userSex != ''"> and user_sex = #{userSex} </if> </sql> <!-- sql --> <select id="getAll" resultMap="BaseResultMap" > SELECT <include refid="Base_Column_List" /> FROM users </select> <!-- 从分页对象中,获取分页信息和查询条件 --> <select id="getList" resultMap="BaseResultMap" parameterType="com.jdxia.param.UserParam"> select <include refid="Base_Column_List" /> from users where 1=1 <include refid="Base_Where_List" /> order by id desc limit #{beginLine} , #{pageSize} </select> <select id="getCount" resultType="Integer" parameterType="com.jdxia.param.UserParam"> select count(1) from users where 1=1 <include refid="Base_Where_List" /> </select> <select id="getOne" parameterType="Long" resultMap="BaseResultMap" > SELECT <include refid="Base_Column_List" /> FROM users WHERE id = #{id} </select> <insert id="insert" parameterType="com.jdxia.model.User" > INSERT INTO users (userName,passWord,user_sex) VALUES (#{userName}, #{passWord}, #{userSex}) </insert> <update id="update" parameterType="com.jdxia.model.User" > UPDATE users SET <if test="userName != null">userName = #{userName},</if> <if test="passWord != null">passWord = #{passWord},</if> nick_name = #{nickName} WHERE id = #{id} </update> <delete id="delete" parameterType="Long" > DELETE FROM users WHERE id =#{id} </delete> </mapper> ~~~ ## 测试 ~~~ @Resource private UserMapper userMapper; @Test public void testUser() { userMapper.insert(new User("aa", "a123456", UserSexEnum.MAN)); } ~~~ # 多数据源 ## 配置文件 ~~~ mybatis.config-location=classpath:mybatis/mybatis-config.xml spring.datasource.one.jdbc-url=jdbc:mysql://localhost:3306/test1?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=true spring.datasource.one.username=root spring.datasource.one.password=root spring.datasource.one.driver-class-name=com.mysql.cj.jdbc.Driver spring.datasource.two.jdbc-url=jdbc:mysql://localhost:3306/test2?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=true spring.datasource.two.username=root spring.datasource.two.password=root spring.datasource.two.driver-class-name=com.mysql.cj.jdbc.Driver ~~~ 第一个数据源以 `spring.datasource.one.* `为前缀连接数据库 test1, 第二个数据源以 `spring.datasource.two.*`为前缀连接数据库 test2。 同时需要将上述的 UserMapper.xml 文件复制两份到 `resources/mybatis/mapper/one` 和`resources/mybatis/mapper/two` 目录下各一份。 数据源配置为两个数据源创建不同的 Mapper 包路路径, 将以前的 UserMapper 复制到包 com.neo.mapper.one 和 com.neo.mapper.two 路路径下,并且分别重命名为:User1Mapper、User2Mapper。 ## 配置数据源 配置第一个数据源,新建 DataSource1Config **在多数据源中只能指定一个 @Primary作为默认的数据源** * basePackages 指明 Mapper 地址 * sqlSessionTemplateRef 指定 Mapper 路径下注⼊的 sqlSessionTemplate ~~~ import org.apache.ibatis.session.SqlSessionFactory; import org.mybatis.spring.SqlSessionFactoryBean; import org.mybatis.spring.SqlSessionTemplate; import org.mybatis.spring.annotation.MapperScan; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.jdbc.DataSourceBuilder; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; import org.springframework.core.io.support.PathMatchingResourcePatternResolver; import org.springframework.jdbc.datasource.DataSourceTransactionManager; import javax.sql.DataSource; //把创建的SqlSessionTemplate注入到对应的Mapper包路径下,这样包下面的Mapper都会使用第一个数据源来进行数据库操作 @Configuration @MapperScan(basePackages = "com.jdxia.mapper.one", sqlSessionTemplateRef = "oneSqlSessionTemplate") public class DataSource1Config { // 加载配置的数据源 @Bean(name = "oneDataSource") @ConfigurationProperties(prefix = "spring.datasource.one") @Primary public DataSource testDataSource() { return DataSourceBuilder.create().build(); } // 根据创建的数据源,构建对应的SqlSessionFactory,代码中指定需要加载的Mapper xml文件 @Bean(name = "oneSqlSessionFactory") @Primary public SqlSessionFactory testSqlSessionFactory(@Qualifier("oneDataSource") DataSource dataSource) throws Exception { SqlSessionFactoryBean bean = new SqlSessionFactoryBean(); bean.setDataSource(dataSource); bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mybatis/mapper/one/*.xml")); return bean.getObject(); } //把数据源加到事务中 @Bean(name = "oneTransactionManager") @Primary public DataSourceTransactionManager testTransactionManager(@Qualifier("oneDataSource") DataSource dataSource) { return new DataSourceTransactionManager(dataSource); } //把上面创建的SqlSessionFactory注入,创建我们在Mapper中需要使用的SqlSessionTemplate @Bean(name = "oneSqlSessionTemplate") @Primary public SqlSessionTemplate testSqlSessionTemplate(@Qualifier("oneSqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception { return new SqlSessionTemplate(sqlSessionFactory); } } ~~~ **另一个数据源也同理** 第⼆个数据源配置, DataSource2Config 的配置和上⾯类似,⽅法上需要去掉 @Primary 注解,替换对应的数据源和 Mapper 路 径即可 创建多数据源的过程就是:⾸先创建 DataSource,注⼊到 SqlSessionFactory 中,再创建事务,将 SqlSessionFactory 注⼊到创建的 SqlSessionTemplate 中,最后将 SqlSessionTemplate 注⼊到对应的 Mapper 包路径下。其中需要指定分库的 Mapper 包路径。 注意,在多数据源的情况下,我们不需要在启动类添加:`@MapperScan("com.xxx.mapper")` 的注解。 这样 MyBatis 多数据源的配置就完成了 ## 测试 ~~~ @Autowired private User1Mapper userMapper; @Test public void testInsert() throws Exception { userMapper.insert(new User("aammx", "a123456", UserSexEnum.MAN)); userMapper.insert(new User("bbmmx", "b123456", UserSexEnum.WOMAN)); userMapper.insert(new User("ccmmx", "b123456", UserSexEnum.WOMAN)); // Assert.assertEquals(3, userMapper.getAll().size()); } ~~~