内容简介:MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Ordinary Java Object,普通的 Java对象)映射成数据库中的记录。换句话说,我觉得利用mybatis整合持久层要方便很多,比起以前编写jdbc代码操作数据库的一些连接,简直不要太爽。创建一个简单的具有start-w
SpringBoot系列(五)Mybatis整合
1. Mybatis简介
MyBatis 是一款优秀的持久层框架,它支持定制化 SQL 、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Ordinary Java Object,普通的 Java对象)映射成数据库中的记录。
换句话说,我觉得利用mybatis整合持久层要方便很多,比起以前编写jdbc代码操作数据库的一些连接,简直不要太爽。
2. 项目创建
创建一个简单的具有start-web依赖的SpringBoot项目,然后添加mybatis相关的依赖。
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
依赖下载完之后,在yml文件,也可以是properties文件里面配置连接数据库的相关配置。
spring:
datasource:
url: jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf8&allowMultiQueries=true&serverTimezone=GMT%2B8
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
然后我们在数据库mybatis下面创建一个student表
CREATE TABLE `student`( `id` int(10) NOT NULL AUTO_INCREMENT COMMENT '唯一标识id', `name` varchar(30) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT '姓名', `age` int(3) NOT NULL COMMENT '年龄', PRIMARY KEY (`id`) USING BTREE ) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8 COLLATE = utf8_bin ROW_FORMAT = Dynamic;
完成项目初始配置。
3. entity 实体类代码
/**
* (Student)实体类
*
* @author 全栈学习笔记
* @since 2020-04-14 11:39:10
*/
public class Student {
private static final long serialVersionUID = -91969758749726312L;
/**
* 唯一标识id
*/
private Integer id;
/**
* 姓名
*/
private String name;
/**
* 年龄
*/
private Integer age;
}
以上省略了get,以及set方法。
4. dao层代码
package com.example.demomybatis.dao;
import com.example.demomybatis.entity.Student;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import java.util.List;
/**
* (Student)表数据库访问层
*
* @author 全栈学习笔记
* @since 2020-04-14 11:39:18
*/
@Mapper
@Repository
public interface StudentDao {
/**
* 通过ID查询单条数据
*
* @param id 主键
* @return 实例对象
*/
Student queryById(Integer id);
/**
* 查询指定行数据
*
* @param offset 查询起始位置
* @param limit 查询条数
* @return 对象列表
*/
List<Student> queryAllByLimit(@Param("offset") int offset, @Param("limit") int limit);
/**
* 通过实体作为筛选条件查询
*
* @param student 实例对象
* @return 对象列表
*/
List<Student> queryAll(Student student);
/**
* 新增数据
*
* @param student 实例对象
* @return 影响行数
*/
int insert(Student student);
/**
* 修改数据
*
* @param student 实例对象
* @return 影响行数
*/
int update(Student student);
/**
* 通过主键删除数据
*
* @param id 主键
* @return 影响行数
*/
int deleteById(Integer id);
}
代码说明:dao层属于数据访问层,与mybatis 的xml文件相互映射,实现SQL语句的功能。
注解说明:在 dao 层的类需要加上 @Mapper 的注解,这个注解是 mybatis 提供的,标识这个类是一个数据访问层的bean,并交给spring容器管理。并且可以省去之前的xml映射文件。在 编译 的时候,添加了这个类也会相应的生成这个类的实现类。
如果你是用的idea,在 serviceImpl 中使用 @Autowired 注入bean的时候,idea会报错,但是不影响运行,报错是因为 @mapper 不是spring提供的,当需要自动注入这个bean的时候idea不能 预检测 到这个bean是否可以注入到容器中,不知道新版的idea会不会有这种问题。如果想消除这个报错,你可以在dao层的类上面加上一个 @Repository ,这个注解是spring提供的,这样就可以预检测到mapper的bean是可以注册到spring容器里面的。
你会发现在代码中,有的接口的参数是带了 @Param 这个注解的,有的参数是没有这个注解的。如果你只有 一个参数 ,这个注解可要可不要。当你有 两个及其以上的注解 时,你就需要用这个注解了,不然在对应的xml文件,它分辨不出来这个参数是哪一个就会报错,用这个注解的意思就是说 标识这个参数的名称,以便让接受参数的一方更好的找到并利用这个值。
5. service层代码
package com.example.demomybatis.service;
import com.example.demomybatis.entity.Student;
import java.util.List;
/**
* (Student)表服务接口
*
* @author 全栈学习笔记
* @since 2020-04-14 11:39:19
*/
public interface StudentService {
/**
* 通过ID查询单条数据
*
* @param id 主键
* @return 实例对象
*/
Student queryById(Integer id);
/**
* 查询多条数据
*
* @param offset 查询起始位置
* @param limit 查询条数
* @return 对象列表
*/
List<Student> queryAllByLimit(int offset, int limit);
/**
* 新增数据
*
* @param student 实例对象
* @return 实例对象
*/
Student insert(Student student);
/**
* 修改数据
*
* @param student 实例对象
* @return 实例对象
*/
Student update(Student student);
/**
* 通过主键删除数据
*
* @param id 主键
* @return 是否成功
*/
boolean deleteById(Integer id);
}
代码说明:这是服务层的接口,serviceImpl对应服务层接口的实现。
6. serviceImpl层代码
package com.example.demomybatis.service.impl;
import com.example.demomybatis.entity.Student;
import com.example.demomybatis.dao.StudentDao;
import com.example.demomybatis.service.StudentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
/**
* (Student)表服务实现类
*
* @author 全栈学习笔记
* @since 2020-04-14 11:39:19
*/
@Service("studentService")
public class StudentServiceImpl implements StudentService {
@Autowired
private StudentDao studentDao;
/**
* 通过ID查询单条数据
*
* @param id 主键
* @return 实例对象
*/
@Override
public Student queryById(Integer id) {
return this.studentDao.queryById(id);
}
/**
* 查询多条数据
*
* @param offset 查询起始位置
* @param limit 查询条数
* @return 对象列表
*/
@Override
public List<Student> queryAllByLimit(int offset, int limit) {
return this.studentDao.queryAllByLimit(offset, limit);
}
/**
* 新增数据
*
* @param student 实例对象
* @return 实例对象
*/
@Override
public Student insert(Student student) {
this.studentDao.insert(student);
return student;
}
/**
* 修改数据
*
* @param student 实例对象
* @return 实例对象
*/
@Override
public Student update(Student student) {
this.studentDao.update(student);
return this.queryById(student.getId());
}
/**
* 通过主键删除数据
*
* @param id 主键
* @return 是否成功
*/
@Override
public boolean deleteById(Integer id) {
return this.studentDao.deleteById(id) > 0;
}
}
代码说明: @Service 标识这个bean是service层的,也就是服务层,并交给spring容器管理。参数的value属性是这个bean的名称,也可以不写,默认为类名。
这里我们可以说一下, @Resource 与 @Autowired ,前面我们在 serviceImpl 里面需要用到 dao 层的方法的时候,不是直接new一个对象,在哪需要就在哪new,而是利用注解,实现自定注入装配,利用spring容器管理这些bean,这样写出来的代码是松耦合的,类之间的耦合度更低,维护性就相对提高了。
@Resource与 @Autowired 是可以起到一个相同的作用。根据包名就可以看到,他们不是一个包里面的。区别如下:
- @Autowired 默认按 类型 装配,默认情况下必须要求依赖对象必须存在,如果要允许null值,可以设置它的required属性为false,如:@Autowired(required=false) ,这个注解是属于 spring 的,如果我们想使用名称装配可以结合 @Qualifier 注解进行使用。
- @Resource 默认按照名称进行装配,名称可以通过name属性进行指定,如果 没有指定name属性 ,当注解写在字段上时, 默认取字段名进行安装名称查找 ,如果注解写在setter方法上默认取属性名进行装配。当找不到与名称匹配的bean时才按照类型进行装配。但是需要注意的是,如果name属性一旦指定,就只会按照名称进行装配。 这个注解属于J2EE的 。
7. mapper层代码
所谓的mapper层,就是xml文件,与dao层对应的。
<?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.example.demomybatis.dao.StudentDao">
<resultMap type="com.example.demomybatis.entity.Student" id="StudentMap">
<result property="id" column="id" jdbcType="INTEGER"/>
<result property="name" column="name" jdbcType="VARCHAR"/>
<result property="age" column="age" jdbcType="INTEGER"/>
</resultMap>
<!--查询单个-->
<select id="queryById" resultMap="StudentMap">
select
id, name, age
from mybatis.student
where id = #{id}
</select>
<!--查询指定行数据-->
<select id="queryAllByLimit" resultMap="StudentMap">
select
id, name, age
from mybatis.student
limit #{offset}, #{limit}
</select>
<!--通过实体作为筛选条件查询-->
<select id="queryAll" resultMap="StudentMap">
select
id, name, age
from mybatis.student
<where>
<if test="id != null">
and id = #{id}
</if>
<if test="name != null and name != ''">
and name = #{name}
</if>
<if test="age != null">
and age = #{age}
</if>
</where>
</select>
<!--新增所有列-->
<insert id="insert" keyProperty="id" useGeneratedKeys="true">
insert into mybatis.student(name, age)
values (#{name}, #{age})
</insert>
<!--通过主键修改数据-->
<update id="update">
update mybatis.student
<set>
<if test="name != null and name != ''">
name = #{name},
</if>
<if test="age != null">
age = #{age},
</if>
</set>
where id = #{id}
</update>
<!--通过主键删除-->
<delete id="deleteById">
delete from mybatis.student where id = #{id}
</delete>
</mapper>
这里面对应了SQL的增删改查语句,然后在dao层的方法,对应了每一个SQL语句,这里面SQL语句的id,对应dao层的每一个接口方法。
默认的配置是检测不到这个xml文件的,然后我们需要做以下的配置。
我把xml文件放在 resources文件夹下面的dao 文件夹下面。
然后我们在yml里面加上以下配置。
mybatis: type-aliases-package: com.example.demomybatis.entity mapper-locations: classpath:dao/*Mapper.xml
8. controller层代码
controller层的代码我们是用来测试的,一般也是返回数据给前端的地方。
package com.example.demomybatis.controller;
import com.example.demomybatis.entity.Student;
import com.example.demomybatis.service.StudentService;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
/**
* (Student)表控制层
*
* @author 全栈学习笔记
* @since 2020-04-14 11:39:20
*/
@RestController
@RequestMapping("student")
public class StudentController {
/**
* 服务对象
*/
@Resource
private StudentService studentService;
/**
* 通过主键查询单条数据
*
* @param id 主键
* @return 单条数据
*/
@GetMapping("selectOne")
public Student selectOne(Integer id) {
return this.studentService.queryById(id);
}
}
代码说明: @RestController 这个注解等效于 @Controller 加上 @ResponseBody ,添加了这个注解就是让这个类返回json串,这是spring内部提供的json解析。 @RequesMapping 注解是一个地址映射的注解。就是根据这个地址,可以找到这个方法,这个类,注解到类上,就相当于方法的父类地址。
测试一下。我们先在数据库里面添加一条数据。
insert into student(id,name,age) VALUES(2,'全栈学习笔记',22)
然后在浏览器输入:localhost:8088/student/selectOne?id=2 就可以看到我们拿到的数据了。端口配置根据自己项目而定。
好了,这一期的mybatis整合就到这里,有兴趣的可以 wx search 全栈学习笔记 ,给个关注,精彩美文每天推送到你的手中!
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- SpringBoot整合MybatisPlus的简单教程(简单整合)
- springmvc教程--整合mybatis开发(spring+springMVC+mybatis整合开发)
- springboot整合springsecurity从Hello World到源码解析(五):springsecurity+jwt整合restful服务
- SSM整合搭建(二)
- SSM整合
- Storm 整合 Hbase
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
数字时代的营销战略
曹虎、王赛、乔林、【美】艾拉·考夫曼 / 机械工业出版社 / 2017-1 / 99.00元
菲利普•科特勒说,市场比市场营销变得更快(Market changes faster than Marketing),在这个变革的时代,从硅谷、波士顿到北京、上海、深圳,我们正在重新定义公司,重新定义组织,重新定义战略;同样地,营销亦需要重新定义。 从本质上讲,营销战略只有两个时代:实体时代与比特时代,也可称为工业时代与数字时代。从5年前开始,第二个时代正在向未来20年展开画卷,数字创新型企......一起来看看 《数字时代的营销战略》 这本书的介绍吧!
URL 编码/解码
URL 编码/解码
UNIX 时间戳转换
UNIX 时间戳转换