Spring Boot(3)--使用Mybatis
本章內容
- 新增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