MyBatis基本操作及概念

MyBatis

一、Mybatis简介

1.1 什么是Mybatis

MyBatis logo

  1. MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。
  2. Mybatis可以简化数据库编程,底层封装的是JDBC,在使用Mybatis实现数据库编程时,只需要定义每个数据操作功能的抽象方法,并配置这个抽象方法对应的SQL语句即可。

1.2 导入SSM组件

  1. MyBatis经常和Spring、SpringMVC一起使用,简称为SSM框架。
  2. 导入SSM的依赖
	<dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.13</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>5.2.6.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-jdbc</artifactId>
      <version>5.2.6.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>3.5.3</version>
    </dependency>
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis-spring</artifactId>
      <version>2.0.3</version>
    </dependency>
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>8.0.17</version>
    </dependency>
    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>druid</artifactId>
      <version>1.1.21</version>
    </dependency>
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>4.0.1</version>
      <scope>provided</scope>
    </dependency>
  1. 配置MyBatis数据库连接参数
db.driver=com.mysql.cj.jdbc.Driver
db.url=jdbc:mysql://localhost:3306/test?characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true
db.username=root
db.password=root010216
db.maxActive=10
db.initialSize=2
  1. 创建Spring配置类,配置数据库连接池
package com.yuanle.config;

import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;

import javax.sql.DataSource;

@Configuration
@PropertySource("classpath:jdbc.properties")
public class MybatisConfig {

    @Bean
    public DataSource dataSource(
            @Value("${db.driver}") String driver,
            @Value("${db.url}") String url,
            @Value("${db.username}") String username,
            @Value("${db.password}") String password,
            @Value("${db.maxActive}") int maxActive,
            @Value("${db.initialSize}") int initialSize){
        DruidDataSource ds = new DruidDataSource();
        ds.setDriverClassName(driver);
        ds.setUrl(url);
        ds.setUsername(username);
        ds.setPassword(password);
        ds.setMaxActive(maxActive);
        ds.setInitialSize(initialSize);
        return ds;
    }
}

1.3 Mybatis helloWorld

  1. 在Mybatis的配置类中配置Mtbatis的核心工厂SqlSessionFactory,需要将dataSource注入给它,这样Mybatis才能正确连接到数据库。
@Bean
public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
    SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
    bean.setDataSource(dataSource);
    return bean.getObject();
}
  1. 在Mybatis的配置类上标注@MapperScan(basePackages=“com.yuanle.mapper”),目的是自动查找mapper接口,并且自动创建接口的实现类。

  2. 声明数据访问接口DemoMapper,MyBatis会自动创建这个接口的具体实例。

package com.yuanle.mapper;

import org.apache.ibatis.annotations.Select;

public interface DemoMapper {

    @Select("SELECT 'HelloWorld!'")
    String hello();
}
  1. 运行原理是:在DemoMapper接口中抽象方法前面标注了@Select注解,这个注解为hello方法声明了SQL语句,MyBatis会自动处理这个注解:在调用hello方法时候,MyBatis会自动向数据库发送注解中的SQL语句,接着数据库执行SQL返回数据,MyBatis还会自动将SQL返回结果作为hello方法的返回值。

二、利用MyBatis实现数据表CRUD操作

2.1 初始化数据库

create database test;
use test;
create table user(
	id int(11) auto_increment comment '用户id',
	username varchar(20) unique not null comment '用户名',
	password varchar(20) not null comment '密码',
	age int comment '年龄',
	phone varchar(20) comment '电话',
	email varchar(20) comment '电子邮箱',
	primary key(id)
) ENGINE=INNODB default charset=utf8;

INSERT INTO user(username,password,phone,age,email) VALUES
('Frank01','1234','13800138001',28,'frank01@163.com'),
('Frank04','1234','13800138004',33,'frank04@163.com'),
('Frank05','1234','13800138005',21,'frank05@163.com'),
('Frank09','1234','13800138009',26,'frank09@163.com'),
('Frank06','1234','13800138006',29,'frank06@163.com'),
('Frank11','1234','13800138011',24,'frank11@163.com'),
('Frank12','1234','13800138012',23,'frank12@163.com'),
('Frank07','1234','13800138007',31,'frank07@163.com'),
('Frank08','1234','13800138008',22,'frank08@163.com'),
('Frank02','1234','13800138002',27,'frank02@163.com'),
('Frank03','1234','13800138003',32,'frank03@163.com'),
('Frank10','1234','13800138010',30,'frank10@163.com'),
('Frank13','1234','13800138013',25,'frank13@163.com');

2.2 查询功能

  1. MyBatis会自动的将数据库的信息加载到JavaBean对象中,创建User类,和数据库中表对应。

  2. 声明数据库访问接口UserMapper,在接口中声明数据访问方法,这个借口并不需要实现,MyBatis最强大的功能就是自动实现这个接口,并且实现相应的功能。在UserMapper中设计一个根据用户的ID查询一个用户信息的方法findUserById,参数就是用户的主键ID

@Select("SELECT id, username, password, age, phone, email FROM user WHERE id=#{id}")
User findUserById(Integer id);
  1. 然后测试,原理就是MyBatis利用JDBC查询数据库,并将查询结果映射到User对象属性,然后将User对象作为findUserById方法结果返回。
  2. 上述是查询单条数据,查询多条数据也不难,就是将数据访问方法的返回值改为List,然后遍历List,即可获得。
@Select("SELECT id, username, password, age, phone, email FROM user")
List<User> fingAll();

@Test
public void testFindAll(){
    UserMapper userMapper = ctx.getBean("userMapper", UserMapper.class);
    List<User> users = userMapper.fingAll();
    for(User user: users){
        System.out.println(user);
    }
}

2.3 新增功能

  1. 只需要将SQL语句需要插入数据的地方替换为#{}占位,并且使#{}中的名字与User对象的属性名一致,然后在数据访问接口中声明抽象方法,使用@Insert映射SQL语句于方法的对应关系。MyBatis执行时候就会自动读取参数的属性填充到对应占位符#{}。

  2. 注意:这样插入之后我们的User类中的自增id是获取不到的,需要在抽象方法上加@Options注解,其中属性添加useGeneratedKeys = true, keyProperty = “id”。

@Insert("INSERT INTO user (username, password, age, phone, email) " +
    "VALUES (#{username}, #{password}, #{age}, #{phone}, #{email})")
@Options(useGeneratedKeys = true, keyProperty = "id")
Integer insertUser(User user);

2.4 修改功能

  1. 在接口方法上使用@Update声明更新语句,就可以完成更新功能。但是这种方法会更新所有的值。
  2. 若只想修改其中的几个值,那么SQL语句中就会有多个参数,所以,在设计抽象方法的时候,抽象方法的参数列表中也应该有多个参数,这么做调用方法的时候,传过去的参数MyBatis在处理时参数名称其实不是我们穿过去的值,而是arg0、arg1…,它就会找不到映射参数,这个时候我们可以用@Param()注解填上我们要改的参数值,就可以了。
@Update("UPDATE user SET password=#{password} WHERE id=#{id}")
Integer updatePasswordById(@Param("password") String password, @Param("id") Integer id);

2.5 删除功能

  1. 删除功能和上述功能实现方式完全一致。

三、动态SQL拼接

3.1 XML文件映射

  1. MyBatis提供了注解定义SQL与Mapper接口的映射关系,还提供了利用XML文件映射与接口方法的关系。相对于注解,xml文件更加灵活强大,可以实现复杂的动态SQL拼接,以及复杂结果映射功能。

  2. 使用XML文件映射步骤:

    (1)首先在数据访问接口中定义抽象方法

    (2)创建XML文件为接口SQL提供映射关系,XML文件中的标签及属性功能介绍:

    ​ a. 标签中用于书写各种SQL语句,其中的namespace属性指向数据访问接口的全类名

    ​ b. 标签中的id属性指向数据访问接口中的抽象方法的方法名,resultType属性用于声明数据访问接口中的抽象方法的返回值。

    (3)在sqlSesstionFactroy配置中加载XML文件,并将映射文件的位置配置在properties文件中

    @Bean
    public SqlSessionFactory sqlSessionFactory(DataSource dataSource,
               @Value("${mybatis.mapper.location}") Resource[] mapperLocations) throws Exception {
            SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
            bean.setDataSource(dataSource);
            bean.setMapperLocations(mapperLocations);
            return bean.getObject();
        }
    
    mybatis.mapper.location=classpath:mappers/*.xml
    

3.2 动态SQL-foreach

  1. 动态SQL:是指根据调用方法时给出的参数不同,最终生成的SQL语句会不相同

  2. foreach节点标签可以实现动态SQL中的遍历,遍历参数值来生成最终的SQL。

(1)使用如下:

public interface UserMapper {
    Integer deleteByIds(Integer... ids);
}
<mapper namespace="com.yuanle.mapper.UserMapper">
    <delete id="deleteByIds" parameterType="int">
        DELETE FROM user WHERE id IN(
            <foreach collection="array" item="id" separator=",">
                #{id}
            </foreach>
        )
    </delete>
</mapper>

(2)上述配置中各属性的作用

​ a. connection:表示被遍历的对象,当抽象方法的参数只有1个且没有添加@Param注解时,如果参数的类型是List集合类型的,则取值为list,如果参数的类型是数组类型的,则取值为array;否则,取值是@Param注解中配置的名称。

​ b. item:在遍历过程中,被遍历到的数据的名称,将根据这个名称来使用被遍历到的数据,所以,在的子级,将根据这个属性配置的值来使用数据,

​ c. separator:分隔符,用于分隔遍历时生成的多个占位符。

​ d. open与close:遍历生成SQL语句片段的多个占位符。

3.3 显示MyBatis生成的SQL

  1. MyBatis提供了显示动态生成SQL功能,利用这个功能可以查看SQL,分析问题原因,甚至是优化查询性能。这个功能是利用日志系统实现的,需要先导入日志包。
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-log4j12</artifactId>
    <version>1.7.25</version>
</dependency>
  1. 导入包之后还应该添加日志配置文件log4j.properties
log4j.rootLogger=ERROR, stdout

log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n

# MyBatis Mapper:控制日志输出
log4j.logger.com.yuanle.mapper.UserMapper=TRACE

3.4 动态SQL-if

  1. 标签的配置语法格式是:
<if test="表达式">
	SQL语句片段
</if>
  1. 使用可以根据判断条件不同而得到不同的SQL语句,在使用时,如果有多个条件存在逻辑关系,可以使用“and”表示“与”,使用“or”表示“或”,在MyBatis中的并没有对应的else标签,如果要实现if…else的效果,需要使用系列的标签,基本格式是:
<choose>
	<when test="表达式">
		满足条件时执行的SQL语句片段
	</when>
	<otherwise>
		不满足条件时SQL语句片段
	</otherwise>
</choose>
  1. 使用有条件的SQL时,可能会发生多“,”的BUG,MyBatis考虑到这个情况提供了标签消除多余的符号。

  2. 在进行多参数动态查询时,where条件也要使用标签,这个标签可以为我们去除多余的AND或添加符号等等。

<select id="findUserByParams" resultType="com.yuanle.entity.User">
        SELECT
            id, username, password, age, phone, email
        FROM
            user
        <where>
            <if test="username != null">
                username like #{username}
            </if>
            <if test="age !=null">
                AND age = #{age}
            </if>
            <if test="phone != null">
                AND phone like #{phone}
            </if>
        </where>
    </select>

3.5 xml文件中其它标签的意义及属性

  1. resultMap:用于映射复杂的SQL语句。

  2. result:用于将列名和属性名映射一致

    (1)column属性:用于指定查询结果中的列名

    (2)property属性:用于对应javaBean中的属性

  3. collection:用于遍历JavaBean中的集合,其中property属性对应JavaBean中集合的名字,ofType用于指定集合中泛型的类型。

3.6 关于#{}和${}格式的占位符

  1. 在MyBatis中,配置SQL语句时,可以使用#{}或${}格式的占位符,用于表示参数的值。
  2. 使用#{}格式的占位符时,只能表示某个参数值,不可以表示SQL语句中的某个片段,使用这种占位符时,MyBatis在处理过程中,是使用预编译的做法,所以,这种做法是安全的,不存在SQL注入的风险。
  3. 使用${}格式的占位符,可以表示SQL语句中的任何部分,可以是某个值,也可以是SQL语句中的某个片段。使用这种占位符时,MyBatis在处理过程中,是先将占位符对应的值拼接到SQL语句中,这种没有预编译的处理,存在SQL注入风险,使用时要甚用。
@Delete("DELETE FROM ${table} WHERE id=#{id}")
Integer deleteById(
       @Param("table") String table,
       @Param("id") Integer id
);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值