MyBatis操作数据库

目录

1 什么是MyBatis

2 MyBatis入门

2.1 准备工作

2.1.1 创建项目

2.1.2 数据准备

2.2 配置数据库连接字符串

2.3 写持久层代码

2.4 测试

2.5 使用IDEA自动生成测试类

2.6 使用MyBatis常见的错误

3 MyBatis的基础操作 

3.1 打印日志

3.2 参数传递 

3.3 增(Insert)

3.4 删(Delete)

3.5 改(Update)

​编辑 3.6 查(Select)

3.6.1 起别名

3.6.2 结果映射

3.6.6 自动转驼峰(推荐)

4 MyBatis XML配置文件

4.1 配置连接字符串和MyBatis

4.2 写持久层代码

4.2.1 添加mapper接口

4.2.2 添加UserInfoXMLMapper.xml

4.2.3 测试 

4.2.4 使用XML的常见问题

4.3 增删改查操作

4.3.1 增(Insert)

4.3.2 删(Delete)

4.3.3 改(Update)

4.3.4 查(Select)

1 什么是MyBatis

Mybatis是一款优秀的持久层框架,用于简化JDBC的开发,持久层指的是持久化操作的层,通常指数据访问层(DAO),是用来操作数据库的,简单来说Mybatis是更简单完成程序和数据交互的框架,也就是更简单的操作和读取数据库工具

2 MyBatis入门

MyBatis操作数据库的步骤:

1)准备工作(创建SpringBoot项目、数据库表准备、实体类)

2)引入MyBatis的相关依赖,配置MyBatis(数据库连接信息)

3)编写SQL语句(注解/XML)

4)测试

2.1 准备工作

2.1.1 创建项目

创建SpringBoot项目,并导入mybatis的依赖、mybatis的驱动包

 项目创建完毕会自动在pom.xml文件中导入MyBatis依赖和MySQL驱动依赖

<!--Mybatis 依赖包-->
<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>2.3.1</version>
</dependency>
<!--mysql驱动包-->
<dependency>
    <groupId>com.mysql</groupId>
    <artifactId>mysql-connector-j</artifactId>
    <scope>runtime</scope>
</dependency>

2.1.2 数据准备

创建用户表,并创建对应的实体类User

-- 创建数据库
DROP DATABASE IF EXISTS mybatis_test;
CREATE DATABASE mybatis_test DEFAULT CHARACTER SET utf8mb4;
-- 使⽤数据数据
USE mybatis_test;
-- 创建表[⽤⼾表]
DROP TABLE IF EXISTS userinfo;
CREATE TABLE `userinfo` (
`id` INT ( 11 ) NOT NULL AUTO_INCREMENT,
`username` VARCHAR ( 127 ) NOT NULL,
`password` VARCHAR ( 127 ) NOT NULL,
`age` TINYINT ( 4 ) NOT NULL,
`gender` TINYINT ( 4 ) DEFAULT '0' COMMENT '1-男 2-⼥ 0-默认',
`phone` VARCHAR ( 15 ) DEFAULT NULL,
`delete_flag` TINYINT ( 4 ) DEFAULT 0 COMMENT '0-正常, 1-删除',
`create_time` DATETIME DEFAULT now(),
`update_time` DATETIME DEFAULT now(),
PRIMARY KEY ( `id` )
) ENGINE = INNODB DEFAULT CHARSET = utf8mb4;
-- 添加⽤⼾信息
INSERT INTO mybatis_test.userinfo ( username, `password`, age, gender, phone )
VALUES ( 'admin', 'admin', 18, 1, '18612340001' );
INSERT INTO mybatis_test.userinfo ( username, `password`, age, gender, phone )
VALUES ( 'zhangsan', 'zhangsan', 18, 1, '18612340002' );
INSERT INTO mybatis_test.userinfo ( username, `password`, age, gender, phone )
VALUES ( 'lisi', 'lisi', 18, 1, '18612340003' );
INSERT INTO mybatis_test.userinfo ( username, `password`, age, gender, phone )
VALUES ( 'wangwu', 'wangwu', 18, 1, '18612340004' );

创建对应的实体类UserInfo

@Data
public class UserInfo {
    private Integer id;
    private String username;
    private String password;
    private Integer age;
    private Integer gender;
    private String phone;
    private Integer deleteFlag;
    private Date createTime;
    private Date updateTime;
}

2.2 配置数据库连接字符串

MyBatis重要连接数据库,需要数据库相关参数配置

1)MySQL驱动类   2)登录名   3)密码   4)数据库连接字符串

# 数据库连接配置
spring:
  datasource:
    url: jdbc:mysql://127.0.0.1:3306/mybatis_test?characterEncoding=utf8&useSSL=false
    username: root
    password: root
    driver-class-name: com.mysql.cj.jdbc.Driver

注意:如果使用MySQL是5.X之前的是"com.mysql.jdbc.Driver",5.X之后的是"com.mysql.cj.jdbc.Driver"

2.3 写持久层代码

在项目中创建持久层接口UserInfoMapper

@Mapper
public interface UserInfoMapper {
    @Select("select * from userinfo")
    List<UserInfo> selectAll();
}

 Mybatis的持久层接口规范一般为XxxMapper

@Mapper注解:表示MyBatis中的Mapper接口

程序运行时,框架会自动生成接口的实现类对象,并交给Spring的IOC容器管理

@Select注解:代表select查询,也就是注解对应方法的具体实现内容

2.4 测试

@RestController
public class UserInfoController {
    @Autowired
    private UserInfoMapper userInfoMapper;
    @RequestMapping("/selectAll")
    public List<UserInfo> selectAll() {
        return userInfoMapper.selectAll();
    }
}

2.5 使用IDEA自动生成测试类

1 在需要测试的Mapper接口中,右键—Generate—Test

2 选择要测试的方法 

3 写代码

@Slf4j
class UserInfoMapperTest {
    @Autowired
    private UserInfoMapper userInfoMapper;
    @Test
    void selectAll() {
        List<UserInfo> list = userInfoMapper.selectAll();
        log.info(list.toString());
    }
}

此时报了空指针异常,是因为没有把对象交给Spring来管理,所以哟啊加上@SpringBootTest这个注解

@Slf4j
@SpringBootTest
class UserInfoMapperTest {
    @Autowired
    private UserInfoMapper userInfoMapper;
    @Test
    void selectAll() {
        List<UserInfo> list = userInfoMapper.selectAll();
        log.info(list.toString());
    }
}

2.6 使用MyBatis常见的错误

1 没有配置数据库相关信息

2 账号密码错误 

3 数据库错误 

4 表不存在 

5 字段错误 

3 MyBatis的基础操作 

主要学习MyBatis的增删改查

3.1 打印日志

在MyBatis当中,可以借助日志,查看到SQL语句的执行、执行传递的参数以及执行结果,在配置文件中进行配置即可

mybatis:
  configuration: # 配置打印 MyBatis⽇志
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

3.2 参数传递 

数据库目前里面有这些信息,接下来查询id=4的用户 

@Mapper
public interface UserInfoMapper {
    @Select("select * from userinfo where id=#{id}")
    UserInfo selectById(Integer id);
}

添加测试用例 

@Slf4j
@SpringBootTest
class UserInfoMapperTest {
    @Autowired
    private UserInfoMapper userInfoMapper;
    @Test
    void selectById() {
        UserInfo userInfo = userInfoMapper.selectById(4);
        log.info(userInfo.toString());
    }
}

上述SQL语句中的id值不能写成固定数值,需要编程动态的数值,因此在selectById中添加一个参数id,将方法中的参数传给SQL语句,使用#{ }的方式获取方法中的参数

如果mapper接口方法形参只有一个普通类型的参数,#{ }里面的属性名可以随便写,如#{id}、#{a}但是建议和参数名保持一致

也可以通过@Param,设置参数的别名,如果使用@Param设置别名,#{ }里面的属性名必须和@Param设置一样

@Select("select * from userinfo where id=#{userid}")
UserInfo selectById(@Param("userid") Integer id);

3.3 增(Insert)

SQL语句

insert into userinfo (username,password,age,gender,phone) values ("123","123",1,1,"123456")

Mapper接口

@Insert("insert into userinfo (username,password,age,gender,phone) " +
            "values (#{username},#{password},#{age},#{gender},#{phone})")
Integer insert(UserInfo userInfo);

测试代码

@Test
void insert() {
    UserInfo userInfo = new UserInfo();
    userInfo.setUsername("123");
    userInfo.setPassword("123");
    userInfo.setGender(1);
    userInfo.setAge(1);
    userInfo.setPhone("123456");
    Integer result = userInfoMapper.insert(userInfo);
    log.info(result.toString());
}

如果设置了@Param属性,#{ }需要使用参数.属性来获取 

@Insert("insert into userinfo (username,password,age,gender,phone) " +
"values (#{userinfo.username},#{userinfo.password},#{userinfo.age},#{userinfo.gender},#{userinfo.phone})")
Integer insert(@Param("userinfo") UserInfo userInfo);

返回主键

Insert语句默认返回的时受影响的行数,因此使用Integer,但是有些情况下,还需要后续的关联操作,需要获取到新插入数据的id,如果想拿到自增id,需要在Mapper接口的方法上添加一个Options的注解

@Options(useGeneratedKeys = true,keyProperty = "id")
@Insert("insert into userinfo (username,password,age,gender,phone) " +
"values (#{userinfo.username},#{userinfo.password},#{userinfo.age},#{userinfo.gender},#{userinfo.phone})")
Integer insert(@Param("userinfo") UserInfo userInfo);
@Test
void insert() {
    UserInfo userInfo = new UserInfo();
    userInfo.setUsername("123");
    userInfo.setPassword("123");
    userInfo.setGender(1);
    userInfo.setAge(1);
    userInfo.setPhone("123456");
    Integer result = userInfoMapper.insert(userInfo);
    log.info("添加的数据条数:" + result + ",数据ID:" + userInfo.getId());
}

useGeneratedKeys:令MyBatis使用JDBC的getGeneratedKeys方法来取出由数据库内部生成的主键,默认为false

keyProperty:指定能够唯一识别的对象的属性

3.4 删(Delete)

@Delete("delete from userinfo where id = ${id}")
Integer delete(Integer id);
@Test
void delete() {
    userInfoMapper.delete(14);
}

3.5 改(Update)

@Update("update userinfo set username=#{username} where id = #{id}")
Integer update(UserInfo userInfo);
void update() {
    UserInfo userInfo = new UserInfo();
    userInfo.setUsername("345");
    userInfo.setId(13);
    Integer result = userInfoMapper.update(userInfo);
    log.info("更改成功");
}

 3.6 查(Select)

通过上面查询时,可以发现有几个字段时没有赋值的,只有Java对象属性和数据库字段一样时,才会进行赋值(结果映射)

原因:当自动映射查询结果时,MyBatis会获取结果中返回的列名并在Java类中查找相同名字的属性(忽略大小写),这意味着如果发现了ID列和id属性,MyBatis会将列ID的值赋给id属性

在企业开发中,尽量不要使用*,需要查询哪些字段就写哪些字段,如果需要全部的,就写全部的

解决方案:

3.6.1 起别名

在SQL语句中,给列名起别名,保持别名和实体类属性名一样

@Select("select id,username,password,age,gender,phone," +
        " delete_flag as deleteFlag,create_time as createTime,update_time as updateTime" +
        " from userinfo")
List<UserInfo> selectAll();

3.6.2 结果映射

@Select("select id,username,password,age,gender,phone," +
        " delete_flag,create_time,update_time" +
        " from userinfo")
@Results({
    @Result(column = "delete_flag",property = "deleteFlag"),
    @Result(column = "create_time",property = "createTime"),
    @Result(column = "update_time",property = "updateTime")
})
List<UserInfo> selectAll2();
void selectAll2() {
    List<UserInfo> list = userInfoMapper.selectAll2();
    log.info(list.toString());
}

如果其他SQL,也想复用这个映射关系,可以给这个Result定义一个名称 

@Select("select id,username,password,age,gender,phone," +
        " delete_flag,create_time,update_time" +
        " from userinfo")
@Results(id = "Map",value = {
    @Result(column = "delete_flag",property = "deleteFlag"),
    @Result(column = "create_time",property = "createTime"),
    @Result(column = "update_time",property = "updateTime")
})
List<UserInfo> selectAll2();
@Select("select id,username,password,age,gender,phone," +
        " delete_flag,create_time,update_time" +
        " from userinfo")
@ResultMap(value = "Map")
List<UserInfo> selectAll();

3.6.6 自动转驼峰(推荐)

通常数据库列使用蛇形命名法进行命名(下划线分割各个单词),而Java属性一般遵循驼峰命名约定,为了在这两种命名方式之间启用自动映射,需要将mapUnderscoreToCamelCase设置为true

mybatis:
  configuration:
    map-underscore-to-camel-case: true #配置驼峰⾃动转换
@Select("select id,username,password,age,gender,phone," +
        " delete_flag,create_time,update_time" +
        " from userinfo")
List<UserInfo> selectAll3();

自动转驼峰之后Java代码不需要做出任何改变

4 MyBatis XML配置文件

MyBatis的开发有两种方式

1)注解      2)XML

使用MyBatis的注解方式,主要是来完成一些简单的增删改查共能,如果要实现复杂的SQL功能,建议使用XML来配置,也就是将SQL语句写在XML配置文件中

MyBatis XML的方式需要以下两步:

1)配置数据库连接字符串和MyBatis         2)写持久层代码

4.1 配置连接字符串和MyBatis

这个步骤需要进行两项设置,配置数据库和指明xml的路径

# 数据库连接配置
spring:
  datasource:
    url: jdbc:mysql://127.0.0.1:3306/mybatis_test?characterEncoding=utf8&useSSL=false
    username: root
    password: root
    driver-class-name: com.mysql.cj.jdbc.Driver
# 配置 mybatis xml 的⽂件路径,在 resources/mapper 创建所有表的 xml ⽂件
mybatis:
  mapper-locations: classpath:mapper/**Mapper.xml

4.2 写持久层代码

持久层代码分两部分

1)方法定义 Interface           2)方法实现:XXX.xml

4.2.1 添加mapper接口

@Mapper
public interface UserInfoXMLMapper {
    List<UserInfo> selectAll();
}

4.2.2 添加UserInfoXMLMapper.xml

MyBatis的固定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.example.demo.mapper.UserInfoMapper">

</mapper>

创建UserInfoXMLMapper.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.example.demo.mapper.UserInfoXMLMapper">
    <select id="selectAll" resultType="com.example.demo.UserInfo">
        select username,password,age,gender,phone from userinfo
    </select>
</mapper>

上述标签的含义:

<mapper>标签:需要指定namespace属性,表示命名空间,值为mapper接口的全限定名,包括全包名.类名

<select>查询标签:用来执行数据库的查询操作

id:和Interface接口中定义的方法名称一样,表示对接口的具体实现方法

resultType:返回的数据类型,也就是最开始定义的实体类

4.2.3 测试 

@Slf4j
@SpringBootTest
class UserInfoXMLMapperTest {
    @Autowired
    private UserInfoXMLMapper userInfoXMLMapper;
    @Test
    void selectAll() {
        List<UserInfo> list = userInfoXMLMapper.selectAll();
        log.info(list.toString());
    }
}

4.2.4 使用XML的常见问题

1)XML和接口定义的方法名称不一致

2)mapper的路径配置和XML的路径不一样

3)XML namespace写错了

4.3 增删改查操作

4.3.1 增(Insert)

UserInfoMapper接口:

Integer insert(UserInfo userInfo);

UserInfoMapper.xml实现:

<insert id="insert">
    insert into userinfo (username,password,age,gender,phone) values
    (#{username},#{password},#{age},#{gender},#{phone})
</insert>

测试代码:

@Test
void insert() {
    UserInfo userInfo = new UserInfo();
    userInfo.setUsername("hello");
    userInfo.setPassword("hello");
    userInfo.setAge(12);
    userInfo.setGender(1);
    userInfo.setPhone("22233554");
    Integer result = userInfoXMLMapper.insert(userInfo);
    log.info(result.toString());
}

运行结果:

如果使用@Param设置参数名称的话,使用方法和注解类似 

UserInfoMapper接口:

Integer insert(@Param("userinfo") UserInfo userInfo);

 UserInfoMapper.xml实现:

<insert id="insert">
    insert into userinfo (username,password,age,gender,phone) values
    (#{userinfo.username},#{userinfo.password},#{userinfo.age},#{userinfo.gender},
    #{userinfo.phone})
</insert>

返回自增id

接口定义不变,Mapper.xml实现,设置useGeneratedKeys和keyProperty属性

<insert id="insert" useGeneratedKeys="true" keyProperty="id">
    insert into userinfo (username,password,age,gender,phone) values
    (#{username},#{password},#{age},#{gender},#{phone})
</insert>

4.3.2 删(Delete)

Integer delete(Integer id);
<delete id="delete">
    delete from userinfo where id=#{id}
</delete>
@Test
void delete() {
    userInfoXMLMapper.delete(13);
}

4.3.3 改(Update)

Integer update(UserInfo userInfo);
<update id="update">
    update userinfo set username=#{username} where id = #{id}
</update>
@Test
void update() {
    UserInfo userInfo = new UserInfo();
    userInfo.setId(19);
    userInfo.setUsername("wangwu");
    Integer update = userInfoXMLMapper.update(userInfo);
    log.info(userInfo.toString());
}

4.3.4 查(Select)

同样的,使用XML的方式进行查询,也存在数据封装的问题,其中deleteFlag,createTime,updateTime为空,没有进行赋值

解决办法和注解的方式一样

1)起别名       2)结果映射       3)自动转驼峰

1 起别名

<select id="selectAll" resultType="com.example.demo.UserInfo">
    select id,username,password,age,gender,phone,delete_flag as deleteFlag,
    create_time as createTime,update_time as updateTime from userinfo
</select>

2 结果映射

<resultMap id="Map" type="com.example.demo.UserInfo">
    <id column="id" property="id"></id>
    <result column="delete_flag" property="deleteFlag"></result>
    <result column="create_time" property="createTime"></result>
    <result column="update_time" property="updateTime"></result>
</resultMap>

<select id="selectAll" resultMap="Map">
    select id,username,password,age,gender,phone,delete_flag,
    create_time,update_time from userinfo
</select>

3 自动转驼峰

mybatis:
  configuration:
    map-underscore-to-camel-case: true #配置驼峰⾃动转换

总结:以上就是MyBatis的介绍,其中XML和注解两种方式都可以用

  • 25
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值