Mybatis框架学习笔记

简介

作用

底层是对JDBC的封装

优点

使用 mybatis 时不需要编写实现类,只需要写需要执行的sql命令

环境搭建

jar
  • jstl
  • log4j
  • mybatis
  • mysql-connector
全局配置文件
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE configuration
    PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
    "http://mybatis.org/dtd/mybatis-3-config.dtd">
    <configuration>
    <environments default="default">
        <environment id="default">
            <transactionManager type="JDBC"></transactionManager>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/ssm?useUnicode=true&amp;characterEncoding=utf8&amp;serverTimezone=GMT%2B8&amp;useSSL=false"/>
                <property name="username" value="root"/>
                <property name="password" value="xxxxxxx"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="mapper/LogMapper.xml"></mapper>
    </mappers>
</configuration>
mapper配置文件

文件作用: 编写需要执行的 SQL 命令

把 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="mapper.LogMapper">
    <select id="selByAccinAccount" resultType="pojo.Log">
    </select>
</mapper>
单独使用mybatis时的执行方法
InputStream is = Resources.getResourceAsStream("myabtis.xml");
//使用工厂设计模式
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
//生产 SqlSession
SqlSession session=factory.openSession();

//a.b为命名空间
List<Flower> list = session.selectList("a.b.selAll");
for (Flower flower : list) {
    System.out.println(flower.toString());
}
session.close();

三种查询方式

  • selectList() 返回值为 List<resultType 属性控制>
  • selectOne() 返回值 Object
  • selectMap() 返回值 Map

路经相关问题

  1. 编写路径为了告诉编译器如何找到其他资源.
  2. 路径分类
  • 相对路径:从当前资源出发找到其他资源的过程

  • 绝对路径:从根目录(服务器根目录或项目根目录)出发找到其他资源的过程

    注意:只要以/开头的都是绝对路径

  1. 绝对路径
  • 如果是请求转发 / 表示项目根目录(WebContent)
  • 其他重定向,
    1. 如果客户端请求的控制器,控制器转发到JSP后,jsp中如果使用相对路径,需要按照控制器的路径去找其他资源.

    使用绝对路径,可以防止上面的问题.

    log4j(日志)

    作用:不仅能把内容输出到控制台,还能把内容输出到文件中.便于观察结果.

    使用步骤
    1. 导入log4j-xxx.jar
    2. 在src下新建log4j.properties(路径和名称都不允许改变)

    log4j.appender.LOGFILE.File 文件位置及名称(日
    志文件扩展名.log)

    log4j关联mapper的namespace

    log4j.rootCategory=DEBUG, CONSOLE ,LOGFILE
    log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppend
    er
    log4j.appender.CONSOLE.layout=org.apache.log4j.Patter
    nLayout
    log4j.appender.CONSOLE.layout.ConversionPattern=%C %d{
    YYYY-MM-dd hh:mm:ss} %m %n
    log4j.appender.LOGFILE=org.apache.log4j.FileAppender
    log4j.appender.LOGFILE.File=D://logs/my.log
    log4j.appender.LOGFILE.Append=true
    log4j.appender.LOGFILE.layout=org.apache.log4j.Patter
    nLayout
    log4j.appender.LOGFILE.layout.ConversionPattern=%C %m %L %n
    
    在mybatis中使用log4j
    <settings>
        <setting name="logImpl" value="LOG4J"/>
    </settings>
    

    parameterType属性

    1. 在 XXXMapper.xml 中等标签的 parameterType 可以控制参数类型
    2. SqlSession的selectList()和selectOne()的第二个参数和selectMap()的第三个参数都表示方法的参数,例:
    People p = session.selectOne("a.b.selById",1);
    System.out.println(p);
    

    在 Mapper.xml 中可以通过#{}获取参数,使用索引,从 0 开始 #{0}表示第一个参数

    #{} 和 ${} 的区别

    #{} 获取参数的内容支持 索引获取,param1 获取指定位置参数, 并且 SQL 使用?占位符。

    • 使用索引,从 0 开始 #{0}表示第一个参数
    • 如果参数是对象#{属性名}, 如果参数是 map 写成#{key}
    • 字 符 串 拼 接 不 使 用 ? , 默 认 找 {} 字符串拼接不使用?,默认找 使?,{内容}内容的 get/set 方法,如
      果写数字,就是一个数字

    typeAliases别名

    给某个类起别名

    示例

    <typeAliases>
        <typeAlias type="com.bjsxt.pojo.People" alias="peo"/>
    </typeAliases>
    

    mapper.xml

    <select id="page" resultType="peo" parameterType="map">
        select * from people limit #{pageStart},#{pageSize}
    </select>
    
    给某个包下所有类起别名,别名为类名,不区分大小写

    mtbatis.xml

    <typeAliases>
        <package name="com.bjsxt.pojo" />
    </typeAliases>
    

    mapper.xml

    <select id="page" resultType="People" parameterType="map">
        select * from people limit #{pageStart},#{pageSize}
    </select>
    

    小结

    • 在 mybatis 中默认是关闭了 JDBC 的自动提交功能
    • JDBC 中 executeUpdate()执行新增,删除,修改的 SQL.返回值 int, 表示受影响的行数.
    • mybatis 中 标签没有 resultType 属性, 认为返回值都是 int
    • 如果出现异常,应该 session.rollback()回滚事务

    Mybatis实现新增

    1. 概念复习

    1.1 功能:从应用程序角度出发,软件具有哪些功能.

    1.2 业务:完成功能时的逻辑.对应 Service 中一个方法

    1.3 事务:从数据库角度出发,完成业务时需要执行的 SQL 集合,统称一个事务.

    事务回滚.如果在一个事务中某个 SQL 执行事务,希望回
    归到事务的原点,保证数据库数据的完整性.

    2.关于自动提交

    在 mybatis 中默认是关闭了 JDBC 的自动提交功能

    2.1 每一个 SqlSession 默认都是不自动提交事务.

    2.2 session.commit()提交事务.

    2.3 openSession(true);自动提交.setAutoCommit(true);

    3.关于底层封装

    mybatis 底层是对 JDBC 的封装.

    3.1 JDBC 中 executeUpdate()执行新增,删除,修改的 SQL.返回值 int, 表示受影响的行数.

    3.2 mybatis 中 标签没有 resultType 属性, 认为返回值都是 int

    4.在 openSession()时 Mybatis 会创建 SqlSession 时同时创建一个Transaction(事务对象),同时 autoCommit 都为 false

    如果出现异常,应该 session.rollback()回滚事务

    新增

    <insert id="ins" parameterType="People">
        insert into people values(default,#{name},#{age})
    </insert>
    
    int index1 = session.insert("a.b.ins", p);
    if(index1>0){
        System.out.println("成功");
        session.commit();
    } else{
        System.out.println("失败");
        session.rollback();
    }
    

    修改

    <update id="upd" parameterType="People">
        update people set name = #{name} where id = #{id}
    </update>
    

    删除

    <delete id="del" parameterType="int">
        delete from people where id = #{0}
    </delete>
    

    接口绑定方案及多参数传递

    实现创建一个接口后把mapper.xml由mybatis 生成接口的实现类,通过调用接口对象就可以获取 mapper.xml 中编写的 sql。

    实现步骤:
    创建一个接口
    • 接口包名和接口名与mapper.xml中namespace相同
    • 接口中方法名和 mapper.xml 标签的 id 属性相同
    在 mybatis.xml 中使用进行扫描接口和mapper.xml
    代码实现步骤

    在 mybatis.xml 中下使用

    <mappers>
        <package name="mapper"/>
    </mappers>
    

    在 mapper 下新建接口

    public interface LogMapper {
        List<Log> selAll();
    }
    

    在mapper 新建一个 xxxMapper.xml

    • namespace 必须和接口全限定路径(包名+类名)一致
    • id 值必须和接口中方法名相同
    • 如果接口中方法为多个参数,可以省略 parameterType
    <mapper namespace="mapper.LogMapper">
    <select id="selAll" resultType="log">
        select * from log
    </select>
    </mapper>
    
    多参数实现方法

    在接口中声明方法

    List<Log> selByAccInAccout(String accin,String accout);
    

    在mapper.xml中添加

    • #{}中使用 0,1,2 或 param1,param2
    <!-- 当多参数时,不需要写 parameterType -->
    <select id="selByAccInAccout" resultType="wz.pojo.Log" >
        select * from log where accin=#{0} and accout=#{1}
    </select>
    
    • 使用注解方法
    /**
    * mybatis 把参数转换为 map 了,其中@Param("key") 参数内
    容就是 map 的 value
    * @param accin123
    * @param accout3454235
    * @return
    */
    List<Log> selByAccInAccout(@Param("accin") String accin123,@Param("accout") String accout3454235);
    

    mapper.xml文件

    <!-- 当多参数时,不需要写 parameterType -->
    <select id="selByAccInAccout" resultType="wz.pojo.Log" >
    select * from log 
    where accin=#{accin} 
    and
    accout=#{accout}
    </select>
    

    动态SQL(很实用)

    1. 根据不同的条件需要执行不同的 SQL 命令.称为动态 SQL
    2. MyBatis 中动态 SQL 在 mapper.xml 中添加逻辑判断等.
    3. if使用
        <select id="selByAccinAccout" resultType="wz.pojo.Log">
            select * from log where 1=1
            <!-- OGNL表达式 -->
            <if test="accIn!=null and accIn!=''">
                and accin=#{accIn}
            </if>
    
            <if test="accOut!=null and accOut!=''">
                and accout=#{accOut}
            </if>
        </select>
    
    • 当编写 where 标签时,如果内容中第一个是 and 去掉第一个
      and
    • 如果中有内容会生成 where 关键字,如果没有内容不
      生成 where 关键字
        <select id="selByAccinAccout" resultType="wz.pojo.Log">
            select * from log
            <where>
                <!-- OGNL表达式 -->
                <if test="accIn!=null and accIn!=''">
                    and accin=#{accIn}
                </if>
    
                <if test="accOut!=null and accOut!=''">
                    and accout=#{accOut}
                </if>
            </where>
    
        </select>
    

    比直接使用少写 where 1=1

    1. 用在修改 SQL 中 set 从句
    • 去掉最后一个逗号
    • 如果里面有内容生成 set 关键字,没有就不生成

    实例

        <update id="upd" parameterType="wz.pojo.Log">
            update log
            <set>
            id=#{id},
                <if test="accIn!=null and accIn!=''">
                    accin=#{accIn},
                </if>
                <if test="accOut!=null and accOut!=''">
                    accout=#{accOut},
                </if>
            </set>
            where accin=#{accIn}
        </update>
    
    1. Trim
    • prefix 在前面添加内容
    • prefixOverrides 去掉前面内容
    • suffix 在后面添加内容
    • suffixOverrieds 去掉后面内容
    • 执行顺序去掉内容后添加内容
        <select id="selByLog" parameterType="wz.pojo.Log" resultType="wz.pojo.Log">
            select * from log
            <trim prefix="where" prefixOverrides="and">
                and accin=#{accIn}
            </trim>
        </select>
    
    
    1. bind
    • 作用:给参数重新赋值
    • 使用场景:1.模糊查询 2.在原内容前后添加内容

    resultMap标签

    resultMap N+1查询
    • N+1:先查询出某个表的全部信息,根据这个表的信息
      查询另一个表的信息
    • 与业务装配的区别:在 service 里面写的代码,由 mybatis 完成装配
    实现步骤

    1.查询关联对象(1对1)

    在 Student 实现类中包含了一个 Teacher 对象

    public class Student {
        private int id;
        private String name;
        private int age;
        private int tid;
    
        private Teacher teacher;
    

    在 TeacherMapper 中提供一个查询

        <select id="selById" parameterType="int" resultType="wz.pojo.Teacher">
            select * from teacher
            where id=#{0};
        </select>
    

    在StudentMapper中

        <resultMap id="stuMap" type="wz.pojo.Student">
            <id property="id" column="id"/>
            <result property="name" column="name"/>
            <result property="age" column="age"/>
            <result property="tid" column="tid"/>
    
            <association property="teacher" select="wz.mapper.TeacherMapper.selById" column="tid">
            </association>
    
        </resultMap>
        <select id="selAll" resultMap="stuMap">
            select * from student
        </select>
    

    简化方式

    N+1 时,如果列名和属性名相同可以不配置

        <resultMap id="stuMap" type="wz.pojo.Student">
        
            <!-- N+1 时,如果列名和属性名相同可以不配置-->
            
            <result property="tid" column="tid"/>
    
            <association property="teacher" select="wz.mapper.TeacherMapper.selById" column="tid">
            </association>
    
        </resultMap>
        <select id="selAll" resultMap="stuMap">
            select * from student
        </select>
    

    2.查询关联对象(1对多)

        <resultMap id="mymap" type="wz.pojo.Teacher">
            <id column="id" property="id"/>
            <result column="name" property="name"/>
            <collection property="list" select="wz.mapper.StudentMapper.selByTid" column="id"/>
        </resultMap>
    
        <select id="selAll" resultMap="mymap">
            select * from teacher
        </select>
    
        <select id="selByTid" resultType="wz.pojo.Student">
            select * from student
            where tid=#{0}
        </select>
    
    使用实现加载集合数据(联合查询方式)

    TeacherMapper

        <resultMap id="mymap1" type="wz.pojo.Teacher">
            <id column="tid" property="id"/>
            <result column="tname" property="name"/>
            <collection property="list" ofType="wz.pojo.Student">
                <id column="sid" property="id"/>
                <result column="sname" property="name"/>
                <result column="age" property="age"/>
                <result column="tid" property="tid"/>
            </collection>
        </resultMap>
        <select id="selAll1" resultMap="mymap1">
             select t.id tid, t.name tname, s.id sid, s.name sname, age, tid
             from teacher t left join student s on t.id = s.tid
        </select>
    

    mybatis 可以通过主键判断对象是否被加载过

    Mybatis注解

    1. 注解:为了简化配置文件
    2. Mybatis的注解简化mapper.xml文件(涉及动态SQL依然用mapper.xml)
    3. mapper.xml和注解可以共存
    4. 使用注解时mybatis.xml中使用
    1. 查询
    @Select("select * from teacher")
    List<Teacher> selAll();
    
    1. 新增
    @Insert("insert into teacher values(default,#{name})")
    int insTeacher(Teacher teacher);
    
    1. 修改
    @Update("update teacher set name=#{name} where id=#{id}")
    int updTeacher(Teacher teacher);
    
    1. 删除
    @Delete("delete from teacher where id=#{0}")
    int delById(int id);
    
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值