本章内容
- 添加mybatis支持
- 多数据源配置
- 总结
前一章也说过,连接使用数据库主要有两种方式,一种是ORM框架,使用对像来生成需要的SQL,代表的有JPA和Hibernate。另一种方式就是直接使用SQL操作,最常用的就是Mybatis。
添加mybatis
首先,添加相关的jar包
<!--mybatis连接-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.2.0</version>
</dependency>
<!--mybatis分页插件-->
<dependency>
<groupId>com.github.miemiedev</groupId>
<artifactId>mybatis-paginator</artifactId>
<version>1.2.17</version>
</dependency>
其次,在application.yml配置文件中,标明mybatis需要扫描的文件,需要在resources目录下新增mapper包用于存放mybatis的SQL配置文件,如果业务比较多,想区分不同的文件夹,也可以,只需要按一定的规则配置即可,例如:classpath:mapper/*/*.xml
mybatis:
config-location: classpath:mybatis-config.xml
mapper-locations: classpath:mapper/*.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>
<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" />
<!--实体类包-->
<package name="com.xps.sc.springbootdemo.entity"></package>
</typeAliases>
<!--引用分页插件-->
<plugins>
<plugin interceptor="com.github.miemiedev.mybatis.paginator.OffsetLimitInterceptor">
<property name="dialectClass" value="com.github.miemiedev.mybatis.paginator.dialect.MySQLDialect"/>
</plugin>
</plugins>
</configuration>
最后,需要在启动入口,使用@MapperScan标注mybatis扫描的Dao层的包名(或者在每一个Dao上使用@Mapper,这样比较麻烦)。
@SpringBootApplication
//@EnableTransactionManagement
@MapperScan("com.xps.sc.springbootdemo.mapper")
public class SpringBootDemoApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootDemoApplication.class, args);
}
}
这样配置的部分就已经完成了。接下来我们来测试一下。新增一个BatisUserMapper的接口
public interface BatisUserMapper {
@Select("select * from T_TEST_USER where user_id = #{userId}")
@Results({
@Result(property = "userId",column = "user_id",javaType = Long.class),
@Result(property = "userName",column = "user_name",javaType = String.class),
@Result(property = "nickName",column = "nick_name",javaType = String.class),
@Result(property = "email",column = "email",javaType = String.class),
@Result(property = "createTime",column = "create_time",javaType = Date.class)
})
User getUserById(Long userId);
@Insert("insert into T_TEST_USER(user_id,user_name,nick_name,pass_word,email,reg_time,create_time) values(" +
"#{userId,jdbcType=BIGINT},#{userName,jdbcType=VARCHAR},#{nickName},#{passWord},#{email},#{regTime},#{createTime,jdbcType=TIMESTAMP})")
void insert(User user);
@Update("update T_TEST_USER set email=#{email} where user_id = #{userId}")
void update(User user);
//以下是使用mapper.xml配置文件来配置sql
List<User> getUserList(String nickName);
void insertUser(User user);
void updateUser(User user);
void delete(Long userId);
}
可以看到,mybatis提供了相关的注解来配置SQL及字段元素等等,与xml中的元素类似。两者可以同时使用,一般来说比较简单的增、删、改可以使用注解的方式,比较复杂的业务还是使用xml直接写sql比较方便。
测试:
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
@WebAppConfiguration
public class BatisUserTests {
private Logger logger = LoggerFactory.getLogger(HelloBootController.class);
@Autowired
private BatisUserMapper userMapper;
@Before
public void setUp() throws Exception {
}
@Test
public void save() throws Exception {
User user = new User();
user.setUserName("eea");
user.setPassWord("eea");
user.setEmail("[email protected]");
user.setNickName("eea在");
user.setRegTime("2018-12-13 11:19:10");
user.setCreateTime(new Date());
//userMapper.insert(user);
userMapper.insertUser(user);
}
}
我与jpa一起使用的时候,总是报找不到entityFactory的错误。不知道是不是不能一起使用,还是我配置的有问题。这个以后再研究。
多数据源配置
在比较复杂的业务中我们可能需要跨多个数据库来操作业务,这样就需要mybatis对多数据源的支持。在spring boot中使用多数据源也是非常简单的。
首先,配置相关的数据源
spring:
datasource:
master: #注意这里只能使用jdbc-url,直接使用url会报jdbcUrl is required with driverClassName的错误
jdbc-url: jdbc:mysql://localhost:3306/world?serverTimezone=UTC
username: root
password: root
driver-class-name: com.mysql.cj.jdbc.Driver
slave:
jdbc-url: jdbc:mysql://localhost:3306/sys?serverTimezone=UTC
username: root
password: root
driver-class-name: com.mysql.cj.jdbc.Driver
然后,写两个配置类(有多少个数据源就写多少个配置类,但要注意DataSource只能有一个@Primary),例如,master数据源的配置如下(其它的都类似只是相关的名称需要换一下):
@Configuration
@MapperScan(basePackages = "com.xps.sc.springbootdemo.mapper1",
sqlSessionTemplateRef = "masterSqlSessionTemplate")
public class DataSourceMasterConfig {
// @Bean(name = "masterDataSourceProperties")
// @ConfigurationProperties(prefix = "spring.datasource.master")
//@Qualifier("masterDataSourceProperties")
// @Primary
public DataSourceProperties masterDataSourceProperties(){
return new DataSourceProperties();
}
@Bean(name = "masterDataSource")
@ConfigurationProperties(prefix = "spring.datasource.master")
public DataSource masterDataSource() {
//return masterDataSourceProperties().initializeDataSourceBuilder().build();
return DataSourceBuilder.create().build();
}
@Bean(name = "masterSqlSessionFactory")
@Primary
public SqlSessionFactory masterSqlSessionFactory(@Qualifier("masterDataSource") DataSource dataSource) throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper1/*.xml"));
return bean.getObject();
}
@Bean(name = "masterTransactionManager")
@Primary
public DataSourceTransactionManager masterTransactionManager(@Qualifier("masterDataSource") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
@Bean(name = "masterSqlSessionTemplate")
@Primary
public SqlSessionTemplate masterSqlSessionTemplate(@Qualifier("masterSqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
return new SqlSessionTemplate(sqlSessionFactory);
}
}
最后,根据相关的配置 增加对应的包,再编写相应的Dao(与上面的UserMapper.java一样,只是所放置的目录不同)和mapper.xml配置文件即可。
测试,只查询出各自库中的数据,说明多数据源已经配置成功:
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
@WebAppConfiguration
public class BatisUserTests {
private Logger logger = LoggerFactory.getLogger(HelloBootController.class);
@Autowired
private BatisUserMapper userMapper;
@Autowired
private UserMasterMapper masterMapper;
@Autowired
private UserSlaveMapper slaveMapper;
@Before
public void setUp() throws Exception {
}
@Test
public void findByDiffDataSource() throws Exception {
User user = masterMapper.getUserById(6l);
logger.debug("查询出来的user:{}", JSON.toJSONString(user));
user = slaveMapper.getUserById(6l);
logger.debug("查询出来的user:{}", JSON.toJSONString(user));
user = userMapper.getUserById(6l);
logger.debug("查询出来的user:{}", JSON.toJSONString(user));
}
}
附,userMapper.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.xps.sc.springbootdemo.mapper.BatisUserMapper" >
<resultMap id="BaseResultMap" type="com.xps.sc.springbootdemo.entity.User" >
<id column="user_id" property="userId" jdbcType="BIGINT" />
<result column="user_name" property="userName" jdbcType="VARCHAR" />
<result column="pass_word" property="passWord" jdbcType="VARCHAR" />
<result column="email" property="email" jdbcType="VARCHAR"/>
<result column="nick_name" property="nickName" jdbcType="VARCHAR" />
<result column="reg_time" property="regTime" jdbcType="VARCHAR" />
<result column="create_time" property="createTime" jdbcType="TIMESTAMP" />
</resultMap>
<sql id="Base_Column_List" >
user_id, user_name, pass_word, nick_name, email,reg_time,create_time,nick_name
</sql>
<select id="getUserList" resultMap="BaseResultMap" parameterType="java.lang.String">
SELECT
<include refid="Base_Column_List" />
FROM t_test_user
where nick_name= #{nickName,jdbcType=VARCHAR}
</select>
<insert id="insertUser" parameterType="com.xps.sc.springbootdemo.entity.User" >
insert into T_TEST_USER(user_id,user_name,nick_name,pass_word,email,reg_time,create_time)
values(#{userId,jdbcType=BIGINT},#{userName,jdbcType=VARCHAR},
#{nickName,jdbcType=VARCHAR},#{passWord,jdbcType=VARCHAR},#{email,jdbcType=VARCHAR},
#{regTime,jdbcType=VARCHAR},#{createTime,jdbcType=TIMESTAMP})
</insert>
<update id="updateUser" parameterType="com.xps.sc.springbootdemo.entity.User" >
UPDATE T_TEST_USER
<set>
<if test="userName != null" >
user_name = #{userName,jdbcType=VARCHAR},
</if>
<if test="nickName != null" >
nick_name = #{nickName,jdbcType=VARCHAR},
</if>
<if test="passWord != null" >
pass_word = #{passWord,jdbcType=VARCHAR},
</if>
<if test="email != null" >
email = #{email,jdbcType=VARCHAR},
</if>
<if test="regTime != null" >
reg_time = #{regTime,jdbcType=VARCHAR},
</if>
<if test="createTime != null" >
create_time = #{createTime,jdbcType=TIMESTAMP},
</if>
</set>
where user_id = #{userId,jdbcType=BIGINT}
</update>
<delete id="delete" parameterType="java.lang.Long" >
DELETE FROM T_TEST_USER WHERE user_id = #{userId,jdbcType=BIGINT}
</delete>
</mapper>
总结
mybatis一般用于比较大型的项目,简单的sql无法满足业务需要。虽然说jpa也可以写出复杂业务的sql,但用相对于mybatis没有后者直接写sql的方式简单,易读懂,易修改和维护。关于多数据源的配置主要的思路是针对不同的package使用不同的数据源。当然,还可以使用spring或spring aop等方式来配置多数据。
感谢以下博主的分享,学习中:http://www.ityouknow.com/springboot/2016/11/25/spring-boot-multi-mybatis.html