Mybatis

目录

一、概述

二、Mybatis案例

1.项目结构

2.修改pom文件,添加mybatis的jar包依赖

3.创建核心配置文件,指定连接数据库的参数

4.创建映射文件,写SQL

5.创建User类

6.创建测试类

三、其它知识点

1.别名

2.xml的转义符号

3.参数值:paramterType

4.返回值:resultType

5.返回值:resultMap

6.#和$的区别

7.sql和include

8.if

9.where

10.set

11.foreach

 四、动态SQL

1.需求

2.创建Dept类,用来完成ORM

3.创建DeptMapper.xml,用来写SQL

4.修改核心配置文件,引用新的映射文件

5.创建测试文件

五、Mybatis的接口开发

1.结构

2.修改映射文件,把namespace的值改成接口的全路径

3.创建接口文件

4.测试类

六、ResultMap

1.概述

2.测试

七、优化简化resultmap

八、SpringBoot 整合Mybatis流程

九、Mybatis调用流程


一、概述

简化了JDBC操作数据库的过程,是一个优秀的ORM框架。
两个配置文件:
核心配置文件 – 用来配置数据库的连接的参数(例:mybatis-config.xml)
映射文件 – 用来写SQL(例:UserMapper.xml)
两个核心的工具类:
SqlSessionFactory – 会话工厂,用来产生会话
SqlSession – 会话,用来执行SQL
ORM:对象关系映射
是指把表里字段的值 自动映射给 类里的属性

二、Mybatis案例

1.项目结构

 

2.修改pom文件,添加mybatis的jar包依赖

<dependencies>
    <!--mybatis依赖包-->
     <dependency>
         <groupId>org.mybatis.spring.boot</groupId>
         <artifactId>mybatis-spring-boot-starter</artifactId>
         <version>2.1.4</version>
     </dependency>
     <!--jdbc依赖包-->
     <dependency>
         <groupId>mysql</groupId>
         <artifactId>mysql-connector-java</artifactId>
         <version>5.1.48</version>
     </dependency>
 </dependencies>

3.创建核心配置文件,指定连接数据库的参数

<?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">

<!-- mybatis的核心配置文件 -->
<configuration>

    <!--可以配置多个数据库连接的环境,使用default指定默认用哪个-->
    <environments default="test">
        <!--配置了具体连接数据库的参数-->
        <environment id="test">
            <!--使用的事务管理器-->
            <transactionManager type="JDBC"></transactionManager>
            <!--数据源:就是制定了数据库连接时的参数-->
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/mybatisdb2?characterEncoding=utf8&amp;serverTimezone=Asia/Shanghai" />
                <property name="username" value="root"/>
                <property name="password" value="root"/>
            </dataSource>
        </environment>
    </environments>

<!--引入映射文件-->
    <mappers>
        <mapper resource="UserMapper.xml"></mapper>
    </mappers>

</configuration>


4.创建映射文件,写SQL

<?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">

<!--这是映射文件,namespace用来作为文件的唯一标识
-->
<mapper namespace="UserMapperNS">
    <!--select标签表示要发起查询的SQL,
    id是SQL语句的唯一标识,
    resultType用来完成ORM,把表里的字段值 自动映射 类里的属性
    -->
    <select id="getAll" resultType="cn.tedu.pojo.User">
        select * from user
    </select>
</mapper>

5.创建User类

package cn.tedu.pojo;
//Mybatis自动完成ORM,把表里的字段的值 查到 封装给 类里的属性
//要求:属性名要和字段名一样
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
    private Integer id;
    private String name;
    private String addr;
    private Integer age;
}

6.创建测试类

public class Test1 {
    @Test
    public void get() throws IOException {
        //1,读取核心配置文件
        InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
        //2,创建会话工厂
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
        //3,创建会话
        SqlSession session = factory.openSession();
        //4,执行SQL
        //session.selectList("namespace的值.id的值");//唯一的定位了SQL
        List<User> list = session.selectList("UserMapperNS.getAll");//查询出多个结果
        //5,处理结果
        for(User u : list){
            System.out.println(u);
        }
    }
}

三、其它知识点

1.别名

–设置别名:修改核心配置文件,加一个typeAliases标签

 <!--用来设置别名 type是类的全路径 alias是以后要用的别名-->
  <typeAliases>
      <typeAlias type="cn.tedu.pojo.User" alias="User"></typeAlias>
  </typeAliases>

–使用别名:在映射文件里,在resultType处直接使用别名

 <select id="getAll" resultType="User">
    select * from user
 </select>

2.xml的转义符号

3.参数值:paramterType

指定参数类型,通常制定一个对象类型。

4.返回值:resultType

完成ORM的映射关系所在。这里指定的cd.tedu.mybatis.domain.User代表把结果集转换成一个User对象实例。

5.返回值:resultMap

resultMap 用于对复杂对象结构时,对应的ResultMap结构名称

6.#和$的区别

两种方式都可以获取参数的值。区别如下:

#: 使用#{parameterName}引用参数的时候,Mybatis会把这个参数认为是一个字符串,例如传入参数是"Smith",那么在SQL(Select * from emp where name = #{employeeName})使用的时候就会转换为Select * from emp where name = 'Smith'。

$: 不做字符串拼接,SQL(Select * from emp where name = ${employeeName})使用的时候就会转换为Select * from emp where name = Smith。此时,如果字段是varchar类型直接抛出SQL异常。(如果where后输入1=1,也能获取要获取的信息,存在注入安全隐患)

!!!从安全性上考虑,能使用#尽量使用#来传参,因为这样可以有效防止SQL注入的问题。

7.sql和include

Sql标签用来提取SQL片段,来提高SQL的复用.

使用位置需要通过include引用指定的SQL片段.

<sql id="cols">
id,title,sell_point,price,num,barcode,image,cid,status,created,updated
</sql>

<select id="find" resultType="Item" parameterType="Item">
SELECT <include refid="cols"/> FROM tb_item
</select>

8.if

执行SQL时,可以添加一些判断条件.

<select id="find" resultType="Item" parameterType="Item">
SELECT <include refid="cols"/> FROM tb_item where
	<if test="title != null"> title like #{title} </if>
	<if test="sellPoint != null">and sell_point like #{sellPoint}</if>
</select>

9.where

去掉条件中可能多余的and或者or:

<select id="find" resultType="Item" parameterType="Item">
SELECT <include refid="cols"/> FROM tb_item
<where> 
	<if test="title != null"> title like #{title} </if>
	<if test="sellPoint != null">and sell_point like #{sellPoint}</if>
</where>
</select>

10.set

去掉最后可能多余的逗号:

<update id="update">
UPDATE teachers 
<set>
		<if test="tname != null">tname=#{tname},</if>
		<if test="tsex != null">tsex=#{tsex},</if>
		<if test="tbirthday != null">tbirthday=#{tbirthday},</if>
		<if test="prof != null">prof=#{prof},</if>
		<if test="depart != null">depart=#{depart}</if>
</set>
WHERE tno=#{tno}	
</update>

11.foreach

用于in子查询中的多个值的遍历:

<delete id="delete">
DELETE FROM teachers WHERE tno IN 
<!--ids是给SQL传递的参数Map里的key,item的值就像是for循环里的i变量名-->
<foreach collection="ids" item="id" open="(" close=")" separator=",">
#{id}
</foreach>	
</delete>

调用代码:

Map<String,Object> map = new HashMap<String,Object>();
String[] ps = {"1","22"};
map.put("ids", ps );
mapper.delete(map);

 四、动态SQL

1.需求

操作dept表

2.创建Dept类,用来完成ORM

package cn.tedu.pojo;
//Mybatis自动完成ORM,把表里的字段的值 查到 封装给 类里的属性
//要求:属性名要和字段名一样
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Dept {
    private Integer id;
    private String dname;
    private String loc;
}

3.创建DeptMapper.xml,用来写SQL

<?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="DeptMapperNS">
    <!-- 1. 提取SQL片段,提高复用性-->
    <sql id="cols">
        id,dname,loc
    </sql>

    <!--resultType使用了别名,因为在核心配置文件里配过了 -->
    <select id="getAll" resultType="Dept">
        select
            <include refid="cols"></include> /* 2.使用了指定的SQL片段*/
        from dept;
    </select>
    <!--查询name=java教研部 的部门信息-->
    <select id="getByName" resultType="Dept">
        select
            <include refid="cols"></include>
        from dept
        /* if用来判断,test写判断条件,满足条件才执行,不满足不执行*/
        <if test="dname != null">
             where dname = #{dname}
        </if>
    </select>

    <!--查询id是1或者是3的部门信息
        /* 可以去除条件中多余的or 或者 and关键字 */
    -->
    <select id="getByIds" resultType="Dept">
        select 
            <include refid="cols"></include>
        from dept
        <where>
                <if test="id!=null">
                    id=#{id}
                </if>
            or id=3
        </where>
    </select>

    <!--删除id是1 2 3 的部门信息-->
    <delete id="delByIds">
        /*delete from dept where id in(1,2,3) 参数写死了,最好动态解析*/
        delete from dept where id in(
            /*foreach用来遍历,collection属性的值是固定值array list map里的key
                item相当于遍历得到的数据 separator是数据间的分隔符
            */
            <foreach collection="array" item="i" separator="," >
                #{i} /*获取了遍历得到的数据*/
            </foreach>
        )
    </delete>
</mapper>




4.修改核心配置文件,引用新的映射文件

<?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">

<!-- mybatis的核心配置文件 -->
<configuration>

    <!--用来设置别名 type是类的全路径 alias是以后要用的别名-->
    <typeAliases>
        <typeAlias type="cn.tedu.pojo.Dept" alias="Dept"></typeAlias>
    </typeAliases>

    <!--可以配置多个数据库连接的环境,使用default指定默认用哪个-->
    <environments default="test">
        <!--配置了具体连接数据库的参数-->
        <environment id="test">
            <!--使用的事务管理器-->
            <transactionManager type="JDBC"></transactionManager>
            <!--数据源:就是制定了数据库连接时的参数-->
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/mybatisdb2?characterEncoding=utf8&amp;serverTimezone=Asia/Shanghai" />
                <property name="username" value="root"/>
                <property name="password" value="root"/>
            </dataSource>
        </environment>
    </environments>

    <!--引入映射文件-->
    <mappers>
        <mapper resource="DeptMapper.xml"></mapper>
    </mappers>

</configuration>


5.创建测试文件

public class Test1 {
    @Test
    public void get() throws IOException {
        InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
        SqlSession session = factory.openSession();
        //执行SQL
        List<Dept> list = session.selectList("DeptMapperNS.getAll");
        for (Dept d : list) {
            System.out.println(d);
        }
        //Mybatis的以及缓存:相同的SqlSession执行相同的SQL时会查缓存不会再次发起SQL了
        List<Dept> list2 = session.selectList("DeptMapperNS.getAll");
        for (Dept d : list2) {
            System.out.println(d);
        }
        //selectList(1,2)--1是SQL的定位2是SQL需要的参数
        List<Dept> list1 = session.selectList("DeptMapperNS.getByName", null);
        for (Dept d : list1) {
            System.out.println(d);
        }

        //selectList(1,2)--1是SQL的定位2是SQL需要的参数
        List<Dept> list3 = session.selectList("DeptMapperNS.getByIds",null);
        for (Dept d : list3) {
            System.out.println(d);
        }

        int[] a = {1,2,3};
        session.delete("DeptMapperNS.delByIds",a);//给SQL传入多个参数
//Mybatis不会自动提交事务,需要手动提交:openSession(true)或者commit()
        session.commit();//增删改都需要提交事务,不然对数据库没有持久性的影响
        System.out.println("删掉了");

    }
}

五、Mybatis的接口开发

1.结构

2.修改映射文件,把namespace的值改成接口的全路径

<?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="cn.tedu.dao.DeptDao">
    <!-- 1. 提取SQL片段,提高复用性-->
    <sql id="cols">
        id,dname,loc
    </sql>
    <!--resultType使用了别名,因为在核心配置文件里配过了 -->
    <!--查询name=java教研部 的部门信息-->
    <select id="getByName" resultType="Dept">
        select
            <include refid="cols"></include>
        from dept
        /* if用来判断,test写判断条件,满足条件才执行,不满足不执行*/
        <if test="dname != null">
             where dname = #{dname}
        </if>
    </select>
</mapper>

3.创建接口文件

接口文件的全路径 = Mapper.xml里namespace的值
接口中的方法名 = Mapper.xml里的SQL的id值
接口中的方法的返回值 = Mapper.xml里的SQL的resultType值

package cn.tedu.dao;
//接口文件的全路径 = Mapper.xml里namespace的值
public interface DeptDao {
    /**
     * 获取所有
     * @return 所有部门信息
     */
    List<Dept> getAll();
    /**
     * 根据名称获取部门信息
     * @return 相关名字的部门信息
     */
    List<Dept> getByName(String name);
    List<Dept> getByIds(int[] id);
    void delByIds(int[] ids);
}

4.测试类

public class Test2 {
    @Test
    public void get() throws IOException {
        //加载核心配置文件
        InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
        //创建会话工厂
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
        //创建会话
        SqlSession session = factory.openSession();
        //获取指定的接口
        DeptDao dao = session.getMapper(DeptDao.class);
        //调用接口里的方法
        List<Dept> list = dao.getAll();
        for (Dept dept : list) {
            System.out.println(dept);
        }
        //根据名称获取部门信息
        List<Dept> list2 = dao.getByName("开发");
        for (Dept dept : list2) {
            System.out.println(dept);
        }
    }
}

六、ResultMap

1.概述

resultType只能完成简单的ORM,只能完成那些 字段名 和 属性名一致的情况
字段名 和 属性名 不一样的情况,resultType必须换成resultMap,否则无法ORM

2.测试

(1)项目结构

(2)创建了表,加了记录

CREATE TABLE `user_info` (
  `id` int(11) NOT NULL auto_increment,
  `user_name` varchar(20) default NULL,
  `user_addr` varchar(20) default NULL,
  `user_age` int(11) default NULL,
  PRIMARY KEY  (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

(3)修改pom文件,添加mybatis的jar包(略)

(4)创建核心配置文件

<?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">
<!-- mybatis的核心配置文件,配置了事务管理,数据源 -->
<configuration>
    <!--environments可以配置多个数据库的连接信息,default指定默认的环境-->
    <environments default="test">
        <environment id="test">
            <!--使用的事务管理器-->
            <transactionManager type="JDBC"></transactionManager>
            <!--配置了数据源-->
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/mybatisdb2?characterEncoding=utf8&amp;serverTimezone=Asia/Shanghai" />
                <property name="username" value="root"/>
                <property name="password" value="root"/>
            </dataSource>
        </environment>
    </environments>
    <!--引入映射文件-->
    <mappers>
        <mapper resource="userInfoMapper.xml"></mapper>
    </mappers>
</configuration>

(5)创建映射文件

<?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="cn.tedu.dao.UserInfoMapper">
    <!-- 查询所有 ,字段名和属性名不一样,resultType换成resultMap
        resultType="cn.tedu.pojo.UserInfo"
    -->
    <!-- ORM:是指把字段的值查到以后  交给 同名属性保存
        使用resultMap: 字段名 和 属性名 不一样
        id是唯一标识  type是类的全路径
    -->
    <resultMap id="abc" type="cn.tedu.pojo.UserInfo">
        <result column="user_name" property="userName"></result>
        <result column="user_addr" property="userAddr"></result>
        <result column="user_age" property="userAge"></result>
    </resultMap>
    <!--resultMap属性是解决了resultType解决不了的问题,引用指定的resultMap-->
    <select id="selectList" resultMap="abc">
        select * from user_info
    </select>

</mapper>

 (6)创建接口类

package cn.tedu.dao;

import cn.tedu.pojo.UserInfo;

import java.util.List;

public interface UserInfoMapper {
    List<UserInfo> selectList();//查询所有
}


 (7)创建pojo类

@Data
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
public class UserInfo {
    private Integer id;
    private String userName;
    private String userAddr;
    private Integer userAge;
}

(8)测试

public class Test1 {
    @Test
    public void all() throws IOException {
        InputStream in = Resources.getResourceAsStream(
                        "mybatis-config.xml");
        SqlSessionFactory factory = new SqlSessionFactoryBuilder()
                                            .build(in);
        //true表示自动提交事务
        SqlSession session = factory.openSession(true);
        //获取指定接口
        UserInfoMapper mapper = session.getMapper(UserInfoMapper.class);
        //调用方法
        List<UserInfo> list = mapper.selectList();
        for (UserInfo uf : list) {
            //UserInfo(id=1, userName=null, userAddr=null, userAge=null)
            System.out.println(uf);
        }
    }


}

七、优化简化resultmap

第一步:在核心配置文件中开启驼峰规则

 <settings>
        <!--开启驼峰规则,简化resultMap的编写-->
        <setting name="mapUnderscoreToCamelCase" value="true" />
  </settings>

 第二步:resultMap标签中添加新属性 autoMapping=“true” 是开启了自动驼峰规则的匹配

<?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="cn.tedu.dao.UserInfoMapper">
    <!-- 查询所有 ,字段名和属性名不一样,resultType换成resultMap
        resultType="cn.tedu.pojo.UserInfo"
    -->
    <!-- ORM:是指把字段的值查到以后  交给 同名属性保存
        使用resultMap: 字段名 和 属性名 不一样
        id是唯一标识  type是类的全路径  
        autoMapping="true"是开启了自动驼峰规则的匹配
    -->
    <resultMap autoMapping="true" id="abc" type="cn.tedu.pojo.UserInfo">
       <!-- <result column="user_name" property="userName"></result>
        <result column="user_addr" property="userAddr"></result>
        <result column="user_age" property="userAge"></result>-->
    </resultMap>
    <!--resultMap属性是解决了resultType解决不了的问题,引用指定的resultMap-->
    <select id="selectList" resultMap="abc">
        select * from user_info
    </select>

</mapper>



八、SpringBoot 整合Mybatis流程

(1)导入依赖jar包 数据库驱动/JDBC包/Spring整合Mybatis包

(2)编辑application.yml文件 配置数据源/配置Spring整合Mybatis

(3)编辑Mybatis 接口文件/编辑xxx.xml映射文件

(4)通过@MapperScan为接口创建代理对象

九、Mybatis调用流程

(1)Spring容器为接口创建代理对象. Spring容器启动对象立即创建

(2)根据 @Autowired 注解动态注入Mapper接口的代理对象

(3)用户通过Mapper接口调用方法.(执行业务操作)

(4)Mybatis根据接口方法动态匹配xml的映射文件:

          1.根据Mapper的接口路径匹配xml映射文件中的 com.jt.mapper.UserMapper
          2.根据接口的方法 匹配xml映射文件中的Sql ID 之后执行Sql语句

(5)Mybatis将结果集封装为对象 之后返回.

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值