MyBatis基础入门篇

MyBatis框架

第一章 框架的概述

1.1 什么是框架(framework)

​ 框架:就是一个软件,完成了部分功能。软件中类和类之间的方法调用都已经规定好了。通过这些可以完成某些功能。框架可以看作是模板

1.2 框架解决的问题

​ 1)框架能实现技术的整合。

​ 2)提高开发的效率。降低难度。

1.3 MyBatis框架概述

​ 1)什么是MyBatis?

​ 是一个持久层框架,原名是ibatis,2013年改为MyBatis。MyBatis可以操作数据库,对数据执行增删改查。看作是高级的JDBC,解决JDBC的缺点。

​ 2)MyBatis能做什么?

​ 1)注册驱动。

​ 2)创建jdbc中的Connection、Statement、ResultSet。

​ 3)执行sql语句,得到ResultSet。

​ 4)处理ResultSet,把记录集中的数据转为Java对象,同时还把Java对象放到List集合中。

​ 5)关闭资源。

​ 6)实现sql语句和Java代码的解耦合。

1.4 中文官方文档

​ MyBatis网址:https://mybatis.org/mybatis-3/zh/index.html

​ github地址:https://github.com/mybatis/mybatis-3/releases

第二章 MyBatis入门

2.1 入门案例

​ 实现步骤:

  1. 创建student表(id,name,email,age)

  2. 新建maven项目

  3. 修改pom.xml

    1)加入依赖mybatis,mysql驱动,junit

    2)在<build>加入资源插件.

  4. 创建实体类Student,定义属性,属性名和列名保持一致.

  5. 创建Dao接口,定义操作数据库的方法。

  6. 创建xml文件(mapper文件),写sql语句.

    1. mybatis框架推荐是把sql语句和Java代码分开.

    2. mapper文件:定义和dao接口在同一目录,一个表对应一个mapper文件

  7. 创建mybais的主配置文件(xml文件)

    1. 定义创建连接实力的数据源(DataSource)对象

    2. 指定其他的mapper文件的位置.

  8. 创建测试的内容

    • 使用main方法,测试myBatis访问数据库。
    • 也可以使用Junit访问数据库。

2.2 概念

  1. 自动提交:当你的sql语句执行完毕后,提交事务。数据库更新操作之间保存数据。

  2. 手动提交事务:在你需要提交事务的位置,执行方法,提交事务或者回滚事务。

2.3 MyBatis的一些重要对象

  1. Resources: mybatis框架的中的对象,一个作用—>读取 主配置信息

    InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
    
  2. SqlSessionFactoryBuilder:负责创建SqlSessionFactory对象

    SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);
    
  3. SqlSessionFactory:重要对象

    1. SqlSessionFactory是重量级对象:创建此对象需要使用更多的资源和时间。在项目中有一个就可以了。

    2. SqlSessionFactory接口:作用是SqlSession的工厂,就是创建SqlSession对象。

    3. DefaultSqlSessionFactory实现类

      public class DefaultSqlSessionFactory implements SqlSessionFactory {}
      
    4. SqlSessionFactory接口中的方法

      • openSession():获取一个默认的SqlSession对象,默认是需要手工提交事务的。

      • openSession(boolean):boolean参数表示是否自动提交事务。

        true:创建一个自动提交事务的SqlSession。

        false:等同于没有参数的openSession。

    5. SqlSession对象:

      • SqlSession对象是通过SqlSessionFactory获取的,SqlSession本身是接口

      • DefaultSqlSession:是它(SqlSessionFactory)的实现类。

        public class DefaultSqlSession implements SqlSession {}
        
      • SqlSession作用是提供了大量的执行sql语句的方法

        • selsectOne:执行sql语句最多得到一行记录,多于1行是错误的。
          selectList:执行sql语句,返回多条数据。
          selectMap:执行sql语句,得到一个Map结果。
          
        • insert:执行插入(insert)语句。
          update:执行的是更新(update)语句。
          delete:执行删除(delete)语句。
          commit:提交事务。
          rollback:回滚事务。
          
          • 注意

            SqlSession对象不是线程安全的,使用的步骤:

            1. 在方法的内部,执行sql语句之前,先获取SqlSession对象
            2. 调用SqlSession的方法,执行sql语句。
            3. 关闭SqlSession对象,执行SqlSession.close()方法。

2.4 使用工具类和模板

  1. ​ 创建模板,mapper文件模板mybatis主配置文件模板

    1. mybatis-mapper文件

      <?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="dao接口的全限定名称">
          <!-- 使用insert,update,delete,select标签写sql-->
      
      </mapper>
      
    2. 主配置文件(mybatis-config.xml

    <?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>
        <!--    设置日志-->
        <settings>
            <setting name="logImpl" value="STDOUT_LOGGING"/>
        </settings>
        <!--配置 mybatis 环境-->
        <environments default="mysql">
            <!--id:数据源的名称-->
            <environment id="mysql">
                <!--配置事务类型:使用 JDBC 事务(使用 Connection 的提交和回
               滚)-->
                <transactionManager type="JDBC"/>
                <!--数据源 dataSource:创建数据库 Connection 对象
                type: POOLED 使用数据库的连接池
                -->
                <dataSource type="POOLED">
                    <!--连接数据库的四个要素-->
                    <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                    <!-- 连接数据库的url-->
                    <property name="url"
                              value="jdbc:mysql://localhost:3306/ssm?useUnicode=true&amp;characterEncoding=utf-8"/>
                    <!-- 用户名-->
                    <property name="username" value="root"/>
                    <!-- 密码-->
                    <property name="password" value="020821"/>
                </dataSource>
            </environment>
        </environments>
        <!--    指定其他mapper文件的位置
                找到其他文件中的sql语句。
        -->
        <mappers>
            <!--告诉 mybatis 要执行的 sql 语句的位置,可以有多个mapper文件
                使用mapper的resource属性指定mapper文件的路径
                这个路径是从target/classes路径开始的
                使用注意:
                        1、resource = “mapper文件的路径,使用 / 分割路径”
                        一个mapper resource 指定一个mapper文件
            -->
            <mapper resource="com/dao/StudentDao.xml"/>
        </mappers>
    </configuration>
    
  2. 工具类MyBatisUtil

    public class MyBatisUtil {
        private static SqlSessionFactory factory = null;
    
        static {
            String config = "mybatis-config.xml";
            try {
                InputStream inputStream = Resources.getResourceAsStream(config);
                factory = new SqlSessionFactoryBuilder().build(inputStream);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
        public static SqlSession getSqlSession() {
            SqlSession session = null;
            if (factory != null) {
                session = factory.openSession();
            }
            return session;
        }
    }
    

第三章 dao代理

  1. mybatis提供代理:mybatis创建Dao接口的实现类对象,完成对sql语句的执行。
  2. mybatis创建一个对象代替你的Dao实现类的功能
  3. mybatis使用mybatis代理要求:
    1. mapper文件中的namespace一定是dao接口的全限定名称
    2. mapper文件中标签的id是dao接口方法的名称

3.1 MyBatis代理实现方式

​ 使用SqlSession对象的方法getMapper(dao.class)

​ 例如:现在有StudentDao接口

        SqlSession session = MyBatisUtil.getSqlSession();
        StudentDao dao = session.getMapper(StudentDao.class);
//        等同于普通的  StudentDao student = new StudentImpl();        
        List<Student> studentList = dao.selectStudents();
        System.out.println(studentList);
3.1.1 理解参数

理解参数是:通过Java程序把数据传入到mapper文件中的sql语句。参数主要是指dao接口方法的形参。

3.1.2 parameterType

parameterType:表示参数的类型,指定dao方法的形参数据类型。这个形参的数据类型是给mybatis使用。

mybatis在给sql语句的参数赋值时使用。PreparedStatement.setXXX(位置,值)

第一个用法:java类型的全限定类型名称:parameterType = "java.lang.Integer"   
第二个用法:mybatis定义的Java类型的别名:parameterType = "int"
parameterType:mybatis通过反射机制可以获取 dao接口方法参数的类型,可以不写。

<select id="selectStudentById" parameterType="int" resultType="com.domain.Student">
        select id, name, email, age
        from student
        where id = #{studentId};
</select>
3.1.2.1 dao接口方法是一个简单类型的参数(****)
//dao接口的方法形参是一个简单类型的
//简单类型:Java基本数据类型和String
Student selectStudentByEmail(String email);
//也可以利用注解方式
Student selectStudentByEmail(@Param("studentEmail") String email);
<!-- 
	dao接口是一个简单数据类型的参数
	mapper文件,获取这个参数值,使用#{任意字符}	 
-->    
<select id="selectStudentByEmail"resultType="com.domain.Student">
        select id, name, email, age
        from student
        where email = #{studentEmail};
    </select>
3.1.2.3 dao接口方法有多个简单类型的参数(****)

@Param:命名参数,在方法的形参前面使用的,定义参数名。这个名称可以用在mapper文件中。

dao接口,方法的定义。

StudentDao.java

    /**
     * 根据学生姓名和年龄查找
     *
     * @param name
     * @param age
     * @return 返回Student对象
     * @description: 多个简单类型的参数
     * 使用@Param命名参数,注解是mybatis提供的
     * 位置:在形参定义的前面
     * 属性:value 自定义的参数名称
     */
    Student selectStudentByNameAndAge(@Param(value = "studentName") String name,
                                      @Param(value = "studentAge") Integer age);
}

mapper.xml

<!--
    多个简单类型的参数,
    当使用了@Param命名后,例如@Param("studentName")
    在mapper文件中,使用#{命名的参数}   例如:#{"studentName"}
-->
    <select id="selectStudentByNameAndAge" resultType="com.domain.Student">
        select id,name,email,age 
        from student
        where name = #{studentName} and age = #{studentAge};
    </select>
3.1.2.4 dao接口方法使用一个对象作为参数(****)

方法的形参是一个Java对象。这个对象表示多个参数。

java对象

public class Student {
    private Integer id;
    private String name;
    private String email;
    private Integer age;
    
    //set|get方法
}
public class Param{
	private Object p1;
    private Object p2;
    
    //set|get方法
}

dao接口中的方法定义

    /**
     * 将参数封装到对象中进行传递。
     *
     * @param student
     * @return 返回一个List集合
     */
    List<Student> selectByObject(Student student);
    
    List<Student> selectByParam(Param param);

mapper文件

<!--    一个java对象作为方法的参数,使用对象的属性作为参数值使用
            简单的语法:#{属性名},mybatis调用此属性的getXXX()方法获取属性值
    -->
<select id="selectByObject" resultType="com.domain.Student">
        select id, name, email, age
        from student
        where name = #{name}
           or age = #{age};
</select>

<select id="selectByParam" resultType="com.domain.Student">
        select id, name, email, age
        from student
        where name = #{p1}
           or age = #{p2};
</select>

还可以这样写

<select id="selectByObject" resultType="com.domain.Student">
        select id, name, email, age
        from student
        where name = #{name,javaType=java.lang.String,javaType=VARCHAR}
           or age = #{age,javaType=java.lang.INTEGER,jdbcType=INTEGER};
</select>
3.1.2.5 dao接口中多个简单数据类型的参数,按照参数使用位置

​ 参数位置:dao接口中方法的形参列表,从左往右,参数位置是0,1,2…

语法格式#{arg0},#{arg1}

注意:语法格式中的arg不能是其他的参数名,只能是arg0,arg1,arg2…

​ dao接口的方法

    /**
     * 按照位置来传递参数
     *
     * @param name
     * @param age
     * @return
     */
    List<Student> selectByPosition(String name, Integer age);

mapper文件

    <!--
		这种传参方法是在MyBatis 3.5.1及以上才行。
        使用位置来获取参数值,dao接口方法是多个简单类型的参数
        语法:#{arg0},#{arg1}...
    -->
<select id="selectByPosition" resultType="com.domain.Student">
        select id, name, email, age
        from student
        where name = #{arg0}
          or age = #{arg1};
</select>
3.1.2.6 dao接口参数是一个Map

dao接口方法

    /**
     * 通过map传参
     *
     * @param map
     * @return
     */
    List<Student> selectByMap(Map<String, Object> map);

mapper文件

    <!--
        使用Map传递参数
        在mapper文件中,获取map的值,是通过key获取的,语法是:#{key}
    -->
<select id="selectByMap" resultType="com.domain.Student">
        select id, name, email, age
        from student
        where name = #{myName}
           or age = #{age};
</select>

具体实现

    @Test
    public void selectByMap() {
        SqlSession session = MyBatisUtil.getSqlSession();
        StudentDao dao = session.getMapper(StudentDao.class);
        Map<String, Object> map = new HashMap<>();
        map.put("myName","邓进");
        map.put("age",20);
        List<Student> studentList = dao.selectByMap(map);
        studentList.forEach(stu -> System.out.println("stu = " + stu));
    }

3.2 # 和 $ 的区别

3.2.1 #{}占位符

语法:#{字符}

mybatis处理#{}使用jdbc对象是PreparedStatement对象

<select id="selectStudentById" parameterType="int" 
        resultType="com.domain.Student">
        select id, name, email, age
        from student
        where id = #{studentId};
</select>

mybatis创建PreparedStatement对象,执行sql语句
String sql = "select id, name, email, age from student where id = ? ";
PreparedStatement ps = conn.preparedStatment(sql);
ps.setInt(1,1002);//传递参数
ResultSet rs = ps.executeQuery();//执行sql语句

#{}占位符的特点

​ 1)使用PreparedStatement对象,执行sql语句,效率高

​ 2)使用PreparedStatement对象,避免sql注入语句, sql语句执行更安全

​ 3)#{}占位符常常作为列值使用的,位于等号的右侧。#{}位置的值和数据类型有关的。

3.2.2 ${}占位符

语法:${字符}

mybatis执行${}占位符的sql语句

<select id="selectStudentById" parameterType="int" 
        resultType="com.domain.Student">
        select id, name, email, age
        from student
        where id = ${studentId};
</select>

${}表示字符串连接,把sql语句的其他内容和${}内容使用字符串(+)连接的方式连在一起
String sql = "select id, name, email, age from student where id = " + "1001";

mybatis创建Statement对象,执行sql语句。
Statement stmt = conn.createStatement(sql);
ResultSet rs = stmt.executeQuery();

${}的特点:

1)使用Statement对象,执行sql语句,效率低

2)${}占位符的值,使用的是字符串拼接的方式,有sql注入的风险。有代码安全问题

3)${} 数据是原样使用的,不会区分数据类型

4)${} 常用作表名或列名,在能保证数据安全的情况下使用${}。

3.3 封装MyBatis输出结果

​ 封装输出结果:MyBatis执行sql语句,得到ResultSet,转为Java对象。

3.3.1 resultType

resultType:执行sql得到ResultSet转换类型,作为<select>标签的属性出现的。使用类型的完全限定名或别名,注意如果返回的是集合,那应该设置为集合包含的类型,而不是集合本身,resultSet 和 resultMap,不能同时使用

​ 1)Java类型的全限定名称

接口方法
Student selectById(Integer id);

<select id="selectStudentByNameAndAge" resultType="com.domain.Student">
        select id, name, email, age
        from student
        where name = #{studentName}
          and age = #{studentAge};
</select>

resultType:现在使用Java类型的全限定名称。表示的意思是MyBatis执行sql,把ResultType中的数据转为Student类型的对象。mybatis会做以下操作:
	1、调用com.domain.Student 的无参数构造方法,创建对象。
		Student student = new Student();//使用反射机制创建对象。
	2、同名的列赋值给同名的属性。
		student.setId(rs.getInt("id"));
		student.setName(rs.getString("name"));
	3、得到Java对象,如果dao接口返回的是List集合,mybatis把student对象放入到List集合中。

所以执行 Student stu = dao.selectById(1002);//得到数据库中 id = 1002这行数据。
这列数据的值,赋给了stu 对象的属性,你能得到stu对象。就相当于是 id = 1002这行数据。
3.3.2 resultType表示Map结构

​ dao接口:

    @MapKey("id")
    Map<Object, Object> selectMap(@Param("stuId") Integer id);

​ mapper文件:

<select id="selectMap" resultType="java.util.HashMap">
        select id ,name,email,age from student where id=#{stuId};
</select>

测试类:

    @Test
    public void selectMap(){
        SqlSession sqlSession = MyBatisUtil.getSqlSession();
        StudentDao dao = sqlSession.getMapper(StudentDao.class);
        Map<Object, Object> map = dao.selectMap(1002);
        System.out.println(map);
3.3.3 resultMap标签

​ resultMap:结果映射。自定义列名和Java对象属性的对应关系。常用在列名和属性名不同的情况下。

​ 用法:

​ 1、先定义resultMap标签,指定列名和属性名称的对应关系。

​ 2、在select标签使用resultMap属性,指定上面定义的resultMap的id值。

<!-- 定义resultMap
	id:给resultMap的映射关系起个名称,唯一值。
	type:java类型的全限定名称。
	column:表示数据库中的字段。
	property:表示Java对象里面的属性。
-->

	<resultMap id="universityMap" type="com.domain.University">
        <!--        定义列名和属性名的对应-->
        <!--        主键类型使用id标签-->
        <id column="id" property="rank"/>
        <!--        非主键类型使用result标签-->
        <result column="university_name" property="university_name"/>
        <!--        列名和属性名相同则可以不同定义-->
    </resultMap>
<!--
    使用resultMap属性,指定映射关系的id
    resultMap和resultType,不能同时使用,二选一
-->
    <select id="selectUniversityMap" resultMap="universityMap">
        select u.id, u.university_name, u.province, u.type, u.total_score
        from university as u
                 join province as p on u.province = p.city
        where p.province_id = #{province_id};
    </select>

3.4 全限定名称-自定义别名

mybatis提供的对Java类型定义的简称,好记名称。

自定义别名的步骤:

​ 1)在mybatis主配置文件,使用typeAliases标签声明别名

​ 2)在mapper文件中,resultType=“定义好的别名”

声明别名(主配置文件)

<!--    声明别名-->
    <typeAliases>
<!--
    第一种语法格式:
    type:java类型的全限定名称(自定义类型)
    alias:自定义别名
	优点:别名可以自定义。
	缺点:每个类型必须单独定义。
-->
        <typeAlias type="com.domain.Student" alias="stu"></typeAlias>
    </typeAliases>

<!--
	第二种方式:
		name:包名,mybatis会把这个包中所有类的类名作为别名(不区分大小写)
		优点:使用方便,一次给多个类定义别名。
		缺点:别名不能自定义,必须是类名。
-->
        <package name="com.domain"/>

mapper文件中使用

<!--第二种方式-->
resultType = "别名";
<select id="selectStudents" resultType="stu">
        select id, name, email, age
        from student;
</select>

<!--第二种方式-->
<select id="selectStudents" resultType="student">
        select id, name, email, age
        from student;
</select>

3.5 列名和java对象属性名称不一样解决方式

​ 1)使用resultMap:自定义列名和属性名称对应关系。

​ 2)使用resultType:使用列别名,让别名和jav a对象属性名称一样

​ 例如:id在Java对象中没有,而是用属性rank表示id,通过给id取别名rank,来赋值。

<select id="selectUniversity" resultType="com.domain.University">
        select u.id as rank, u.university_name, u.province, u.type, u.total_score
        from university as u
                 join province as p on u.province = p.city
        where p.province_id = #{province_id};
</select>

3.6 like 模糊查询

第一种方式:在Java程序中,把like的内容组装好。把这个内容传入到sql语句中。

​ dao接口

    List<University> selectLike(@Param("name") String name);

mapper文件

    <select id="selectLike" resultType="com.domain.University">
        select id as rank, university_name, province, type, total_score
        from university
        where university_name like #{name};
    </select>

测试执行like

    @Test
    public void selectLike() {
        SqlSession sqlSession = MyBatisUtil.getSqlSession();
        ProvinceDao dao = sqlSession.getMapper(ProvinceDao.class);
        String name = "%北京%";
        List<University> universityList = dao.selectLike(name);
        System.out.println(universityList);
    }

第二种方式:在sql语句,组织like的内容。

​ sql语句中like的格式:where name like “%“空格#{name}空格”%”

dao接口:

    List<University> selectLike02(@Param("LikeName") String name);

mapper文件

    <select id="selectLike02" resultType="com.domain.University">
        select id as rank, university_name, province, type, total_score
        from university
        where university_name like "%" #{LikeName} "%";
    </select>

测试执行

    @Test
    public void selectLike02() {
        SqlSession sqlSession = MyBatisUtil.getSqlSession();
        ProvinceDao dao = sqlSession.getMapper(ProvinceDao.class);
        String name = "北京";
        List<University> universityList = dao.selectLike02(name);
        System.out.println(universityList);
    }

第四章 动态sql

什么是动态sql:同一个dao方法,根据不同的条件可以表示不同的sql语句,主要是where部分有变化。

使用mybatis提供的标签,实现动态sql的能力,主要讲if,where,foreach,sql

使用动态sql的时候,dao方法的形参使用Java对象。

4.1 if 标签

语法:

<if test = "boolean判断结果">
	sql的代码片段
</if>

<select id = "selectStudent" resultType = "com.domain.Student">
	select * from student
    where id = -1
    <if test = "name!=null or name = ''">
    	or name = #{name}
    </if>
    <if test="age>0">
    	or age &gt; #{age}
    </if>
</select>
4.2 where 标签

使用if标签时,容易引起sql语句语法错误。使用where标签解决if产生的语法问题

使用时where,里面是一个或多个if标签,当有一个if标签 判断条件为true,where标签会转为WHERE关键字附加sql语句的后面,如果if没有一个条件为true,则忽略where和里面的if。

where 标签删除和他最近的 or 或者 and.

语法:
<where>
	<if test = "条件1">sql语句1</if>
    <if test = "条件2">sql语句2</if>
</where>

mapper文件

<!--    where -->
    <select id="selectWhere" resultType="com.domain.Student">
        select *
        from student
        <where>
            <if test="name != null and name != '' ">
                or name = #{name}
            </if>
            <if test="age>0">
                or age &gt; #{age}
            </if>
        </where>
    </select>

测试执行

    @Test
    public void selectWhere() {
        SqlSession sqlSession = MyBatisUtil.getSqlSession();
        StudentDao dao = sqlSession.getMapper(StudentDao.class);
        List<Student> studentList = dao.selectWhere(new Student(1002, null, "dj@qq.com", 20));
        studentList.forEach(stu -> System.out.println("stu = " + stu));

    }
4.3 foreach循环标签

使用foreach可以循环数组,list集合,一般使用在in语句中。

语法:

<foreach collection="集合类型" open="开始的字符" close="结束的字符" 
 item="集合中的成员" separator="集合成员之间的分隔符"> 
		 #{item 的值}
</foreach>

标签属性:
collection:表示循环的对象是数组,还是list集合。如果dao接口方法的形参是 数组,
collection = “array”,如果dao接口形参是List,collection = “list”
open:循环开始时的字符。sql.append("(");

close:循环结束时的字符。slq.append(")");

item:集合成员,自定义变量。 Integer item = idList.get(i);//item是集合成员

separator:集合成员之间的分隔符。sql.append(",");//集合成员之间的分隔符

#{item 的值}获取集合成员的

4.3.1 遍历List<简单类型>
    <!--    foreach-->
    <select id="selectFor" resultType="com.domain.Student">
        select *
        from student
        <!-- 防止list为空或长度为0 -->
        <if test="list != null and list.size()!=0">
            where id in
            <foreach collection="list" open="(" close=")" separator="," item="myId">
                ${myId}
            </foreach>
        </if>
    </select>

测试执行

    @Test
    public void selectFor() {
        SqlSession sqlSession = MyBatisUtil.getSqlSession();
        StudentDao dao = sqlSession.getMapper(StudentDao.class);
        List<Integer> list = new ArrayList<Integer>();
        list.add(1002);
        list.add(1003);
        list.add(1004);
        List<Student> studentList = dao.selectFor(list);
        studentList.forEach(stu -> System.out.println("stu = " + stu));
    }
4.3.2 遍历List<java对象>

dao接口方法

    List<Student> selectFor02(List<Student> studentList);

​ mapper文件

    <select id="selectFor02" resultType="com.domain.Student">
        select *
        from student
        <if test="list !=null and list.size()!=0">
            where id in
            <foreach collection="list" open="(" close=")" separator="," item="stu">
                #{stu.id}
            </foreach>
        </if>
    </select>

测试执行

    @Test
    public void selectFor02() {
        SqlSession sqlSession = MyBatisUtil.getSqlSession();
        StudentDao dao = sqlSession.getMapper(StudentDao.class);
        List<Student> list = new ArrayList<Student>();
        list.add(new Student(1002,"","",20));
        list.add(new Student(1005,"","",20));
        list.add(new Student(1007,"","",20));
        List<Student> studentList = dao.selectFor02(list);
        studentList.forEach(stu -> System.out.println("stu = " + stu));
    }
4.4 sql标签

​ sql标签标识一段sql代码,可以是表名几个字段where条件都可以,可以在其他地方复用sql标签的内容。

使用方式:

1)在mapper文件中定义 sql代码片段<sql id = "唯一字符串">部分sql语句</sql>
2)在其他的位置,使用include标签引用某个代码片段。
类似于Javaweb中的静态包含include

例如:

    <sql id="selectStudent">
        select
        <include refid="tagName"/>
        from student
    </sql>
    <sql id="tagName">
        id
        ,name,email,age
    </sql>
<!-- 外部引用 -->
<select id="selectIf" resultType="com.domain.Student">
        select
        <include refid="tagName"/>
        from student
        where id = -1
        <if test="name!=null and name = ''">
            or name = #{name}
        </if>
        <if test="age>0">
            or age &gt; #{age}
        </if>
</select>

第五章 MyBatis配置文件

​ mybatis配置文件两大类:1)mybatis主配置文件。2)mybatis的mapper文件

​ 1、mybatis主配置文件,提供mybatis全局设置的。包含的内容:日志、数据源、mapper文件的位置。

​ 2、mapper文件:写sql语句的。一个表一个mapper文件。

5.1 设置(settings)

settings是mybatis的全局设置,影响整个mybatis的运行。这个设置一般使用默认值就可以了。

<settings>
  <setting name="cacheEnabled" value="true"/>
  <setting name="lazyLoadingEnabled" value="true"/>
  <setting name="multipleResultSetsEnabled" value="true"/>
  <setting name="useColumnLabel" value="true"/>
  <setting name="useGeneratedKeys" value="false"/>
  <setting name="autoMappingBehavior" value="PARTIAL"/>
  <setting name="autoMappingUnknownColumnBehavior" value="WARNING"/>
  <setting name="defaultExecutorType" value="SIMPLE"/>
  <setting name="defaultStatementTimeout" value="25"/>
  <setting name="defaultFetchSize" value="100"/>
  <setting name="safeRowBoundsEnabled" value="false"/>
  <setting name="mapUnderscoreToCamelCase" value="false"/>
  <setting name="localCacheScope" value="SESSION"/>
  <setting name="jdbcTypeForNull" value="OTHER"/>
  <setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString"/>
</settings>

5.2 类型别名(typeAliases)

类型别名可为 Java 类型设置一个缩写名字。 它仅用于 XML 配置,意在降低冗余的全限定类名书写

例如:

在mybatis主配置文件里面

<!-- 第一种方式 -->
<typeAliases>
  <typeAlias alias="Author" type="domain.blog.Author"/>
  <typeAlias alias="Blog" type="domain.blog.Blog"/>
  <typeAlias alias="Comment" type="domain.blog.Comment"/>
  <typeAlias alias="Post" type="domain.blog.Post"/>
  <typeAlias alias="Section" type="domain.blog.Section"/>
  <typeAlias alias="Tag" type="domain.blog.Tag"/>
</typeAliases>

<!-- 第二种方式 -->
<typeAliases>
  <package name="domain.blog"/>
</typeAliases>

5.3 环境配置(environments)

含义:

environments:环境标签,在里面可以配置多个environment

​ 属性:default,必须是某个environment的id属性值。表示mybatis默认连接的数据库

environment:表示一个数据库的连接信息

​ 属性:id 自定义的环境的标识。唯一值。

transactionManager:事务管理器

​ 属性:type 表示事务管理器的类型

​ 属性值:1)JDBC 使用Connection对象,由mybatis自己完成事务的处理。

​ 2)MANAGED:管理,表示把事务的处理交给容器来实现(由其他软件来完成事 务的提交,回滚)

dataSource:数据源,创建的Connection对象,连接数据库。

​ 属性:type 数据源的类型。

​ 属性值:1)POOLED,mybatis会在内存中创建PooledDataSource类管理多个 Connection连接对象,使用的是数据库连接池。

​ 2)UNPOOLED,不使用连接池,mybatis创建UnPooledDataSource这个 类,每次执行sql语句先创建Connection对象,再执行sql语句,最 后关闭Connection。

​ 3)JNDI:java的命名和目录服务。

    <!--配置 mybatis 环境-->
    <environments default="mysql">
        <!--id:数据源的名称-->
        <environment id="mysql">
            <!--配置事务类型:使用 JDBC 事务(使用 Connection 的提交和回
           滚)-->
            <transactionManager type="JDBC"/>
            <!--数据源 dataSource:创建数据库 Connection 对象
            type: POOLED 使用数据库的连接池
            -->
            <dataSource type="POOLED">
                <!--连接数据库的四个要素-->
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <!-- 连接数据库的url-->
                <property name="url"
                          value="jdbc:mysql://localhost:3306/ssm"/>
                <!-- 用户名-->
                <property name="username" value="root"/>
                <!-- 密码-->
                <property name="password" value="020821"/>
            </dataSource>
        </environment>

5.4 属性配置文件(properties)

​ 需要把数据库的配置信息放到一个单独的文件中,独立管理。这个文件扩展名就是properties。在这个文件中,使用自定义的key=value的格式表示数据。

​ 使用步骤:

​ 1)在resource目录中,创建xxx.properties。

​ 2)在文件中,使用key=value的格式定义数据。

​ 例如jdbc.url = jdbc:mysql://localhost:3306/ssm

​ 3)在mybatis主配置文件中,使用<properties>标签引用外部的属性配置文件。

​ 4)在使用的位置,使用${key}获取key对应的value(等号右侧的值)

例子:

jdbc.properties

jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/ssm?useUnicode=true&characterEncoding=utf-8
jdbc.username=root
jdbc.password=020821

mybatis主配置文件

    <!--    使用外部属性配置文件-->
    <properties resource="jdbc.properties"/>

<environments default="mysql">
        <!--id:数据源的名称-->
        <environment id="mysql">
            <!--配置事务类型:使用 JDBC 事务(使用 Connection 的提交和回
           滚)-->
            <transactionManager type="JDBC"/>
            <!--数据源 dataSource:创建数据库 Connection 对象
            type: POOLED 使用数据库的连接池
            -->
            <dataSource type="POOLED">
                <!--连接数据库的四个要素-->
                <property name="driver" value="${jdbc.driver}"/>
                <!-- 连接数据库的url-->
                <property name="url"
                          value="${jdbc.url}"/>
                <!-- 用户名-->
                <property name="username" value="${jdbc.username}"/>
                <!-- 密码-->
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>
</environments>

5.5 映射器(mapper)

​ 使用mapper指定其他mapper文件的位置。

​ mapper标签使用的格式有两个常用的方式:

<mappers>
<!--
        第一种方式 ,resource = "mapper文件的路径"
		优点:文件清晰。加载的文件是明确的。
			文件的位置比较灵活。
		缺点:文件比较多时,代码量比较大,管理难度大。
-->
        <mapper resource="com/dao/studentDao.xml"/>
        <mapper resource="com/dao/UniversityDao.xml"/>

<!--    第二种方式,使用<package>
        name:包名,mapper文件所在的包名。
        特点:把这个包中的所有mapper文件,一次加载。
        使用要求:
                1、mapper文件和dao接口在同一目录。
                2、mapper文件和dao接口名称完全一样。
-->
        <package name="com.dao"/>
		<package name="com.dao"/>
</mappers>

第六章 扩展插件

6.1 分页插件(PageHelper)

​ 网址:GitHub - pagehelper/Mybatis-PageHelper: Mybatis通用分页插件

6.1.1 Maven依赖坐标
<dependency>
 	<groupId>com.github.pagehelper</groupId>
	<artifactId>pagehelper</artifactId>
 	<version>5.1.10</version>
</dependency>
6.1.2 加入plugin配置

​ 在mybatis主配置文件,加入plugin声明。

<environments>之前加入 
<plugins>
 	<plugin interceptor="com.github.pagehelper.PageInterceptor" />
</plugins>
6.1.3 PageHelper对象

查询语句之前调用 PageHelper.startPage(integer pageNum, Integer pageSize) 静态方法。

​ 除了 PageHelper.startPage 方法外,还提供了类似用法的 PageHelper.offsetPage 方法。

​ 在你需要进行分页的 MyBatis 查询方法前调用 PageHelper.startPage 静态方法即可,紧跟 在这个方法后的第一个 MyBatis 查询方法会被进行分页。

PageHelper.startPage(页码,每页大小)

@Test
public void testSelect() throws IOException {
//获取第 1 页,3 条内容
PageHelper.startPage(1,3);
 List<Student> studentList = studentDao.selectStudents();
 studentList.forEach( stu -> System.out.println(stu));
}

​ mapper文件

    <select id="selectAllStudent" resultType="com.domain.Student">
        select *
        from student
        order by id
    </select>

注意

​ 使用分页插件时,在mapper文件中,写完sql语句后不能在末尾加上";",因为分页是在其基础之上加上limit 关键字来实现分页的。否则会发生语法错误!

==>  Preparing: select * from student order by id LIMIT ?, ?

第七章 MyBatis 逆向工程

7.1 概念

​ MyBatis需要程序员自己编写sql语句,mybatis官方提供逆向工程,可以针对****单表****自动生成mybatis执行所需要的代码(mapper.java、mapper.xml、pojo…),可以让程序员将更多的精力放在繁杂的业务逻辑上。

下载逆向工程

​ 链接: https://github.com/mybatis/generator/releases

​ 官方文档:http://mybatis.org/generator/index.html

7.2 Maven主要的依赖,pom.xml
<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com</groupId>
    <artifactId>MyBatisRevese</artifactId>
    <version>1.0-SNAPSHOT</version>

    <name>MyBatisRevese</name>
    <!-- FIXME change it to the project's website -->
    <url>http://www.example.com</url>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.7</maven.compiler.source>
        <maven.compiler.target>1.7</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.7</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.25</version>
        </dependency>

        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>

        <dependency>
            <groupId>org.mybatis.generator</groupId>
            <artifactId>mybatis-generator-core</artifactId>
            <version>1.3.7</version>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.mybatis.generator</groupId>
                <artifactId>mybatis-generator-maven-plugin</artifactId>
                <version>1.3.2</version>
                <!--需要在逆向工程中引入数据库驱动,不然不能创建-->
                <dependencies>
                    <dependency>
                        <groupId>mysql</groupId>
                        <artifactId>mysql-connector-java</artifactId>
                        <version>8.0.27</version>
                    </dependency>
                </dependencies>
                <configuration>
                    <verbose>true</verbose>
                    <overwrite>true</overwrite>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

7.3 主要的配置文件

generatorConfig.xml,放在resource目录下

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
        PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
        "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">

<generatorConfiguration>
    <context id="testTables" targetRuntime="MyBatis3">
        <commentGenerator>
            <!-- 是否去除自动生成的注释 true:是 : false:否 -->
            <property name="suppressAllComments" value="true"/>
        </commentGenerator>
        <!--数据库连接的信息:驱动类、连接地址、用户名、密码 -->
        <jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"
                        connectionURL="jdbc:mysql://localhost:3306/pymysql"
                        userId="root"
                        password="020821">
        </jdbcConnection>
        <!-- 默认false,把JDBC DECIMAL 和 NUMERIC 类型解析为 Integer,为 true时把JDBC DECIMAL 和
            NUMERIC 类型解析为java.math.BigDecimal -->
        <javaTypeResolver>
            <property name="forceBigDecimals" value="false"/>
        </javaTypeResolver>

        <!-- targetProject:生成PO类的位置 我写的是entity实体类-->
        <javaModelGenerator targetPackage="com.domain"
                            targetProject="src/main/java">
            <!-- enableSubPackages:是否让schema作为包的后缀 -->
            <property name="enableSubPackages" value="false"/>
            <!-- 从数据库返回的值被清理前后的空格 -->
            <property name="trimStrings" value="true"/>
        </javaModelGenerator>
        <!-- targetProject:mapper映射文件生成的位置 -->
        <sqlMapGenerator  targetPackage="mapper" targetProject="./src/main/resources">
            <!-- enableSubPackages:是否让schema作为包的后缀 -->
            <property name="enableSubPackages" value="false"/>
        </sqlMapGenerator>
        <!-- targetPackage:mapper接口生成的位置 -->
        <javaClientGenerator type="XMLMAPPER"
                             targetPackage="com.dao"
                             targetProject="src/main/java">
            <!-- enableSubPackages:是否让schema作为包的后缀 -->
            <property name="enableSubPackages" value="false"/>
        </javaClientGenerator>
        <!-- 指定数据库表 -->
        <table schema="" tableName="booksinfo"></table>
        <table schema="" tableName="news"></table>
        <table schema="" tableName="uni"></table>
        <table schema="" tableName="secondhandhousing"></table>
        <table schema="" tableName="test"></table>
<!--        <table schema="" tableName="product_info"></table>-->
<!--        <table schema="" tableName="product_type"></table>-->
    </context>
</generatorConfiguration>

7.4 java代码

Java执行代码

package utils;

import org.mybatis.generator.api.MyBatisGenerator;
import org.mybatis.generator.config.Configuration;
import org.mybatis.generator.config.xml.ConfigurationParser;
import org.mybatis.generator.internal.DefaultShellCallback;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

/**
 * @author DengJin
 * @ClassName GeneratorCore
 * @date 2022-01-14 22:39
 * @Description:
 * @Version:1.0
 */

public class GeneratorCore {
    public void testGenerator() throws Exception {
        List<String> warnings = new ArrayList<>();
        boolean overwrite = true;
        //指定逆向工程配置文件
        File configFile = new File(GeneratorCore.class.getResource("/generatorConfig.xml").getFile());
//        File configFile = new File("E:\\JDBC\\MyBatisRevese\\src\\main\\resources\\generatorConfig.xml");
        ConfigurationParser cp = new ConfigurationParser(warnings);
        Configuration config = cp.parseConfiguration(configFile);
        DefaultShellCallback callback = new DefaultShellCallback(overwrite);
        MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings);
        myBatisGenerator.generate(null);
    }

    public static void main(String[] args) throws Exception {
        GeneratorCore generator = new GeneratorCore();
        generator.testGenerator();
    }
}
7.5 采用Maven方式运行
Command line : mybatis-generator:generate -e

在这里插入图片描述

7.6 log4j日志

log4j.properties

log4j.rootLogger=DEBUG, stdout
# SqlMap logging configuration...
log4j.logger.com.ibatis=DEBUG
log4j.logger.com.ibatis.common.jdbc.SimpleDataSource=DEBUG
log4j.logger.com.ibatis.sqlmap.engine.cache.CacheModel=DEBUG
log4j.logger.com.ibatis.sqlmap.engine.impl.SqlMapClientImpl=DEBUG
log4j.logger.com.ibatis.sqlmap.engine.builder.xml.SqlMapParser=DEBUG
log4j.logger.com.ibatis.common.util.StopWatch=DEBUG
log4j.logger.java.sql.Connection=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG
log4j.logger.java.sql.ResultSet=DEBUG
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n

\src\main\resources\generatorConfig.xml");
ConfigurationParser cp = new ConfigurationParser(warnings);
Configuration config = cp.parseConfiguration(configFile);
DefaultShellCallback callback = new DefaultShellCallback(overwrite);
MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings);
myBatisGenerator.generate(null);
}

public static void main(String[] args) throws Exception {
    GeneratorCore generator = new GeneratorCore();
    generator.testGenerator();
}

}


####  7.5 采用Maven方式运行

```xml-dtd
Command line : mybatis-generator:generate -e

​ [外链图片转存中…(img-tUqj2o0N-1648825757857)]

7.6 log4j日志

log4j.properties

log4j.rootLogger=DEBUG, stdout
# SqlMap logging configuration...
log4j.logger.com.ibatis=DEBUG
log4j.logger.com.ibatis.common.jdbc.SimpleDataSource=DEBUG
log4j.logger.com.ibatis.sqlmap.engine.cache.CacheModel=DEBUG
log4j.logger.com.ibatis.sqlmap.engine.impl.SqlMapClientImpl=DEBUG
log4j.logger.com.ibatis.sqlmap.engine.builder.xml.SqlMapParser=DEBUG
log4j.logger.com.ibatis.common.util.StopWatch=DEBUG
log4j.logger.java.sql.Connection=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG
log4j.logger.java.sql.ResultSet=DEBUG
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
MyBatis是一种持久化框架,可以帮助开发人员管理数据库访问,提供了一种简化SQL语句编写和数据访问的方法。在这里,我将为您提供一个快速入门指南,以帮助您开始使用MyBatis。 1. 环境设置 在开始使用MyBatis之前,您需要在计算机上安装JavaMyBatis。您可以在MyBatis官网上下载MyBatis,并按照步骤进行安装。 2. 创建数据库表 在使用MyBatis之前,您需要创建一个数据库表来存储数据。在这里,我将创建一个名为“用户”的表,其中包含id、姓名和年龄字段。 CREATE TABLE `user` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(50) DEFAULT NULL, `age` int(11) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; 3. 创建POJO类 在使用MyBatis之前,您需要创建一个POJO类来表示数据库表中的数据。在这里,我将创建一个名为“User”的类,并在其中添加id、name和age字段的getter和setter方法。 public class User { private int id; private String name; private int age; // getter and setter methods } 4. 创建Mapper接口和XML文件 在MyBatis中,Mapper是一个接口,它定义了与数据库进行交互的方法。在这里,我将创建一个名为“UserMapper”的接口,并在其中添加一个名为“selectUserById”的方法,该方法将返回具有指定ID的用户。 public interface UserMapper { User selectUserById(int id); } 接下来,我们需要创建一个名为“UserMapper.xml”的XML文件,该文件将包含与Mapper接口中方法对应的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="com.example.mapper.UserMapper"> <select id="selectUserById" parameterType="int" resultType="com.example.pojo.User"> SELECT * FROM user WHERE id = #{id} </select> </mapper> 5. 配置MyBatis 现在,我们需要将MyBatis配置为使用我们创建的Mapper接口和XML文件。我们需要创建一个名为“mybatis-config.xml”的XML文件,并在其中添加以下内容: <?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="development"> <environment id="development"> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <property name="driver" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/mybatis"/> <property name="username" value="root"/> <property name="password" value="password"/> </dataSource> </environment> </environments> <mappers> <mapper resource="com/example/mapper/UserMapper.xml"/> </mappers> </configuration> 在这里,我们为MyBatis配置了一个数据源,该数据源将连接到MySQL数据库,并指定了Mapper文件的位置。 6. 测试MyBatis 现在,我们已经准备好使用MyBatis了。我们可以在Java代码中使用MyBatis来获取具有指定ID的用户。在这里,我将提供一个简单的示例: public class Main { public static void main(String[] args) { SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml")); SqlSession session = sessionFactory.openSession(); UserMapper userMapper = session.getMapper(UserMapper.class); User user = userMapper.selectUserById(1); System.out.println(user.getName()); } } 在这里,我们使用SqlSessionFactoryBuilder类从mybatis-config.xml文件中创建SqlSessionFactory对象。然后,我们打开一个SqlSession对象并获取UserMapper接口的实例。最后,我们调用selectUserById方法并打印用户的名称。 这就是MyBatis的快速入门指南。希望这能帮助您开始使用MyBatis,并为您提供一个更好的方法来管理数据库访问。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

阿姨洗铁路℡

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

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

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

打赏作者

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

抵扣说明:

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

余额充值