整合 MyBatis 有两种方式:
1) 使用 mybatis 官方提供的 Spring Boot 整合包实现。
2) 使用 mybatis-spring 整合的方式,也就是传统的方式(推荐,此方式容易控制 MyBatis 的配置)。
具体参考https://www.cnblogs.com/moonlightL/p/8066018.html
此处我们采用官方整合包
1.项目结构
2.添加依赖
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
这里不引入spring-boot-starter-jdbc依赖,是由于mybatis-spring-boot-starter中已经包含了此依赖,并且提供:
- 自动检测现有的DataSource
- 将创建并注册SqlSessionFactory的实例,该实例使用SqlSessionFactoryBean将该DataSource作为输入进行传递
- 将创建并注册从SqlSessionFactory中获取的SqlSessionTemplate的实例。
- 自动扫描mappers,将它们链接到SqlSessionTemplate并将其注册到Spring上下文,以便将它们注入到bean中
3.数据源配置
数据源的配置可以使用默认配置或者自定义配置,与【Spring Boot系列学习】06.数据存储SQL-关系型数据库JdbcTemplate中的数据源的配置一样。默认如下
##配置数据源
spring.datasource.url=jdbc:mysql://localhost:3306/db_study?useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8
spring.datasource.username = root
spring.datasource.password = 123456
spring.datasource.driver-class-name = com.mysql.cj.jdbc.Driver
4.代码:与前文【Spring Boot系列学习】06.数据存储SQL-关系型数据库JdbcTemplate中代码相同。
实体对象
public class User {
private String id;
private String usercode;
private String username;
private String password;
private String salt;
private String locked;
//省略get、set方法和toString方法
}
controller层
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
private Logger logger = LoggerFactory.getLogger(this.getClass());
@RequestMapping("/mybatislist")
public String mybatislist(){
logger.info("-------------userController mybatislist start-------------");
List<JpaUser> list = userService.getAllUsers3();
logger.info("-------------userController mybatislist end-------------");
return list.toString();
}
}
service接口及实现类
@Service("userService")
public class UserServiceImpl implements UserService{
@Autowired
private UserMapper userMapper;
private Logger logger = LoggerFactory.getLogger(this.getClass());
@Override
public List<User> getAllUsers3(){
logger.info("-------------mybatis UserServiceImpl getAllUsers3 start-------------");
List<User> list = userMapper.getAllUsers3();
logger.info("-------------mybatis UserServiceImpl getAllUsers3 start-------------");
return list;
}
}
5.集成MyBatis
有两种集成方式,分别为注解方式以及XML配置方式
5.1注解方式
只要定义一个dao接口,然后sql语句通过注解写在接口方法上。最后给这个接口添加@Mapper注解或者在启动类上添加@MapperScan(“com.bj.study.mapper”)注解都行。
@Component
@Mapper
public interface UserMapper {
/**新增一个用户 */
@Insert("insert into sys_user(id, usercode,username,password,salt,locked) values(#{id},#{usercode},#{username},#{password},#{salt},#{locked})")
void create(User user);
/** 根据name删除一个用户*/
@Delete("delete from sys_user where username=#{name}")
void deleteByName(String name);
/** 获取所有用户信息 */
@Select("select * from sys_user ")
List<User> getAllUsers3();
}
注意:
- ①简单的语句只需要使用@Insert、@Update、@Delete、@Select这4个注解即可,
- ②但是有些复杂点需要动态SQL语句,就需要使用@InsertProvider、@UpdateProvider、@DeleteProvider、@SelectProvider等注解。
@Component
@Mapper
public interface UserMapper {
@DeleteProvider(type = UserSqlBuilder.class, method = "deleteByids")
int deleteByIds(@Param("ids") String[] ids);
@SelectProvider(type = UserSqlBuilder.class, method = "queryUserByParams")
List<User> queryUserList(Map<String, Object> params);
class UserSqlBuilder {
public String queryUserByParams(final Map<String, Object> params) {
StringBuffer sql =new StringBuffer();
sql.append("select * from sys_user where 1=1");
if(!StringUtil.isNull((String)params.get("username"))){
sql.append(" and username like '%").append((String)params.get("username")).append("%'");
}
if(!StringUtil.isNull((String)params.get("usercode"))){
sql.append(" and usercode like '%").append((String)params.get("usercode")).append("%'");
}
System.out.println("查询sql=="+sql.toString());
return sql.toString();
}
//删除的方法
public String deleteByids(@Param("ids") final String[] ids){
StringBuffer sql =new StringBuffer();
sql.append("DELETE FROM sys_user WHERE id in(");
for (int i=0;i<ids.length;i++){
if(i==ids.length-1){
sql.append(ids[i]);
}else{
sql.append(ids[i]).append(",");
}
}
sql.append(")");
return sql.toString();
}
}
针对复杂SQL语句的注解,SQL注解允许指定一个类名(type)和一个方法(method)在执行时来返回运行所需的动态SQL。
5.2XML配置方式
xml配置方式保持映射文件的老传统,优化主要体现在不需要实现dao是实现层,系统会自动根据方法名在映射文件中找对应的sql。其实现如下几步
5.2.1Dao接口编写
@Mapper
public interface UserMapper {
void create(User user);
/** 根据name删除一个用户*/
void deleteByName(String name);
/** 获取所有用户信息 */
List<User> getAllUsers4();
}
5.2.2配置文件新增信息
#指定bean所在包
mybatis.type-aliases-package=com.bj.study.springboot.entity
#指定映射文件
mybatis.mapperLocations=classpath:mapper/*.xml
5.2.3添加映射文件
在resources文件夹下新建mapper文件夹,在mapper目录下新建User.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.bj.study.springboot.dao.UserMapper">
<select id="getAllUsers4" resultType="com.bj.study.springboot.entity.User">
SELECT * FROM sys_user
</select>
<insert id="create" parameterType="com.bj.study.springboot.entity.User" >
INSERT INTO sys_user (id,usercode,username,password,salt,locked) VALUES
(#{id}, #{usercode}, #{username}, #{password}, #{salt}, #{locked})
</insert>
<delete id="deleteByName" parameterType="java.lang.String" >
DELETE FROM sys_user WHERE username=#{username}
</delete>
</mapper>
此处启动项目报异常
framework.beans.BeanInstantiationException: Failed to instantiate [com.bj.study.springboot.dao.UserMapper]: Specified class is an interface
原因是我将俩部分代码放一起,在service层中注入mapper时,导入的类错误引发的冲突。但通过xml方式还是报该异常。再次检查。发现是因为mapper同名类有俩个导致异常,更名后可正常启动并访问。