赞
踩
平凡也就两个字: 懒和惰;
成功也就两个字: 苦和勤;
优秀也就两个字: 你和我。
跟着我从0学习JAVA、spring全家桶和linux运维等知识,带你从懵懂少年走向人生巅峰,迎娶白富美!
关注微信公众号【 IT特靠谱 】,每天都会分享技术心得~
持久层框架有很多,常见的持久层框架实现有spring-data-jpa、mybatis(mybatis-plus)和hibernate等。本教程将以mybatis持久层框架为例,详述springboot整合mybatis框架的过程,并最终通过注解和xml两种方式实现数据增删改查(CRUD)操作。
mybatis官方文档中的解释:MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。
也就是mybatis对数据库操作做了大量封装,使得开发者拿来即用,减少开发成本。同时mybatis支持注解和xml两种映射方式,也提供对原生sql的支持。
创建springboot项目的过程非常简单,此处省略。下面是已经建好的springboot项目的目录结构。
项目名称:mybatis-demo
略!关注微信公众号:IT特靠谱,回复"我要mysql安装教程"免费领取吧~
mysql数据库连接信息如下:
- url: jdbc:mysql://localhost:3306/test_mybatis?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=UTC
- username: root
- password: root
创建的数据库表:user_t, 给数据库表user_t添加唯一索引。索引字段为:mobile,索引名:udx_user_mobile。创建表的sql脚本如下:
- CREATE TABLE `user_t` (
- `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键id',
- `mobile` varchar(11) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '用户手机号',
- `user_name` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '用户名',
- `age` tinyint(4) NULL DEFAULT NULL COMMENT '年龄',
- `create_time` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
- `update_time` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP(0) COMMENT '最后更新时间',
- PRIMARY KEY (`id`) USING BTREE,
- UNIQUE INDEX `udx_user_mobile`(`mobile`) USING BTREE COMMENT '用户手机号唯一索引'
- ) ENGINE = InnoDB AUTO_INCREMENT = 10 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
我们先往user_t数据库表中插入如下4条数据,用于查询测试!
- INSERT INTO `user_t` VALUES (1, '13111111111', '张三', 10, '2020-10-22 15:58:51', '2020-10-22 18:26:31');
- INSERT INTO `user_t` VALUES (2, '13555555555', '李四', 20, '2020-10-22 15:58:59', '2020-10-22 18:26:33');
- INSERT INTO `user_t` VALUES (3, '13666666666', '王五', 20, '2020-10-22 15:59:15', '2020-10-22 18:26:35');
- INSERT INTO `user_t` VALUES (4, '15222222222', '小六', 40, '2020-10-22 17:30:21', '2020-10-22 18:26:39');
项目pom.xml文件中添加mysql数据库驱动、数据库连接池和mybatis相关依赖包。
- <!--持久化api依赖包:与数据库交互,比如Java bean和数据库表的对应关系-->
- <dependency>
- <groupId>javax.persistence</groupId>
- <artifactId>persistence-api</artifactId>
- <version>1.0</version>
- </dependency>
-
- <!--mybatis依赖包-->
- <dependency>
- <groupId>org.mybatis.spring.boot</groupId>
- <artifactId>mybatis-spring-boot-starter</artifactId>
- <version>2.1.1</version>
- </dependency>
-
- <!-- mybatis通用Mapper依赖包:提供了基本的增删改查Mapper -->
- <dependency>
- <groupId>tk.mybatis</groupId>
- <artifactId>mapper-spring-boot-starter</artifactId>
- <version>1.2.4</version>
- </dependency>
-
- <!--mysql数据库驱动包-->
- <dependency>
- <groupId>mysql</groupId>
- <artifactId>mysql-connector-java</artifactId>
- <version>5.1.35</version>
- </dependency>
-
- <!--Druid数据库连接池-->
- <dependency>
- <groupId>com.alibaba</groupId>
- <artifactId>druid-spring-boot-starter</artifactId>
- <version>1.1.10</version>
- </dependency>
在application.properties或application.yml配置文件中添加如下配置。
1)配置数据源
2)指定Mapper.xml资源文件所在路径
3)开启sql日志
- #mysql配置数据源
- spring:
- datasource:
- driver-class-name: com.mysql.jdbc.Driver
- url: jdbc:mysql://localhost:3306/test_mybatis?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=UTC
- username: root
- password: root
-
- #指定Mapper.xml所在路径
- mybatis:
- mapper-locations: classpath:mapping/*Mapper.xml
- type-aliases-package: com.hc.mybatisdemo.entity
- #打印sql日志
- logging:
- level:
- com:
- hc:
- mybatisdemo:
- mapper: debug
- //注意这里需要引入tk.mybatis这个依赖
- import tk.mybatis.spring.annotation.MapperScan;
- import org.springframework.boot.SpringApplication;
- import org.springframework.boot.autoconfigure.SpringBootApplication;
-
- @SpringBootApplication
- @MapperScan("com.hc.mybatisdemo.mapper") //扫描的mapper包路径
- public class MybatisDemoApplication {
-
- public static void main(String[] args) {
- SpringApplication.run(MybatisDemoApplication.class, args);
- }
- }
实体类: User.java
- import com.fasterxml.jackson.annotation.JsonFormat;
- import java.util.Date;
- import javax.persistence.Column;
- import javax.persistence.GeneratedValue;
- import javax.persistence.GenerationType;
- import javax.persistence.Id;
- import javax.persistence.Table;
- import lombok.AllArgsConstructor;
- import lombok.Builder;
- import lombok.Data;
- import lombok.NoArgsConstructor;
- import org.springframework.format.annotation.DateTimeFormat;
-
- /**
- * 用户实体类
- */
- @Data
- @Builder
- @NoArgsConstructor
- @AllArgsConstructor
- @Table(name = "user_t")
- public class User {
-
- /**
- * 主键id
- */
- @Id
- @GeneratedValue(strategy = GenerationType.IDENTITY)
- @Column(name = "id")
- private Long id;
-
- /**
- * 用户手机号
- */
- @Column(name = "mobile")
- private String mobile;
-
- /**
- * 用户名
- */
- @Column(name = "user_name")
- private String userName;
-
- /**
- * 年龄
- */
- @Column(name = "age")
- private Integer age;
-
- /**
- * 创建时间
- */
- @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") //写入数据库时格式化
- @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8") //数据库查询后json格式化
- @Column(name = "create_time")
- private Date createTime;
-
- /**
- * 创建时间
- */
- @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
- @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
- @Column(name = "update_time")
- private Date updateTime;
- }
Mapper接口类:UserMapper.java
- import com.hc.mybatisdemo.entity.User;
- import java.util.List;
- import org.apache.ibatis.annotations.Delete;
- import org.apache.ibatis.annotations.Insert;
- import org.apache.ibatis.annotations.Mapper;
- import org.apache.ibatis.annotations.Param;
- import org.apache.ibatis.annotations.Select;
- import org.apache.ibatis.annotations.Update;
- import tk.mybatis.mapper.common.BaseMapper;
- import tk.mybatis.mapper.common.MySqlMapper;
-
- /**
- * UserMapper接口
- */
- @Mapper
- public interface UserMapper extends BaseMapper<User>, MySqlMapper<User> {
-
- /**
- * 根据id查询
- */
- User findById(Long id);
-
- /**
- * 根据用户名获取用户信息 注意:like模糊查询的占位符用${},不能用#{}
- */
- @Select(value = "select id, mobile, user_name as userName, age, create_time as createTime, update_time as updateTime from user_t where user_name like '%${userName}'")
- List<User> findByUserName(@Param("userName") String userName);
-
- /**
- * 更新id数据的用户名和年龄信息方式1
- */
- @Update(value = "update user_t set user_name = #{userName}, age = #{age} where id = #{id}")
- Integer updateById1(@Param("userName") String userName, @Param("age") Integer age, @Param("id") Long id);
-
- /**
- * 删除id数据方式1
- */
- @Delete(value = "delete from user_t where id = #{id}")
- Integer deleteById1(@Param("id") Long id);
-
- /**
- * 更新数据方式2
- */
- Integer updateById2(User user);
-
- /**
- * 删除id数据方式2
- *
- * @param id 被删除的数据id
- */
- Integer deleteById2(Long id);
- }
- <?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.hc.mybatisdemo.mapper.UserMapper">
-
- <resultMap id="BaseResultMap" type="com.hc.mybatisdemo.entity.User">
- <result column="id" jdbcType="VARCHAR" property="id"/>
- <result column="mobile" jdbcType="VARCHAR" property="mobile"/>
- <result column="user_name" jdbcType="VARCHAR" property="userName"/>
- <result column="age" jdbcType="INTEGER" property="age"/>
- <result column="create_time" jdbcType="TIMESTAMP" property="createTime"/>
- <result column="update_time" jdbcType="TIMESTAMP" property="updateTime"/>
- </resultMap>
-
- <select id="findById" resultMap="BaseResultMap">
- select * from user_t where id = #{id}
- </select>
-
- <!--<select id="findById" resultType="com.hc.mybatisdemo.entity.User">-->
- <!--select * from user_t where id = #{id}-->
- <!--</select>-->
-
- <update id="updateById" parameterType="com.hc.mybatisdemo.entity.User">
- update user_t set user_name = #{userName}, age = #{age} where id = #{id};
- </update>
-
- <delete id="deleteById" parameterType="String">
- delete from user_t where id = #{id};
- </delete>
- </mapper>
创建业务层接口类:IUserService.java
- import com.hc.mybatisdemo.entity.User;
- import java.util.List;
- import org.springframework.stereotype.Service;
-
- /**
- * 用户service接口
- */
- @Service
- public interface IUserService {
-
- /**
- * 查询一个
- */
- User findOne(Long id);
-
- /**
- * 根据用户名获取用户列表
- */
- List<User> findByUserName(String userName);
-
- /**
- * 插入一条数据
- */
- Integer insert(User user);
-
- /**
- * 更新一条数据
- */
- Integer updateById(User user);
-
- /**
- * 删除一条数据
- */
- Integer deleteById(Long id);
-
- /**
- * 事务控制测试--删除id1和id2两条数据
- */
- Integer transactionTest(Long id1, Long id2);
- }
创建业务层接口实现类:UserServiceImpl.java
- import com.hc.mybatisdemo.entity.User;
- import com.hc.mybatisdemo.mapper.UserMapper;
- import com.hc.mybatisdemo.service.IUserService;
- import java.util.List;
- import lombok.extern.slf4j.Slf4j;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.stereotype.Service;
- import org.springframework.transaction.annotation.Transactional;
- import org.springframework.transaction.interceptor.TransactionAspectSupport;
-
- /**
- * 用户service实现类
- */
- @Slf4j
- @Service
- public class UserServiceImpl implements IUserService {
-
- @Autowired
- private UserMapper userMapper;
-
- /**
- * 查询一个
- */
- @Override
- public User findOne(Long id) {
- return userMapper.findById(id);
- }
-
- /**
- * 根据用户名获取用户列表
- */
- @Override
- public List<User> findByUserName(String userName) {
- return userMapper.findByUserName(userName);
- }
-
- /**
- * 新增一条数据
- */
- @Override
- public Integer insert(User user) {
- return userMapper.insertSelective(user);
- }
-
- /**
- * 更新一条数据
- */
- @Override
- public Integer updateById(User user) {
- // return userDao.updateById1(user.getUserName(), user.getAge(), user.getId());
- return userMapper.updateById2(user);
- }
-
- /**
- * 删除一条数据
- */
- @Override
- public Integer deleteById(Long id) {
- // return userDao.deleteById1(id);
- return userMapper.deleteById2(id);
- }
-
- /**
- * 事务控制测试--删除id1和id2两条数据
- */
- @Override
- @Transactional(rollbackFor = Exception.class)
- public Integer transactionTest(Long id1, Long id2) {
- try {
- userMapper.deleteById1(id1);
- userMapper.deleteById1(id2);
- int a = 0;
- int b = 10 / a;//模拟抛出异常
- } catch (Exception e) {
- TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
- return 0;
- }
- return 1;
- }
- }
创建控制层api类:UserController.java
- import com.hc.mybatisdemo.entity.User;
- import com.hc.mybatisdemo.service.IUserService;
- import java.util.List;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.web.bind.annotation.DeleteMapping;
- import org.springframework.web.bind.annotation.GetMapping;
- import org.springframework.web.bind.annotation.PostMapping;
- import org.springframework.web.bind.annotation.PutMapping;
- import org.springframework.web.bind.annotation.RequestBody;
- import org.springframework.web.bind.annotation.RequestMapping;
- import org.springframework.web.bind.annotation.RestController;
-
- /**
- * 用户控制器
- */
- @RestController
- @RequestMapping(value = "/user")
- public class UserController {
-
- @Autowired
- private IUserService userService;
-
- /**
- * 根据id查询
- */
- @GetMapping(value = "findOne")
- public User findOne(Long id) {
- User user = userService.findOne(id);
- return user;
- }
-
- /**
- * 根据用户名获取用户列表
- */
- @GetMapping(value = "findByUserName")
- public List<User> findByUserName(String userName) {
- return userService.findByUserName(userName);
- }
-
- /**
- * 新增一条数据
- */
- @PostMapping(value = "insert")
- public Integer insert(@RequestBody User user) {
- return userService.insert(user);
- }
-
- /**
- * 更新一条数据
- */
- @PutMapping(value = "update")
- public Integer update(@RequestBody User user) {
- return userService.updateById(user);
- }
-
- /**
- * 根据用户名获取用户列表
- */
- @DeleteMapping(value = "delete")
- public Integer delete(Long id) {
- return userService.deleteById(id);
- }
-
- /**
- * 事务控制测试
- */
- @GetMapping(value = "transactionTest")
- public Integer transactionTest(Long id1, Long id2) {
- return userService.transactionTest(id1, id2);
- }
- }
查询id为2的数据。
左模糊查询。查询以“五”结尾的用户名数据。
插入一条用户名为“老七”的记录。
保存结果:
将id为5的数据的用户名更新为“老七七”,年龄更新为75。
更新后结果:
删除id为5的数据。
删除后结果:
7.6 事务控制(Transaction)测试
调用事务控制测试api接口(接口的业务层会删除id为1和2的两条数据),但是我们人为埋下了一个抛出异常的代码(int b = 10/a;)。理想结果:由于代码抛出异常,那么两条数据都不会被删除,因为事务回滚了!
调用接口,删除id为1和2的两条数据:
测试结果如下,可见事务回滚了。id为1和2的数据都没有删除成功。证明了同一个事务种mysql操作的原子性和一致性。
关注微信公众号并回复"我要mybatis整合源码",免费获取本教程mybatis-demo源码~
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。