使用Mybatis作为ORM框架:
如今的接口开发中,ORM框架是我们操作数据库不可或缺的一部分,而其中Hibernate与Mybatis是最为常用的两大框架,其中Hibernate学习周期较长,因为它使用HQL语言代替SQL,以对象为单位操作数据库。而Mybatis使用SQL,也是最为直观的,绝大多数的使用Mysql的互联网公司使用Mybatis作为ORM框架,今天,我们就来看一下Mybatis在SpringBoot中的整合~~
引入Mybatis依赖:
<dependency>
<groupId>org.mybatis.spring.bootgroupId>
<artifactId>mybatis-spring-boot-starterartifactId>
<version>1.2.0version>
dependency>
在引入Mybatis依赖后,这里有个小贴士,我们可以不再引入spring-boot-starter-jdbc的依赖,因为Mybatis的依赖已经存在JDBC依赖了。
添加数据库配置信息:
spring:
datasource:
url: jdbc:mysql://localhost:3306/blog
username: root
password: 123
driver-class-name: com.mysql.jdbc.Driver
type: com.alibaba.druid.pool.DruidDataSource
这里使用的数据库配置信息和我们之前使用JDBC时是一致的,无需更改。
接下来我们只需在我们的代码中直接使用即可。
使用注解配置:
首先我们先使用注解方式来配置Mybatis,我们还是使用之前用户的增删改查四种操作,我们重新建立controller,service以及dao:
controller:
@RestController
@RequestMapping("/mybatis")
public class MybatisController {
@Autowired
private MybatisService service;
/**
* 更新用户信息
* @param user_id 用户ID
* @param nickName 昵称
*/
@PutMapping("/updateUser/{id}")
public void updateUser(@PathVariable("id") String user_id, @RequestParam("nickName") String nickName){
service.updateUser(user_id,nickName);
}
/**
* 获取用户信息
* @param id 用户Id
* @return
*/
@GetMapping("/getUser/{id}")
public UserInfo getUser(@PathVariable("id") Integer id){
return service.getUser(id);
}
/**
* 删除用户
* @param tel
*/
@DeleteMapping("/deleteUserByUserId/{tel}")
public void deleteUserByUserId(@PathVariable("tel") String tel){
UserInfo user = new UserInfo();
user.setTel(tel);
service.deleteUserByUserId(user);
}
/**
* 使用@RequestBody获取参数,用map类型接收,再取出
* @param reqMap
*/
@PostMapping("/createUserByMap")
public void createUserByMap(@RequestBody Map reqMap){
service.createUser(reqMap);
}
}
service:
@Service
public class MybatisService {
@Autowired
private MybatisUserAnnotaionMapper annotaionMapper;
public void updateUser(String user_id, String nickName) {
annotaionMapper.updateUser(user_id,nickName);
}
public UserInfo getUser(Integer id) {
return annotaionMapper.getUser(id);
}
public void deleteUserByUserId(UserInfo userInfo) {
annotaionMapper.deleteUserByUserId(userInfo);
}
public void createUser(Map reqMap) {
annotaionMapper.createUser(reqMap);
}
}
dao:
@Mapper
public interface MybatisUserAnnotaionMapper {
@Insert("INSERT INTO blog.tp_user(tel,password,nickname,secret) VALUES (#{tel},md5(#{pwd}),#{tel},'')")
void createUser(Map reqMap);
@Select("select tel,nickname,password FROM blog.tp_user WHERE user_id = #{id}")
UserInfo getUser(@Param("id") Integer id);
@Update("UPDATE blog.tp_user SET nickname = #{nickName} WHERE user_id = #{userId}")
void updateUser(@Param("userId") String user_id, @Param("nickName") String nickName);
@Delete("DELETE FROM blog.tp_user WHERE tel = #{tel}")
void deleteUserByUserId(UserInfo userInfo);
}
在这里要说明的是,我们可以使用@param对每一个参数进行传值,也可以直接传入Map类型的参数,只需在#{}内写入MAP的KEY,同样我们也可以使用对象进行传值,#{}内写入的是对象的属性名。
我们完成上面代码后使用POSTMAN测试一下:
我们发现报错了,显示未知错误,我们来看一下控制台的输出日志:
可以看到,报错的内容是返回为空,其实这时候数据库已经插入了该用户的信息,只是因为我们的返回值是void所以得不到一个正确的返回报文。
我们按照上一次讲的统一结果管理来重写下我们的controller层:
@Autowired
private MybatisService service;
@Autowired
private ExceptionHandle handle;
/**
* 更新用户信息
* @param user_id 用户ID
* @param nickName 昵称
*/
@PutMapping("/updateUser/{id}")
public Result updateUser(@PathVariable("id") String user_id, @RequestParam("nickName") String nickName){
Result result = ResultUtil.success();
try {
service.updateUser(user_id,nickName);
}catch (Exception e){
result = handle.exceptionGet(e);
}
return result;
// service.updateUser(user_id,nickName);
}
/**
* 获取用户信息
* @param id 用户Id
* @return
*/
@GetMapping("/getUser/{id}")
public Result getUser(@PathVariable("id") Integer id){
Result result = ResultUtil.success();
try {
result.setData(service.getUser(id));
}catch (Exception e){
result = handle.exceptionGet(e);
}
return result;
// return service.getUser(id);
}
/**
* 删除用户
* @param tel
*/
@DeleteMapping("/deleteUserByUserId/{tel}")
public Result deleteUserByUserId(@PathVariable("tel") String tel){
Result result = ResultUtil.success();
try {
UserInfo user = new UserInfo();
user.setTel(tel);
service.deleteUserByUserId(user);
}catch (Exception e){
result = handle.exceptionGet(e);
}
return result;
// UserInfo user = new UserInfo();
// user.setTel(tel);
// service.deleteUserByUserId(user);
}
/**
* 使用@RequestBody获取参数,用map类型接收,再取出
* @param reqMap
*/
@PostMapping("/createUserByMap")
public Result createUserByMap(@RequestBody Map reqMap){
Result result = ResultUtil.success();
try {
service.createUser(reqMap);
}catch (Exception e){
result = handle.exceptionGet(e);
}
return result;
// service.createUser(reqMap);
}
我们再执行就可以看到返回结果为success了:
其中特别获取数据也是没问题的,封装在我们之前定义的date中了,另外值得说一下的是我把delete方法中的条件改为tel了,大家测试的时候别继续传id了哦~~~
贴士:
使用注解配置时返回的结果如果是一个对象且对象名和数据库字段不统一时我们可以使用@Results和@Result来绑定属性,也可以在SQL中使用 AS 属性名来绑定对象属性。
使用XML配置:
使用XML配置Mybatis是我们从SpringMVC就开始用的一种方式,也是我比较推荐的方式,因为注解配置虽然方便,但不是很利于日后的维护,而且如果其他人修改你的代码,一堆SQL很难发现问题,比如一个半角逗号写成全角逗号…………
如果你和我一样使用IDEA作为开发工具的话,需要把XML放在resources下,因为IDEA编译是在resources下作为静态文件的,如果你写在java目录下,运行时是会报Invalid bound statement (not found)找不到绑定SQL的错误的。当然,我们其实还是有办法来改变IDEA的这个习惯的,我们稍等一会会来谈这个问题。
我们还是把之前的controller,service,dao都复制一遍(我真的很懒……),只是指向XML哦诶址的dao层而已,再创建一个XML文件放在resources下的mapper目录,其中写我们的SQL:
<mapper namespace="com.zzp.dao.impl.MybatisUserXMLMapper">
<insert id="createUser" parameterType="java.util.Map">
INSERT INTO blog.tp_user(tel,password,nickname,secret) VALUES (#{tel},md5(#{pwd}),#{tel},'')
insert>
<update id="updateUser">
UPDATE blog.tp_user SET nickname = #{nickName} WHERE user_id = #{userId}
update>
<select id="getUser" resultType="com.zzp.pojo.UserInfo">
SELECT tel,nickname,password FROM blog.tp_user WHERE user_id = #{id}
select>
<delete id="deleteUserByUserId">
DELETE FROM blog.tp_user WHERE tel = #{tel}
delete>
mapper>
关于namespace以及XML的文件名等细节我就不具体说了,和SpringMVC中是一致的。我们完成后测试一下发现报错了,找不到绑定的SQL,这就该说下我们关于Mybatis的一些配置了,如果你不想在运行期间有那么多乱七八糟的错误的话,最好就是按照我的配置来做以下的更改:
1.在yml中写入xml所在位置,智利我是放在resources目录下的:
mybatis:
mapper-locations: classpath:mapper/*.xml
2.在启动类上加入雪要扫描的dao层
@MapperScan(basePackages = "com.zzp.dao")
3.给你的dao层加入@Repository注解,让Spring能够扫描到
完成以上三点后我们再一次测试,就可以得到正常结果啦~~~
彩蛋:
在XML中,我们无法直接从dao层进去XML中SQL语句中,但是如果你使用IDEA的话,就可以通过插件实现这一功能,在IDEA插件中搜索Mybatis就有啦:
安装后就可以直接进入SQL啦,并且还会提示你该方法写没写SQL。