MyBatis快速上手

MyBatis

这是小弟上黑马的MyBatis的课总结的笔记,需要的兄弟姐妹们可以拿去,不到两天就可以直接上手啦。


MyBatis开发手册中文官网:https://mybatis.org/mybatis-3/zh/getting-started.html

什么是MyBatis?

MyBatis是一款持久层框架,用于简化JDBC开发

持久层和框架

JavaEE三层架构:表现层,业务层,持久层

表现层:页面展示

业务层:逻辑处理

持久层:负责数据持久化,将数据保存到数据库的一层代码

框架:一个半成品软件,是一套可以重用的、通用的软件基础代码模型,在其基础上构建软件编写更高效、规范、通用、可扩展

JDBC缺点与MyBatis的简化

JDBC缺点

1.硬编码

(1)注册驱动

(2)SQL语句

2.操作繁琐

(1)手动设置参数

(2)手动封装结果集

MyBatis的简化

硬编码-----》 使用配置文件

操作繁琐-----》 自动完成

MyBatis快速入门

1、创建user表,添加数据

2、创建模块,导入坐标

3、编写MyBatis核心配置文件-----》替换连接信息,解决硬编码问题

4、编写SQL映射文件-----》统一管理sql语句解决硬编码问题

5、编码:

(1)定义pojo类

(2)加载核心配置文件,获取SqlSessionFactory对象

(3)获取SqlSession对象,执行SQL语句

(4)释放资源

注意:logback.xml、mybatis-config.xml、xxxMapper.xml需要放在resources文件夹下面

导入坐标

写在pom.xml文件里

  <dependencies>
        <!--mybatis依赖-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.9</version>
        </dependency>
​
        <!--mysql驱动-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.28</version>
        </dependency>
​
        <!--junit单元测试-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>3.8.2</version>
            <scope>test</scope>
        </dependency>
​
        <!--slf4j日志api-->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>jcl-over-slf4j</artifactId>
            <version>1.5.6</version>
        </dependency>
​
        <!--logback-classic依赖-->
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.4.5</version>
        </dependency>
​
        <!--logback-core依赖-->
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-core</artifactId>
            <version>1.4.5</version>
        </dependency>
​
​
    </dependencies>

logback配置文件

打印日志时需要,不需要日志可以不用

文件名:logback.xml

<configuration>
<appendername="STDOUT"class="ch.qos.logback.core.ConsoleAppender">
    <!--encodersare  bydefaultassignedthetype
          ch.qos.logback.classic.encoder.PatternLayoutEncoder-->
    <encoder>
        <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level%logger{36} -%msg%n</pattern>
    </encoder>
</appender>
<rootlevel="debug">
    <appender-refref="STDOUT"/>
</root>
</configuration>

MyBatis核心配置文件

文件名:mybatis-config.xml(一般都为这个)

<?xmlversion="1.0"encoding="UTF-8"?>
<!DOCTYPEconfiguration
        PUBLIC"-//mybatis.org//DTD Config 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <environmentsdefault="development">
        <environmentid="development">
            <transactionManagertype="JDBC"/>
            <dataSourcetype="POOLED">
                <!--数据库连接信息-->
                <propertyname="driver"value="com.mysql.jdbc.Driver"/>
                <propertyname="url"value="jdbc:mysql:///mybatis?useSSL=false"/>
                <propertyname="username"value="root"/>
                <propertyname="password"value="123456"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <!--加载SQL映射文件-->
        <mapperresource="UserMapper.xml"/>
    </mappers>
</configuration>

SQL映射文件

文件名:xxxMapper.xml,xxx根据结果集封装到的pojo而定,如这里的是UserMapper.xml

<?xmlversion="1.0"encoding="UTF-8"?>
<!DOCTYPEmapper
        PUBLIC"-//mybatis.org//DTD Mapper 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--
    namespace:名称空间
-->
<mappernamespace="test">
    <selectid="selectAll"resultType="com.pojo.User">
        select*fromuser;
    </select>
</mapper>

编码
publicclassMyBatisDemo {
​
    publicstaticvoidmain(String[] args) throwsIOException {
        //1.加载mybatis的核心配置文件,获取SqlSessionFactory
        Stringresource="mybatis-config.xml";
        InputStreaminputStream=Resources.getResourceAsStream(resource);
        SqlSessionFactorysqlSessionFactory=newSqlSessionFactoryBuilder().build(inputStream);
​
        //2、获取对象,用它来执行sql
        SqlSessionsqlSession=sqlSessionFactory.openSession();
​
        //3、执行sql
        List<Object>users=sqlSession.selectList("test.selectAll");
​
        System.out.println(users);
​
        //4、释放资源
        sqlSession.close();
    }
}

Mapper代理开发

1、定义与sql映射文件同名的Mapper接口,并将Mapper接口和SQL映射文件放置在同一目录下

(在resources目录下建mapper目录,要和mapper接口所在目录同名,即com.mapper,但是在resources目录下建时,要为com/mapper,否者编译后会文件名为一长串的com.mapper,而非mapper)

2、设置sql映射文件的namespace属性为Mapper接口全限定名

<!--
    namespace:名称空间
-->
<mappernamespace="com.mapper.UserMapper">
    <selectid="selectAll"resultType="com.pojo.User">
        select*
        fromuser;
    </select>
</mapper>

3、在Mapper接口中定义方法,方法名就是SQL映射文件中sql语句的id,并保持参数类型和返回值类型一致

publicinterfaceUserMapper {
​
    List<User>selectAll();
​
}

4、编码:

(1)通过 SqlSession 的 getMapper 方法获取 Mapper接口的代理对象

(2)调用对应方法完成sql的执行

//3、执行sql
//List<Object> users = sqlSession.selectList("test.selectAll");
//3.1 获取UserMapper接口的代理对象
UserMapperuserMapper=sqlSession.getMapper(UserMapper.class);
List<User>users=userMapper.selectAll();

细节:若Mapper接口名称和SQL映射文件名称相同,并在同一目录下,则可以使用包扫描的方式简化SQL映射文件的加载

<mappers>
    <!--加载SQL映射文件-->
    <!--<mapper resource="com/mapper/UserMapper.xml"/>-->

    <!--Mapper代理方式-->
    <package name="com.mapper"/>
</mappers>

Mapper核心配置文件

设置各个标签时,需要遵守前后循序(如上图)

mybatis-config.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <!--别名,简化xxxMapper.xml,使用包扫描技术,默认为pojo类名的小写-->
    <typeAliases>
        <package name="com.pojo"/>
    </typeAliases>

    <!--
        environments:配置数据库连接环境信息。可以配置多个environment,通过default属性切换不同的environment,如开发时的数据库环境,测试时的数据库环境
    -->
    <environments default="development">
        <environment id="development">
            <!--事务管理,将来会给spring接管-->
            <transactionManager type="JDBC"/>
            <!--数据库连接池配置,将来会给spring接管-->
            <dataSource type="POOLED">
                <!--数据库连接信息-->
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql:///mybatis?useSSL=false"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <!--加载SQL映射文件-->
        <!--<mapper resource="com/mapper/UserMapper.xml"/>-->

        <!--Mapper代理方式-->
        <package name="com.mapper"/>
    </mappers>
</configuration>

使用类型别名后,xxxMapper.xml文件如下:
<mapper namespace="com.mapper.UserMapper">
<!--    <select id="selectAll" resultType="com.pojo.User">-->
<!--        select *-->
<!--        from user;-->
<!--    </select>-->

    <!--使用别名-->
    <select id="selectAll" resultType="user">
        select *
        from user;
    </select>
</mapper>

配置文件完成增删改查

前置准备

1. 建好brand数据库表

2. 在pojo包下建好Brand类

3. 建brandMapper接口

4. 建brandMapper.xml

5. 在test包下,建立测试类

6. 安装mybatisX插件

查询
查询所有数据

1.编写接口方法:Mapper接口

参数:无

结果:List<brand>

2.编写SQL语句:SQL映射文件

3.执行方法,测试

brandMapper.xml文件如下:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--
    namespace:名称空间
-->
<mapper namespace="com.mapper.BrandMapper">

<!--
    数据库表的字段名称 和 实体类的属性名称 不一样,则不能自动封装数据
    解决方法:
        (1)起别名:对不一样的列名起别名,使别名和实体类属性名一样(sql语句中用as)
            缺点:每次查询都得定义一次
                解决:sql片段
                    缺点:不灵活
        (2)resultMap:
            1.定义<resultMap>标签
            2.在<select>标签中,使用 resultMap 属性替换 resultType 属性
 -->
<!--
    id:唯一标识
    type:映射的类型,支持别名
-->
    <resultMap id="brandResultMap" type="brand">
        <!--
            id:完成主键字段的映射
                column:表的列名
                property:实体类的属性名
            result:完成一般字段的映射
                column:表的列名
                property:实体类的属性名
        -->
        <result column="brand_name" property="brandName" />
        <result column="company_name" property="companyName"/>
    </resultMap>

    <select id="selectAll" resultMap="brandResultMap">
        select *
        from brand;
    </select>

<!--    &lt;!&ndash;sql片段&ndash;&gt;-->
<!--    <sql id="brand_column">-->
<!--        id,brand_name as branName,company_name as companyName,ordered,description,status-->
<!--    </sql>-->
<!--    &lt;!&ndash;使用sql片段&ndash;&gt;-->
<!--    <select id="selectAll" resultType="brand">-->
<!--        select -->
<!--        <include refid="brand_column"/>-->
<!--        from brand;-->
<!--    </select>-->

<!--    &lt;!&ndash;使用别名&ndash;&gt;-->
<!--    <select id="selectAll" resultType="brand">-->
<!--        select *-->
<!--        from brand;-->
<!--    </select>-->
</mapper>

查询单行数据

1.编写接口方法:Mapper接口

参数:id

结果:Brand

2.编写SQL语句:SQL映射文件

3.执行方法,测试

brandMapper.xml文件如下:

<!--
    *参数占位符:
    1. #{}:会将其替换成 ? :防止SQL注入
    2. ${}:拼sql,会存在SQL注入问题
    3. 使用时机:(一般都用 #{} )
        * 参数传递时:#{}
        * 表名或者列名不确定时:${} 会存在SQL注入问题

    * 参数类型:parameterType 可以省略
    * 特殊字符处理:
        1.转义字符:如 < 的转义字符为 &lt;
        2.CDATA区:(该区内当做纯文本处理)
            <![CDATA[

            ]]>
-->
    <select id="selectById" resultMap="brandResultMap">
        select *
        from brand
        where id = #{id};
    </select>

条件查询
多条件查询

1.编写接口方法:Mapper接口

参数:所有查询条件

结果:List<Brand>

2.编写SQL语句:SQL映射文件

3.执行方法,测试

接口方法:

/*
    条件查询:
        参数接收:
            1. 散装参数:若方法中有多个参数,需要使用@Param("SQL参数占位符名称")
            2. 对象参数:对象属性名称要和参数占位符名称一致
            3. map集合参数:
 */

List<Brand> selectByCondition(@Param("status")int status,@Param("companyName")String companyName,@Param("brandName")String brandName);

List<Brand> selectByCondition02(Brand brand);

List<Brand> selectByCondition03(Map map);

对应SQL映射文件主要代码:

<select id="selectByCondition" resultMap="brandResultMap">
    select *
    from brand
    where
        status = #{status}
    and company_name like #{companyName}
    and brand_name like #{brandName}
</select>

<select id="selectByCondition02" resultMap="brandResultMap">
    select *
    from brand
    where
    status = #{status}
    and company_name like #{companyName}
    and brand_name like #{brandName}
</select>

<select id="selectByCondition03" resultMap="brandResultMap">
    select *
    from brand
    where
    status = #{status}
    and company_name like #{companyName}
    and brand_name like #{brandName}
</select>

对应测试方法:

    @Test
    public void testSelectByCondition() throws IOException {

        int status = 1;
        String companyName = "葡萄";
        String brandName = "葡萄";

		//处理参数
        companyName = "%"+companyName+"%";
        brandName = "%"+brandName+"%";

        Brand brand = new Brand();
        brand.setStatus(status);
        brand.setCompanyName(companyName);
        brand.setBrandName(brandName);

        Map map = new HashMap();
        map.put("status",status);
        map.put("companyName",companyName);
        map.put("brandName",brandName);

        //1.加载mybatis的核心配置文件,获取SqlSessionFactory
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

        //2.获取 SqlSession 对象
        SqlSession sqlSession = sqlSessionFactory.openSession();

        //3.获取Mapper接口代理对象
        BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);

        //4.执行方法

//        List<Brand> brandList = brandMapper.selectByCondition(status, companyName, brandName);

//        List<Brand> brandList = brandMapper.selectByCondition02(brand);

        List<Brand> brandList = brandMapper.selectByCondition03(map);
        System.out.println(brandList);

        //5.释放资源
        sqlSession.close();

    }

多条件动态条件查询

上面写法有缺陷,如果条件为空,则查不出正确的信息,故需要使用动态sql,实现动态条件查询

对应SQL映射文件主要代码:

<!--
    动态条件查询:
        * if: 可用来判断参数是否有值
            *:test:条件判断
        * 问题:当不使用第一项的查询条件时,SQL语法错误
            * 解决:
                * 在where后加恒等式(如:1=1),再在第一个查询条件加上and
                * 用<where>标签替换where关键字

-->
    <select id="selectByCondition03" resultMap="brandResultMap">
        select *
        from brand
        where
            <if test="status != null">
                status = #{status}
            </if>

            <if test="companyName != null and companyName !=''">
                and company_name like #{companyName}
            </if>

            <if test="brandName != null and brandName !=''">
                and brand_name like #{brandName}
            </if>
    </select>

单条件动态条件查询:

对应SQL映射文件主要代码:

<select id="selectByConditionSingle"  resultMap="brandResultMap">
    select *
    from brand
    where
    <choose><!--相当于switch-->
        <when test="status != null"><!--相当于case-->
            status = #{status}
        </when>

        <when test="companyName != null and companyName !=''"><!--相当于switch-->
            company_name like #{companyName}
        </when>

        <when test="brandName != null and brandName !=''"><!--相当于switch-->
            brand_name like #{brandName}
        </when>

        <otherwise><!--相当于default,也可以不用这段,直接用<where>标签包裹when,效果一样-->
            1=1
        </otherwise>
    </choose>

</select>

添加

1.编写接口方法:Mapper接口

参数:除id外的所有数据

结果:void 或 int

2.编写SQL语句:SQL映射文件

3.执行方法,测试

对应部分SQL映射文件代码:

<insert id="add" useGeneratedKeys="true" keyProperty="id">
    insert into brand (brand_name,company_name,ordered,description,status)
    values (#{brandName},#{companyName},#{ordered},#{description},#{status});
</insert>

MyBatis事务管理:

openSession():默认开启事务,进行增删改操作后需要使用sqlSession.commit();手动提交事务

openSession(true):可以设置为自动提交事务(或关闭事务)

主键返回

添加数据成功后,获取插入数据库数据的主键的值

设置:

<insert id="add" useGeneratedKeys="true" keyProperty="id">

修改
修改全部字段

1.编写接口方法:Mapper接口

参数:所有数据

结果:void或int

2.编写SQL语句:SQL映射文件

3.执行方法,测试

对应部分SQL映射文件代码:

<update id="update">
    update brand
    set brand_name = #{brandName},
        company_name = #{companyName},
        ordered = #{ordered},
        description = #{description},
        status = #{status}
    where id = #{id};
</update>

修改部分字段

对应部分SQL映射文件代码:

单独使用<if>标签,每句后面的逗号可能会引起语法错误,故需要结合<set>标签

<update id="update01">
    update brand
    <set>
    <if test="brandName != null and brandName != ''">
        brand_name = #{brandName},
    </if>

    <if test="companyName != null and companyName != ''">
        company_name = #{companyName},
    </if>

    <if test="ordered != null">
        ordered = #{ordered},
    </if>

    <if test="description != null and description != ''">
        description = #{description},
    </if>

    <if test="status != null">
        status = #{status}
    </if>
    </set>
    where id = #{id};
</update>

删除
单个删除

1.编写接口方法:Mapper接口

参数:id

结果:void或int

2.编写SQL语句:SQL映射文件

3.执行方法,测试

对应部分SQL映射文件代码:

<delete id="deleteById">
    delete from brand
    where id = #{id};
</delete>

批量删除

1.编写接口方法:Mapper接口

参数:id数组

结果:void或int

2.编写SQL语句:SQL映射文件

3.执行方法,测试

对应部分SQL映射文件代码:

<!--
    mybatis会将数组参数封装为一个Map集合
        * 默认:array = 数组
        * 或使用@Param注解改变map集合的默认key的名称
        * separator="," 表示遍历得到的值用逗号隔开
        * open="(" close=") 表示以左括号开头,右括号结尾
-->
    <delete id="deleteByIds">
        delete from brand
        where id
        in
            <foreach collection="array" item="id" separator="," open="(" close=")">
                #{id}
            </foreach>
        ;
    </delete>

注解

在xxxMapper接口文件写,如:

@Select("select * from brand where id = #{id}")
Brand selectById(int id);

插入、修改、删除操作同理

但是注解只能进行简单的sql操作,一旦sql语句里面涉及到例如动态sql时,就会显得力不从心

故当要完成简单的功能,可以用注解写sql语句;但要完成较复杂的功能,则用配置文件写sql语句

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值