MyBatis基础学习详细总结

一. Mybatis基础

1. 相关概念

1.1框架介绍

  • 框架是一款半成品软件,我们可以基于这个半成品软件继续开发,来完成我们个性化的需求!
  • 简单来说, 就是"框架把一些不变的东西提前写好, 让我们能更快更好的完成程序的开发"

1.2 ORM介绍

  • ORM(Object Relational Mapping): 对象关系映射
    • object:指的是实体对象,javabean
    • relational:指的是关系型数据库,比如mysql
    • Mapping: 映射,一 一对应的关系
  • 简单来说,ORM可以实现对象与数据库表之间的自动映射

1.3 Mybatis

  • mybatis 是一个优秀的基于java的, 并且实现了ORM映射的持久层框架,它内部封装了jdbc

  • mybatis通过xml或注解的方式实现对数据库的持久化操作

  • MyBatis官网地址:http://www.mybatis.org/mybatis-3/

2. 快速入门

2.1 MyBatis开发步骤

①添加MyBatis的jar包

②编写实体类(对应数据库中的表)

③编写核心配置文件SqlMapConfig.xml

④编写映射配置文件

⑤编写测试类

2.2 具体操作

① 添加MyBatis的jar包

mysql-connector-java-5.1.37-bin.jar
mybatis-3.5.3.jar
og4j-1.2.17.jar

② 编写实体类

  //学生类
    //该类要和数据库表进行一一对应
    public class Student {
        private Integer id;
        private String name;
        private Integer age;
        //省略get个set方法
    }

③ 编写核心文件SqlMapConfig.xml

 <?xml version="1.0" encoding="UTF-8" ?>
    <!--MyBatis的DTD约束-->
    <!DOCTYPE configuration
     		PUBLIC "-//mybatis.org//DTD Config 3.0//EN" 
    		"http://mybatis.org/dtd/mybatis-3-config.dtd">
    
    
    <!--configuration 核心根标签-->
    <configuration>
        <!--environments配置数据库环境,环境可以有多个。default属性指定使用的是哪个-->
        <environments default="mysql">
            <!--environment配置数据库环境  id属性唯一标识-->
            <environment id="mysql">
                <!-- transactionManager事务管理。 type属性,采用JDBC默认的事务-->
                <transactionManager type="JDBC"></transactionManager>
                <!-- dataSource数据源信息   type属性 连接池-->
                <dataSource type="POOLED">
                    <!-- property获取数据库连接的配置信息 -->
                    <property name="driver" value="com.mysql.jdbc.Driver" />
                    <property name="url" value="jdbc:mysql://192.168.59.143:3306/db1" />
                    <property name="username" value="root" />
                    <property name="password" value="root" />
                </dataSource>
            </environment>
        </environments>
    
        <!-- mappers引入映射配置文件 -->
        <mappers>
            <!-- resource属性指定映射配置文件的位置 -->
            <mapper resource="StudentMapper.xml"/>
        </mappers>
    </configuration>

④ 编写映射配置文件StudentMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!--MyBatis的DTD约束 直接复制-->
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<!-- mapper:核心根标签 namespace属性:名称空间 -->
<mapper namespace="StudentMapper">
    <!--
        select:查询功能的标签.   insert:添加  update:修改  delete:删除
        id属性:唯一标识
        resultType属性:指定结果映射对象类型
        parameterType属性:指定参数映射对象类型
    -->
    <select id="selectAll" resultType="com.shuai.bean.Student">
        SELECT * FROM student
    </select>
    
</mapper>

⑤ 编写测试类

 @Test
public void selectAll() throws Exception{
    //1.加载核心配置文件
    InputStream is = Resources.getResourceAsStream("MyBatisConfig.xml");

    //2.获取SqlSession工厂对象
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);

    //3.通过SqlSession工厂对象获取SqlSession对象
    SqlSession sqlSession = sqlSessionFactory.openSession();

    //4.执行映射配置文件中的sql语句,并接收结果(参数是StudentMapper.xml中的selectAll)
    List<Student> list = sqlSession.selectList("StudentMapper.selectAll");

    //5.处理结果
    for (Student stu : list) {
        System.out.println(stu);
    }

    //6.释放资源
    sqlSession.close();
    is.close();
}

3. 映射配置文件

3.1 配置信息

   <?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="StudentMapper">
       
        <insert id="insert" parameterType="student">
            INSERT INTO student VALUES (#{id},#{name},#{age})
        </insert>
    
        <update id="update" parameterType="student">
            UPDATE student SET name = #{name},age = #{age} WHERE id = #{id}
        </update>
    
        <delete id="delete" parameterType="int">
            DELETE FROM student WHERE id = #{id}
        </delete>
         
        <select id="selectAll" resultType="student">
            SELECT * FROM student
        </select>
    
        <select id="selectById" resultType="student" parameterType="int">
            SELECT * FROM student WHERE id = #{id}
        </select>
    
    </mapper

3.2 注意事项

  //简单类型:基本数据类型+String  	复杂类型:除了基本数据类型和String
    1.参数是简单类型,则parameterType可以省略
    2.参数如果只有一个,且是简单类型时,#{id}可以随便写,都可以获取参数的值
    3.如果参数是复杂类型,则#{id}就相当于调用参数的getId方法,获取对应的参数值
    4.返回值是简单类型,则resultType可以省略
    5.返回值是集合类型,则resultType只写集合中元素的数据类型

4. 核心配置文件

4.1 引入外部properties

① jdbc.properties

   driver=com.mysql.jdbc.Driver
    url=jdbc:mysql://192.168.59.143:3306/db1
    username=root
    password=root

② 引入配置文件

 <!--在MyBatis的核心配置文件中,引入数据库连接的配置文件-->
    <properties resource="jdbc.properties"/>

③ 获取配置信息

   <!-- 在MyBatis的核心配置文件中, 获取引入的properties文件中的配置信息 -->
    <property name="driver" value="${driver}" />
    <property name="url" value="${url}" />
    <property name="username" value="${username}" />
    <property name="password" value="${password}" />

4.2 起别名

4.2.1 语法

  <!--起别名-->
    <typeAliases>
        <!-- 给Student类起别名为"student" -->
        <typeAlias type="com.shuai.bean.Student" alias="student"/>
        <!-- 给com.itheima.bean包下所有的类起别名,别名为类名的小写名字 -->
        <!--<package name="com.shuai.bean"/>-->
        </typeAliase>
    </typeAliases>

4.2.1 作用

当给实体类起别名后, 在MyBatis映射配置文件中的参数或返回值中, 可以直接使用别名, 并且别名不区分大小写

5. selectKey标签

5.1 概述

selectKey标签只能用在增删改语句中, 它可以在"增删改"语句执行前后, 增加对应操作.

5.2 案例

  <insert id="insert" parameterType="student">
        <selectKey keyProperty="id" order="AFTER" >
            SELECT LAST_INSERT_ID()
        </selectKey>
        INSERT INTO student VALUES (#{id},#{name},#{age})
    </insert>

二. Mybatis进阶

1. 接口代理MyBatis

1.1 接口开发规范

  1. Mapper.xml文件中的namespace与mapper接口的全限定名相同
  2. Mapper接口的包名和Mapper.xml文件的文件夹路径相同
  3. Mapper接口方法名和Mapper.xml中定义的每个statement的id相同
  4. Mapper接口方法的输入参数类型和mapper.xml中定义的每个sql的parameterType的类型相同
  5. Mapper接口方法的输出参数类型和mapper.xml中定义的每个sql的resultType的类型相同

1.2 实际代码实现

① 定义Mapper接口

public interface StudentMapper {
    //查询全部
    public abstract List<Student> selectAll();

    //根据id查询
    public abstract Student selectById(Integer id);

    //新增数据
    public abstract Integer insert(Student stu);

    //修改数据
    public abstract Integer update(Student stu);

    //删除数据
    public abstract Integer delete(Integer id);
}

② 创建映射文件

 <?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.shuai.mapper.StudentMapper">
    
        <select id="selectAll" resultType="student">
            SELECT * FROM student
        </select>
    
        <select id="selectById" resultType="student" parameterType="int">
           SELECT * FROM student WHERE id = #{id}
        </select>
    
        <insert id="insert" parameterType="student">
            INSERT INTO student VALUES (#{id},#{name},#{age})
        </insert>
    
        <update id="update" parameterType="student">
            UPDATE student SET name = #{name},age = #{age} WHERE id = #{id}
        </update>
    
        <delete id="delete" parameterType="int">
            DELETE FROM student WHERE id = #{id}
        </delete>
    
    </mapper>

③ Service调用接口方法

  public class StudentServiceImpl implements StudentService {
    
        @Override
        public List<Student> selectAll() {
            //1.获取MyBatis的数据库联接对象SqlSession
            SqlSession sqlSession = MyBatisUtils.getSqlSession();
            //2.获取Mapper的实现类对象, 相当于 StudentMapper mapper = new StudentMapperImpl();
            StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
            //3.调用Mapper实现类对象的方法
            List<Student> list = mapper.selectAll();
            //4.关闭SqlSession
            sqlSession.close();
            //5.返回结果
            return list;
        }
    
        @Override
        public Student selectById(Integer id) {
            SqlSession sqlSession = MyBatisUtils.getSqlSession();
            StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
            Student stu = mapper.selectById(id);
            sqlSession.close();
            return stu;
        }
    
        @Override
        public Integer insert(Student stu) {
            SqlSession sqlSession = MyBatisUtils.getSqlSession();
            StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
            Integer result = mapper.insert(stu);
            sqlSession.close();
            return result;
        }
    
        @Override
        public Integer update(Student stu) {
            SqlSession sqlSession = MyBatisUtils.getSqlSession();
            StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
            Integer result = mapper.update(stu);
            sqlSession.close();
            return result;
        }
    
        @Override
        public Integer delete(Integer id) {
            SqlSession sqlSession = MyBatisUtils.getSqlSession();
            StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
            Integer result = mapper.delete(id);
            sqlSession.close();
            return result;
        }
    }

2. 动态sql语句

2.1 概述

MyBatis支持动态SQL语句, 也就是说, SQL语句可以动态生成

2.2 if标签

① 接口方法

  //多条件查询. (id,name,age)有谁就查询谁
    public abstract List<Student> selectCondition(Student stu);

② 配置文件

   <select id="selectCondition" resultType="student" parameterType="student">
        select * from student
        <where>
            <if test="id != null">
               AND id = #{id}
            </if>
            <if test="name != null">
                AND name = #{name}
            </if>
            <if test="age != null">
                AND age = #{age}
            </if>
        </where>
    </select>

③ 注意事项

1.if标签的test中,书写的就是判断条件
2.test中书写的id,也是调用参数的getId方法.
3.where标签会自动判断条件是否是第一个条件,如果是第一个条件,则会自动去掉AND联接符.

2.3 foreach标签

① 接口方法

   //根据多个id查询
    public abstract List<Student> selectByIds(List<Integer> ids);

② 配置文件

  <select id="selectByIds" resultType="student" parameterType="list">
        select * from student
        <where>
            <foreach collection="list" open="id IN (" close=")" item="id" separator=",">
                #{id}
            </foreach>
        </where>
    </select>

③ 注意事项

  1.foreach标签的collection属性,在参数是list集合时,书写list. 参数是数组时,书写的是array
    2.open属性表示的是拼接的时候的前缀,close属性表示的是拼接的时候的后缀
    3.idea属性表示的是定义的变量,在遍历时,该变量依次存储着集合或数组中的每个元素
    4.foreach标签体中的#{id}表示遍历时,每次都获取id中的值
    5.separator表示在拼接时,变量之间的间隔.
    6.上述配置,如果参数ids的值是1,2,3, 则拼接后的sql语句为"select * from student where id IN (1, 2, 3)"

2.4 SQL片段抽取

所谓的sql片段抽取, 就是把映射配置文件中的公共sql语句部分抽取.

   <mapper namespace="com.shuai.mapper.StudentMapper">
    	<!--抽取-->
        <sql id="select" >
            SELECT * FROM student
        </sql>
        
        <select id="selectAll" resultType="student">
            <!--引用,调用该片段时,会自动把抽取到的片段拼接到这里-->
            <include refid="select"/>
        </select>
    
        <select id="selectById" resultType="student" parameterType="int">
            <!--引用-->
            <include refid="select"/> WHERE id = #{id}
        </select>
    </mapper>

3. 分页插件

3.1 开发步骤

① 导入jar包

jsqlparser-3.1.jar
pagehelper-5.1.10.jar

② 配置PageHelper插件

  <!-- 在mybatis核心配置文件中配置,位置放在typeAliases之后 -->
    <!-- 注意:interceptor:拦截器,插件都是以拦截器形式实现的 --> 
    <plugins>       
        <plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin>
    </plugins>

③ 在查询语句前添加分页条件

@Test
public void selectPaging() throws Exception{
   	SqlSession sqlSession = MyBatisUtils.getSqlSession();
    StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);

    //在查询语句前添加分页条件即可.
    //注意: 参数1:当前页码,参数2:每页显示几条
    PageHelper.startPage(3,3);    
    List<Student> list = mapper.selectAll();

    
    for (Student student : list) {
        System.out.println(student);
    }
    sqlSession.close();
    is.close();
}

3.2 分页参数

把分页查询到的List集合,封装为PageInfo对象, 从PageInfo对象中获取分页参数

  //获取分页相关参数
    PageInfo<Student> info = new PageInfo<>(list);
    System.out.println("总条数:" + info.getTotal());
    System.out.println("总页数:" + info.getPages());
    System.out.println("当前页:" + info.getPageNum());
    System.out.println("每页显示条数:" + info.getPageSize());
    System.out.println("上一页:" + info.getPrePage());
    System.out.println("下一页:" + info.getNextPage());
    System.out.println("是否是第一页:" + info.isIsFirstPage());
    System.out.println("是否是最后一页:" + info.isIsLastPage());

4.多表操作

4.1 概述

在MyBatis中, 多表模型只需要分析两种即可:

一对一模型.

一对多模型.

4.2 一对一模型操作

4.2.1 模型示例

以用户表和订单表为例,站在订单表的角度看, 一个订单只从属于一个用户

4.2.2 修改Order实体

//主表-站在谁的角度,谁就是主表
public class Order {
    private int id;
    private Date ordertime;
    private double total;

    //在主表中,添加一个从表的对象.
    //表示:一个订单只属于一个用户
    private User user;
}

//从表
public class User {    
    private int id;
    private String username;
    private String password;
    private Date birthday;
}

4.2.3 创建OrderMapper接口

public interface OrderMapper {
    List<Order> findAll();
}

4.2.4 配置OrderMapper.xml

   <mapper namespace="com.shuai.mapper.OrderMapper">
        <resultMap id="orderMap" type="com.shuai.domain.Order">
            <result column="uid" property="user.id"></result>
            <result column="username" property="user.username"></result>
            <result column="password" property="user.password"></result>
            <result column="birthday" property="user.birthday"></result>
        </resultMap>
        <select id="findAll" resultMap="orderMap">
            select * from shop_orders o,shop_user u where o.uid=u.id
        </select>
    </mapper>

其中<resultMap>还可以配置如下:

   <resultMap id="orderMap" type="com.shuai.domain.Order">
        <result property="id" column="id"></result>
        <result property="ordertime" column="ordertime"></result>
        <result property="total" column="total"></result>
        <association property="user" javaType="com.shuai.domain.User">
            <result column="uid" property="id"></result>
            <result column="username" property="username"></result>
            <result column="password" property="password"></result>
            <result column="birthday" property="birthday"></result>
        </association>
    </resultMap>

4.2.5 测试

   OrderMapper mapper = sqlSession.getMapper(OrderMapper.class);
    List<Order> all = mapper.findAll();
    for(Order order : all){
        System.out.println(order);
    }

4.3 一对多模型操作

4.2.1 模型示例

以用户表和订单表为例,站在用户表的角度看, 一个用户可以拥有多个订单

4.2.2 修改User实体

 //从表
    public class Order {
        private int id;
        private Date ordertime;
        private double total;
    }
    
    //主表-站在谁的角度,谁就是主表
    public class User {    
        private int id;
        private String username;
        private String password;
        private Date birthday;
        
        //在主表中,添加一个从表的集合对象.
        //表示:一个用户拥有多个订单
        private List<Order> orderList;
    }

4.2.3 创建UserMapper接口

public interface UserMapper {
    List<User> findAll();
}

4.2.4 配置UserMapper.xml

<mapper namespace="com.shuai.mapper.UserMapper">
    <resultMap id="userMap" type="com.shuai.domain.User">
        <result column="id" property="id"></result>
        <result column="username" property="username"></result>
        <result column="password" property="password"></result>
        <result column="birthday" property="birthday"></result>
        <collection property="orderList" ofType="com.shuai.domain.Order">
            <result column="oid" property="id"></result>
            <result column="ordertime" property="ordertime"></result>
            <result column="total" property="total"></result>
        </collection>
    </resultMap>
    <select id="findAll" resultMap="userMap">
        select *,o.id oid from shop_user u left join shop_orders o on u.id=o.uid
    </select>
</mapper>

4.2.5 测试结果

UserMapper mapper = sqlSession.getMapper(UserMapper.class);
List<User> all = mapper.findAll();
for(User user : all){
    System.out.println(user.getUsername());
    List<Order> orderList = user.getOrderList();
    for(Order order : orderList){
        System.out.println(order);
    }
    System.out.println("----------------------------------");
}

4.4 多对多模型操作

4.4.1 模型示例

以用户表和角色表为例,站在用户表的角度看, 一个用户可以拥有多个角色. 站在角色表的角度看, 一个角色也可以属于多个用户

4.4.2 实际操作

分别站在用户表的角度和角色表的角度, 各做一个"一对多"关系即可.

三. MyBatis高级

1. 注解开发

1.1 注意事项

  1. MyBatis的注解开发是把映射配置文件替换为注解形式, 核心配置文件该有还要有
  2. 在MyBatis的核心配置文件中, 配置Mapper时
 <mapper class="Mapper接口的全名称"/>
   <package name="Mapper接口所在的包"/>

必须是上述两种中的一种.

1.2 普通SQL

SQL语句直接书写在Mapper接口的方法上即可

public interface StudentMapper {
    //查询全部
    @Select("SELECT * FROM student")
    public abstract List<Student> selectAll();

    //新增操作
    @Insert("INSERT INTO student VALUES (#{id},#{name},#{age})")
    public abstract Integer insert(Student stu);

    //修改操作
    @Update("UPDATE student SET name=#{name},age=#{age} WHERE id=#{id}")
    public abstract Integer update(Student stu);

    //删除操作
    @Delete("DELETE FROM student WHERE id=#{id}")
    public abstract Integer delete(Integer id);
}

1.3 返回主键自增

1.3.1 概述

目的是在添加操作执行完毕后, 把数据库自动增长所生成的主键id, 放回参数的对应属性中.

1.3.2 @Options实现

 //开启生层主键, 并把生成的主键放入stu对象的id属性中
    @Options(useGeneratedKeys = true, keyProperty = "id", keyColumn = "id")
    @Insert("INSERT INTO student VALUES (#{id},#{name},#{age})")
    public abstract Integer insert(Student stu);

1.3.3 @SelectKey实现

@SelectKey(statement = "select LAST_INSERT_ID()", keyProperty = "id",
           before = false, resultType = int.class)
@Insert("INSERT INTO student VALUES (#{id},#{name},#{age})")
public abstract Integer insert(Student stu);

1.4 一对一模式

1.4.1 主表Mapper

   public interface OrderMapper {
        @Select("select * from shop_orders")
        @Results({
                @Result(id=true,property = "id",column = "id"),
                @Result(property = "ordertime",column = "ordertime"),
                @Result(property = "total",column = "total"),
                @Result(property = "user",column = "uid",
                        javaType = User.class,
                        one = @One(select = "com.shuai.mapper.UserMapper.findById"))
        })
        List<Order> findAll();
    }

1.4.2 从表Mapper

public interface UserMapper {
    @Select("select * from shop_user where id=#{id}")
    User findById(int id);    
}

1.5 一对多模式

1.5.1 主表Mapper

  public interface UserMapper {
        @Select("select * from user")
        @Results({
                @Result(id = true,property = "id",column = "id"),
                @Result(property = "username",column = "username"),
                @Result(property = "password",column = "password"),
                @Result(property = "birthday",column = "birthday"),
                @Result(property = "orderList",column = "id",
                        javaType = List.class,
                        many = @Many(select = "com.shuai.mapper.OrderMapper.findByUid"))
        })
        List<User> findAllUserAndOrder();
    }

1.5.2 从表Mapper

public interface OrderMapper {
    @Select("select * from orders where uid=#{uid}")
    List<Order> findByUid(int uid);

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大梦谁先觉i

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值