Mybatis框架

目录

一、三层架构

二、使用 JDBC 的缺陷

三、快速入门

1、概述

2、解决的主要问题

3、入门案例

添加Maven坐标

加入Maven插件

编写 Student 实体类

编写 Dao 接口 StudentDao

编写 Dao 接口 Mapper 映射文件 StudentDao.xml

创建 MyBatis 主配置文件

创建测试类 MyBatisTest

 配置日志功能

insert 操作

(1)StudentDao 接口中增加方法

(2)StudentDao.xml 加入 sql 语句

(3)增加测试方法

4、MyBatis 对象分析

5、创建工具类

6、MyBatis 使用传统 Dao 开发方式

Dao 开发

传统 Dao 开发方式的分析

四、MyBatis 框架 Dao 代理

1、Dao 代理实现数据库操作

(1)getMapper 获取代理对象

(2)使用 Dao 代理对象方法执行 sql 语句

2、深入理解参数

(1)parameterType

(2)一个简单参数

(3)多个参数-使用@Param

(4)多个参数-使用对象

(5)多个参数-按位置

(6)多个参数-使用 Map

(7)#和$

3、MyBatis 输出结果

(1)resultType

(2)resultMap

(3)实体类属性名和列名不同的处理方式

(4)模糊 like

五、动态 SQL

1、标签

2、

3、

4、代码片段

六、MyBatis 配置文件

1、主配置文件

2、dataSource 标签

3、使用数据库属性配置文件

4、typeAliases(类型别名)

5、mappers(映射器)

七、PageHelper 分页


一、三层架构

(1)、三层架构包含的三层:
  • 界面层(User Interface layer
  • 业务逻辑层(Business Logic Layer)
  • 数据访问层(Data access layer

1. 界面层(表示层,视图层):主要功能是接受用户的数据,显示请求的处理 结果。使用 web 页面和用户交互。

2. 业务逻辑层:接收表示传递过来的数据,检查数据,计算业务逻辑,调用数据访问层获取数据。

3. 数据访问层:与数据库打交道。主要实现对数据的增、删、改、查。将存储 在数据库中的数据提交给业务层,同时将业务层处理的数据保存到数据库

 (2)、三层架构的优点

  1. 结构清晰、耦合度低, 各层分工明确
  2. 可维护性高,可扩展性高
  3. 有利于标准化
  4. 开发人员可以只关注整个结构中的其中某一层的功能实现
  5. 有利于各层逻辑的复用

二、使用 JDBC 的缺陷

public void findStudent() {
        Connection conn = null;
        Statement stmt = null;
        ResultSet rs = null;
        try {
            //注册 mysql 驱动
            Class.forName("com.mysql.jdbc.Driver");
            //连接数据的基本信息 url ,username,password
            String url = "jdbc:mysql://localhost:3306/springdb";
            String username = "root";
            String password = "123456";
            //创建连接对象
            conn = DriverManager.getConnection(url, username, password);
            //保存查询结果
            List stuList = new ArrayList<>();
            //创建 Statement, 用来执行 sql 语句
            stmt = conn.createStatement();
            //执行查询,创建记录集,
            rs = stmt.executeQuery("select * from student");
            while (rs.next()) {
                Student stu = new Student();
                stu.setId(rs.getInt("id"));
                stu.setName(rs.getString("name"));
                stu.setAge(rs.getInt("age"));
                //从数据库取出数据转为 Student 对象,封装到 List 集合
                stuList.add(stu);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                //关闭资源
                if (rs != null) ;
                {
                    rs.close();
                }
                if (stmt != null) {
                    stmt.close();
                }
                if (conn != null) {
                    conn.close();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
1. 代码比较多,开发效率低
2. 需要关注 Connection ,Statement, ResultSet 对象创建和销毁
3. 对 ResultSet 查询的结果,需要自己封装为 List
4. 重复的代码比较多些
5. 业务代码和数据库的操作混在一起

三、快速入门

1、概述

MyBatis 本是 apache 的一个开源项目 iBatis, 2010 年这个项目由 apache software foundation 迁移到了 google code,并且改名为 MyBatis 。2013 年 11 月迁移到 Github

2、解决的主要问题

  • 减轻使用 JDBC 的复杂性,不用编写重复的创建 Connetion , Statement ;不用编写关闭资源代码。
  • 直接使用 java 对象,表示结果数据。让开发者专注 SQL 的处理。

3、入门案例

添加Maven坐标

    
        
            junit
            junit
            4.11
            test
        
        
            org.mybatis
            mybatis
            3.5.1
        
        
            mysql
            mysql-connector-java
            5.1.9
        
    

加入Maven插件


        
            
                src/main/java
                
                    **/*.properties
                    **/*.xml
                
                false
            
        
        
            
                maven-compiler-plugin
                3.1
                
                    1.8
                    1.8
                
            
        
    

编写 Student 实体类

package com.hk.domain;
public class Student {
    //属性名和列名一样 
    private Integer id;
    private String name;
    private String email;
    private Integer age;
    // set ,get , toString
}

编写 Dao 接口 StudentDao

package com.hk.dao;
import com.hk.domain.Student;
import java.util.List;

public interface StudentDao {
 /*查询所有数据*/ 
 List selectStudents();
}

编写 Dao 接口 Mapper 映射文件 StudentDao.xml

  • 在 dao 包中创建文件 StudentDao.xml
  • 要 StudentDao.xml 文件名称和接口 StudentDao 一样,区分大小写的一样。

 
 

  
 

创建 MyBatis 主配置文件

项目 src/main 下创建 resources 目录,创建主配置文件:名称为 mybatis.xml

 

      
     
          
         
              
             
              
             
                  
                 
                 
                 
                 
             
         
     
     
          
         
     

创建测试类 MyBatisTest

@Test
public void testStart() throws IOException {
 //1.mybatis 主配置文件 
 String config = "mybatis-config.xml";
 //2.读取配置文件 
 InputStream in = Resources.getResourceAsStream(config);
 //3.创建 SqlSessionFactory 对象,目的是获取 SqlSession 
 SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
 //4.获取 SqlSession,SqlSession 能执行 sql 语句 
 SqlSession session = factory.openSession();
 //5.执行 SqlSession 的 selectList() 
 List studentList = session.selectList("com.hk.dao.StudentDao.selectStudents");
 //6.循环输出查询结果 
 studentList.forEach( student -> System.out.println(student));
 //7.关闭 SqlSession,释放资源 
 session.close();
}
List studentList = session.selectList("com.hk.dao.StudentDao.selectStudents");
近似等价的 jdbc 代码
Connection conn = 获取连接对象
String sql=” select id,name,email,age from student”
PreparedStatement ps = conn.prepareStatement(sql);
ResultSet rs = ps.executeQuery();

 配置日志功能

mybatis.xml 文件加入日志配置,可以在控制台输出执行的 sql 语句和参数

 

insert 操作

(1)StudentDao 接口中增加方法
       
 int insertStudent(Student student);
(2)StudentDao.xml 加入 sql 语句

    insert into student(id,name,email,age) values(#{id},#{name},#{email},#{age})
(3)增加测试方法
@Test
public void testInsert() throws IOException {
 //1.mybatis 主配置文件 
 String config = "mybatis-config.xml";
 //2.读取配置文件 
 InputStream in = Resources.getResourceAsStream(config);
 //3.创建 SqlSessionFactory 对象 
 SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
 //4.获取 SqlSession 
 SqlSession session = factory.openSession();
 //5.创建保存数据的对象 
 Student student = new Student();
 student.setId(1005);
 student.setName("张丽");
 student.setEmail("[email protected]");
 student.setAge(20);
 //6.执行插入 insert 
 int rows = session.insert("com.hk.dao.StudentDao.insertStudent",student);
 //7.提交事务 
 session.commit();
 System.out.println("增加记录的行数:"+rows);
 //8.关闭 SqlSession 
 session.close();
 
}

4、MyBatis 对象分析

(1) Resources 类
        Resources 类,用于读取资源文件。其有很多方法通 过加载并解析资源文件,返回不同类型的 IO 流对象。
(2) SqlSessionFactoryBuilder 类
         SqlSessionFactory 的创建,需要使用 SqlSessionFactoryBuilder 对象的 build()方法。由于 SqlSessionFactoryBuilder 对象在创建完工厂对象后,就完 成了其历史使命,即可被销毁。所以,一般会将该 SqlSessionFactoryBuilder 对象创建为一个方法内的局部对象,方法结束,对象销毁。
(3)SqlSessionFactory 接口
        SqlSessionFactory 接口对象是一个重量级对象(系统开销大的对象),是线程安全的,所以一个应用只需要一个该对象即可。创建 SqlSession 需要使用SqlSessionFactory 接口的 openSession()方法。
  • openSession(true):创建一个有自动提交功能的 SqlSession
  • openSession(false):创建一个非自动提交功能的 SqlSession,需手动提交
  • openSession():同 openSession(false)
(4) SqlSession 接口
        SqlSession 接口对象用于执行持久化操作。一个 SqlSession 对应着一次数据库会话,一次会话以 SqlSession 对象的创建开始,以 SqlSession 对象的 关闭结束。
        SqlSession 接口对象是线程不安全的,所以每次数据库会话结束前,需要马上调用其 close()方法,将其关闭。再次需要会话,再次创建。 SqlSession在方法内部创建,使用完毕后关闭。

5、创建工具类

(1) 创建 MyBatisUtil 类
package com.hk.common;

public class MyBatisUtil {
 //定义 SqlSessionFactory 
 private static SqlSessionFactory factory = null;
 static {
     //使用 静态块 创建一次 SqlSessionFactory 
     try{
         String config = "mybatis-config.xml";
        //读取配置文件 
         InputStream in = Resources.getResourceAsStream(config);
         //创建 SqlSessionFactory 对象 
         factory = new SqlSessionFactoryBuilder().build(in);
     }catch (Exception e){
         factory = null;
         e.printStackTrace();
     }
 }
 /* 获取 SqlSession 对象 */ 
 public static SqlSession getSqlSession(){
     SqlSession session = null;
     if( factory != null){
         session = factory.openSession();
     }
     return session;
 }
}
(2)使用 MyBatisUtil 类
@Test
public void testUtils() throws IOException {
 SqlSession session = MyBatisUtil.getSqlSession();
 List studentList = session.selectList("com.hk.dao.StudentDao.selectStudents");
 studentList.forEach( student -> System.out.println(student));
 session.close();
}

6、MyBatis 使用传统 Dao 开发方式

        使用 Dao 的实现类,操作数据库

Dao 开发

(1) 创建 Dao 接口实现类
public class StudentDaoImpl implements StudentDao

(2)实现接口中 select 方法

public List selectStudents() {

    SqlSession session = MyBatisUtil.getSqlSession();

    List studentList = session.selectList("com.hk.dao.StudentDao.selectStudents");

    session.close();
    
    return studentList;
}

测试查询操作

@Test
public void testSelect() throws IOException {
    StudentDao studentDao = new StudentDaoImpl();
    final List studentList = studentDao.selectStudents();
    studentList.forEach( stu -> System.out.println(stu));
}
(3) 实现接口中 insert 方法
public int insertStudent(Student student) {

    SqlSession session = MyBatisUtil.getSqlSession();

    int nums = session.insert("com.hk.dao.StudentDao.insertStudent",student);

    session.commit();

    session.close();

    return nums;
}

测试 insert

@Test
public void testInsert() throws IOException {

    Student student = new Student();

    student.setId(1006);

    student.setName("林浩");

    student.setEmail("[email protected]");

    student.setAge(26);

    int nums = studentDao.insertStudent(student);

    System.out.println("使用 Dao 添加数据:"+nums);
}

传统 Dao 开发方式的分析

在前面例子中自定义 Dao 接口实现类时发现一个问题:
Dao 的实现类其实并没有干什么实质性的工作,它仅仅就是通过 SqlSession 的相关 API 定位到
映射文件 mapper 中相应 id 的 SQL 语句,真正对 DB 进行操作的工作其实是由框架通过 mapper 中的 SQL 完成的。所以,MyBatis 框架就抛开了 Dao 的实现类,直接定位到映射文件 mapper 中的相应 SQL 语句,对 DB 进行操作。这种对 Dao 的实现方式称为Mapper 的动态代理方式。Mapper 动态代理方式无需程序员实现 Dao 接口。接口是由 MyBatis 结合映射文件自动生成的动态代理实现的。

四、MyBatis 框架 Dao 代理

1、Dao 代理实现数据库操作

        删除dao的实现类

(1)getMapper 获取代理对象

        只需调用 SqlSession 的 getMapper()方法,即可获取指定接口的实现类对象。该方法的参数为指定 Dao 接口类的 class 值。
StudentDao studentDao = MyBatisUtil.getSqlSession().getMapper(StudentDao.class);
// getMapper()创建的对象,是代替我们自己创建的 StudentDaoImpl 类

(2)使用 Dao 代理对象方法执行 sql 语句

select 方法:
@Test
public void testSelect() throws IOException {

    final List studentList = studentDao.selectStudents();

    studentList.forEach( stu -> System.out.println(stu));
}

insert 方法:

@Test
public void testInsert() throws IOException {

    Student student = new Student();

    student.setId(1006);

    student.setName("林浩");

    student.setEmail("[email protected]");

    student.setAge(26);

    int nums = studentDao.insertStudent(student);
    
    System.out.println("使用 Dao 添加数据:"+nums);
}

2、深入理解参数

        从 java 代码中把参数传递到 mapper.xml 文件。

(1)parameterType

        parameterType: 接口中方法参数的类型, 类型的完全限定名或别名。这个属性是可选的,因为 MyBatis 可以推断出具体传入语句的参数,默认值为未设置( unset)。

 delete from student where id=#{studentId}

等同于

 delete from student where id=#{studentId}

(2)一个简单参数

Dao 接口中方法的参数只有一个简单类型(java 基本类型和 String),占位符 #{ 任意字符 } ,和方法的参数名无关。
接口方法:
Student selectById(int id);

mapper 文件:

#{studentId} , studentId 是自定义的变量名称,和方法参数名无关。

测试方法:
@Test
public void testSelectById(){
    //一个参数
    Student student = studentDao.selectById(1005);
    System.out.println("查询 id 是 1005 的学生:"+student);
}

(3)多个参数-使用@Param

当 Dao 接口方法多个参数,需要通过名称使用参数。 在方法形参前面加入@Param(“自定义参数名”),mapper 文件使用#{自定义参数名}。
接口方法:
List selectMultiParam(@Param("personName") String name,@Param("personAge") int age);

mapper 文件:

测试方法:

@Test
public void testSelectMultiParam(){
    List stuList = studentDao.selectMultiParam("李力",20);
    stuList.forEach( stu -> System.out.println(stu));
}

(4)多个参数-使用对象

        使用 java 对象传递参数, java 的属性值就是 sql 需要的参数值。 每一个属性就是一个参数。
语法格式: #{ property,javaType=java 中数据类型名,jdbcType=数据类型名称 } javaType, jdbcType 的类型 MyBatis 可以检测出来,一般不需要设置。常用格式 #{ property }
创建保存参数值的对象 QueryParam
package com.hk.vo;
public class QueryParam {

    private String queryName;

    private int queryAge;

    //set ,get 方法
}

接口方法:

List selectMultiObject(QueryParam queryParam);

mapper 文件:

测试方法:

@Test
public void selectMultiObject(){
 QueryParam qp = new QueryParam();
 qp.setQueryName("李力");
 qp.setQueryAge(20);
 List stuList = studentDao.selectMultiObject(qp);
 stuList.forEach( stu -> System.out.println(stu));
}

(5)多个参数-按位置

参数位置从 0 开始, 引用参数语法 #{ arg 位置 } , 第一个参数是#{arg0}, 第二个是#{arg1}
接口方法:
List selectByNameAndAge(String name,int age);

mapper 文件

测试方法:

@Test
public void testSelectByNameAndAge(){

    //按位置参数
    List stuList = studentDao.selectByNameAndAge("李力",20);
    stuList.forEach( stu -> System.out.println(stu));
}

(6)多个参数-使用 Map

Map 集合可以存储多个值,使用 Map 向 mapper 文件一次传入多个参数。Map 集合使用 String 的 key,Object 类型的值存储参数。 mapper 文件使用 # { key } 引用参数值。 例如:
接口方法:
Map data = new HashMap();
data.put(“myname”,”李力”);
data.put(“myage”,20);
​​​​​​​List selectMultiMap(Map map);

mapper 文件:

测试方法:

@Test
public void testSelectMultiMap(){

    Map data = new HashMap<>();
    data.put("myname","李力");// #{myname}
    data.put("myage",20); // #{myage}
    List stuList = studentDao.selectMultiMap(data);
    stuList.forEach( stu -> System.out.println(stu));
}

(7)#和$

  • #:占位符,告诉 mybatis 使用实际的参数值代替。并使用PrepareStatement 对象执行 sql 语句, #{…}代替 sql 语句的“?”。这样做更安全,更迅速,通常也是首选做法,
mapper 文件

转为 MyBatis 的执行是:

String sql=” select id,name,email,age from student where id=?”;
PreparedStatement ps = conn.prepareStatement(sql);
ps.setInt(1,1005);

解释:

where id=? 就是 where id=#{studentId}
ps.setInt(1,1005) , 1005 会替换掉 #{studentId}
  • $ 字符串替换,告诉 mybatis 使用$包含的“字符串”替换所在位置。使用Statement 把 sql 语句和${}的内容连接起来。主要用在替换表名,列名,不同列排序等操作
例 1: 分别使用 id , email 列查询 Student
接口方法:
Student findById(int id);
Student findByEmail(String email);

mapper 文件:



测试方法:

@Test
public void testFindStuent(){

    Student student1 = studentDao.findById(1002);
    System.out.println("findById:"+student1);
    Student student2 = studentDao.findByEmail("[email protected]");
    System.out.println("findByEmail:"+student2);
}

例 2:通用方法,使用不同列作为查询条件

接口方法:
Student findByDiffField(@Param("col") String colunName,@Param("cval") Object value);
mapper 文件:

测试方法:

@Test
public void testFindDiffField(){

    Student student1 = studentDao.findByDiffField("id",1002);
    System.out.println("按 id 列查询:"+student1);
    Student student2 = studentDao.findByDiffField("email","[email protected]");
    System.out.println("按 email 列查询:"+student2);
}

3、MyBatis 输出结果

(1)resultType

        resultType: 执行 sql 得到 ResultSet 转换的类型,使用类型的完全限定名或别名。 注意如果返回的是集合,那应该设置为集合包含的类型,而不是集合本身。 resultType resultMap ,不能同时使用。
  • 简单类型
接口方法:
int countStudent();

mapper 文件:

测试方法:

@Test
public void testRetunInt(){

    int count = studentDao.countStudent();
    System.out.println("学生总人数:"+ count);
}
  • 对象类型
接口方法:
Student selectById(int id);
mapper 文件:
  • Map
        sql 的查询结果作为 Map 的 key 和 value。推荐使用Map。注意:Map 作为接口返回值,sql 语句的查询结果最多只能有一条记录。大于 一条记录是错误。
接口方法:
Map selectReturnMap(int id);

mapper 文件:

测试方法:

@Test
public void testReturnMap(){
    
    Map retMap = studentDao.selectReturnMap(1002);
    System.out.println("查询结果是 Map:"+retMap);
}

(2)resultMap

        resultMap 可以自定义 sql 的结果和 java 对象属性的映射关系。更灵活的把列值赋值给指定属性。
接口方法:
List selectUseResultMap(QueryParam param);

mapper 文件:



    
    
    
    
    
    



测试方法:

@Test
public void testSelectUseResultMap(){

    QueryParam param = new QueryParam();
    param.setQueryName("李力");
    param.setQueryAge(20);
    List stuList = studentDao.selectUseResultMap(param);
    stuList.forEach( stu -> System.out.println(stu));
}

(3)实体类属性名和列名不同的处理方式

  • 使用列别名和
步骤:
1. 创建新的实体类 PrimaryStudent
package com.hk.domain;

/**
* 

Description: 实体类

*/ public class PrimaryStudent { private Integer stuId; private String stuName; private Integer stuAge; // set , get 方法 }

2. 接口方法

List selectUseFieldAlias(QueryParam param);

3. mapper 文件:

4.测试方法

@Test
public void testSelectUseFieldAlias(){
 QueryParam param = new QueryParam();
 param.setQueryName("李力");
 param.setQueryAge(20);
 List stuList;
 stuList = studentDao.selectUseFieldAlias(param);
 stuList.forEach( stu -> System.out.println(stu));
}
  • 使用
步骤:
1. 接口方法
List selectUseDiffResultMap(QueryParam param);

2. mapper 文件:




    
    
    
    
    



3. 测试方法
@Test
public void testSelectUseDiffResultMap(){
    QueryParam param = new QueryParam();
    param.setQueryName("李力");
    param.setQueryAge(20);
    List stuList;
    stuList = studentDao.selectUseDiffResultMap(param);
    stuList.forEach( stu -> System.out.println(stu));
}

(4)模糊 like

        模糊查询的实现有两种方式, 一是 java 代码中给查询数据加上“%” ; 二是在 mapper 文件 sql 语句的条件位置加上“%”
需求:查询姓名有“力”的
例 1: java 代码中提供要查询的 “%力%”
接口方法:
List selectLikeFirst(String name);

mapper 文件:

测试方法:
@Test
public void testSelectLikeOne(){
    String name="%力%";
    List stuList = studentDao.selectLikeFirst(name);
    stuList.forEach( stu -> System.out.println(stu));
}

2mapper 文件中使用 like name "%" #{xxx} "%"

接口方法:
List selectLikeSecond(String name);

mapper 文件:

测试方法:

@Test
public void testSelectLikeSecond(){
    String name="力";
    List stuList = studentDao.selectLikeSecond(name);
    stuList.forEach( stu -> System.out.println(stu));
}

五、动态 SQL

        动态 SQL,通过 MyBatis 提供的各种标签对条件作出判断以实现动态拼接 SQL 语句。这里的条件判断使用的表达式为 OGNL 表达式。常用的动态 SQL标签有等。
        MyBatis 的动态 SQL 语句,与 JSTL 中的语句非常相似。动态 SQL,主要用于解决查询条件不确定的情况:在程序运行期间,根据用户提交的查询条件进行查询。提交的查询条件不同,执行的 SQL 语句不同。若将每种可能的情况均逐一列出,对所有条件进行排列组合,将会出现大量的
SQL 语句。此时,可使用动态 SQL 来解决这样的问题。
        在 mapper 的动态 SQL 中若出现大于号(>)、小于号(<)、大于等于号(>=),小于等于号(<=)等符号,最好将其转换为实体符号。否则,XML 可能会出现解析出错问题。
        特别是对于小于号(<),在 XML 中是绝不能出现的。否则解析 mapper文件会出错。
实体符号表:
< 小于 <
> 大于 >
>= 大于等于 >=
<= 小于等于 <=

1、标签

        对于该标签的执行,当 test 的值为 true 时,会将其包含的 SQL 片断拼接到其所在的 SQL 语句中。
语法: sql 语句的部分
接口方法:
List selectStudentIf(Student student);
mapper 文件:

测试方法:

@Test
public void testSelect() throws IOException {
    Student param = new Student();
    param.setName("李力");
    param.setAge(18);
    List studentList = studentDao.selectStudentIf(param);
    studentList.forEach( stu -> System.out.println(stu));
}

2、

        标签的中存在一个比较麻烦的地方:需要在 where 后手工添加 1=1的子句。因为,若 where 后的所有条件均为 false,而 where 后若又没有 1=1 子句,则 SQL 中就会只剩下一个空的 where,SQL 出错。所以,在where 后,需要添加永为真子句 1=1,以防止这种情况的发生。但当数据量很大时,会严重影响查询效率。
        使用标签,在有查询条件时,可以自动添加上 where 子句;没有查询条件时,不会添加 where 子句。需要注意的是,第一个标签中的 SQL 片断,可以不包含 and。不过,写上 and 也不错,系统会将多出的 and 去掉。但其它中 SQL 片断的 and,必须要求写上。否则 SQL 语句将拼接出错。
语法: 其他动态 sql
接口方法:
List selectStudentWhere(Student student);

mapper 文件:

测试方法:

@Test
public void testSelectWhere() throws IOException {
    Student param = new Student();
    param.setName("李力");
    param.setAge(18);
    List studentList = studentDao.selectStudentWhere(param);
    studentList.forEach( stu -> System.out.println(stu));
}

3、

标签用于实现对于数组与集合的遍历。对其使用,需要注意:
  • collection 表示要遍历的集合类型, list ,array 等。
  • open、close、separator 为对遍历内容的 SQL 拼接。
语法:
< foreach collection= " 集合类型 " open= " 开始的字符 " close= " 结束的字符 " item= " 集合中的成员 " separator= " 集合成员之间的分隔符 " >
         #{item 的值 }
foreach >
(1) 遍历 List<简单类型>
        表达式中的 List 使用 list 表示,其大小使用 list.size 表示。
需求:查询学生 id 是 1002,1005,1006
接口方法:
List selectStudentForList(List idList);

mapper 文件:

测试方法:

@Test
public void testSelectForList() {
    List list = new ArrayList<>();
    list.add(1002);
    list.add(1005);
    list.add(1006);
    List studentList = studentDao.selectStudentForList(list);
    studentList.forEach( stu -> System.out.println(stu));
}

(2)遍历 List<对象类型>

接口方法:
List selectStudentForList2(List stuList);

mapper 文件:

测试方法:
@Test
public void testSelectForList2() {
    List list = new ArrayList<>();
    Student s1 = new Student();
    s1.setId(1002);
    list.add(s1);
    s1 = new Student();
    s1.setId(1005);
    list.add(s1);
    List studentList = studentDao.selectStudentForList2(list);
    studentList.forEach( stu -> System.out.println(stu));
}

4、代码片段

        标签用于定义 SQL 片断,以便其它 SQL 标签复用。而其它标签使用该 SQL 片断,需要使用子标签。该标签可以定义 SQL 语句中的任何部分,所以子标签可以放在动态 SQL 的任何位置。
接口方法:
List selectStudentSqlFragment(List stuList);

mapper 文件:



    select id,name,email,age from student

测试方法:
@Test
public void testSelectSqlFragment() {
    List list = new ArrayList<>();
    Student s1 = new Student();
    s1.setId(1002);
    list.add(s1);
    s1 = new Student();
    s1.setId(1005);
    list.add(s1);
    List studentList = studentDao.selectStudentSqlFragment(list);
    studentList.forEach( stu -> System.out.println(stu));
}

六、MyBatis 配置文件

1、主配置文件

        之前项目中使用的 mybatis.xml 是主配置文件。
        主配置文件特点:
  • xml 文件,需要在头部使用约束文件

  • 根元素,<configuration>
  • 主要包含内容:
                定义别名
                数据源
                mapper 文件

2、dataSource 标签

        Mybatis 中访问数据库,可以连接池技术,但它采用的是自己的连接池技术。在 Mybatis 的 mybatis.xml 配置文件中,通过来实现 Mybatis 中连接池的配置。
数据源分为三类:
  • UNPOOLED 不使用连接池的数据源
  • POOLED 使用连接池的数据源
  • JNDI 使用 JNDI 实现的数据源
其中 UNPOOLED ,POOLED 数据源实现了 javax.sq.DataSource 接口,JNDI 和前面两个实现方式不同,了解可以

dataSource 配置

在 MyBatis.xml 主配置文件,配置 dataSource:

    
    
    
    
    

        MyBatis 在初始化时,根据的 type 属性来创建相应类型的数据源DataSource,即:

  • type=”POOLED”:MyBatis 会创建 PooledDataSource 实例
  • type=”UNPOOLED” : MyBatis 会创建 UnpooledDataSource 实例
  • type=”JNDI”:MyBatis 会从 JNDI 服务上查找 DataSource 实例,然后返回使用

3、使用数据库属性配置文件

        为 了方便对数据库连接的管理,DB 连接四要素数据一般都是存放在一个专门的属性文件中的。MyBatis 主配置文件需要从这个属性文件中读取这些数据。
步骤:
(1) 在 classpath 路径下,创建 properties 文件
                在 resources 目录创建 jdbc.properties 文件,文件名称自定义。 Mybatis框架_第1张图片
(2) 使用 properties 标签
修改主配置文件,文件开始位置加入:
Mybatis框架_第2张图片
(3)使用 key 指定值

    
    
    
    
    

4、typeAliases(类型别名)

        Mybatis 支持默认别名,我们也可以采用自定义别名方式来开发,主要使用在 select id,name,email,age from student

5、mappers(映射器)

(1)
        使用相对于类路径的资源,从 classpath 路径查找文件
        例如:
(2)
        指定包下的所有 Dao 接口
        如:
        注意:此种方法要求 Dao 接口名称和 mapper 映射文件名称相同,且在同一个目录中。

七、PageHelper 分页

1 maven 坐标

    com.github.pagehelper
    pagehelper
    5.1.10

(2)加入 plugin 配置

之前加入

    

(3)PageHelper 对象

        查询语句之前调用 PageHelper.startPage 静态方法。
        除了 PageHelper.startPage 方法外,还提供了类似用法的 PageHelper.offsetPage 方法。
        在你需要进行分页的 MyBatis 查询方法前调用 PageHelper.startPage 静态方法即可,紧跟
在这个方法后的第一个 MyBatis 查询方法 会被进行分页。
@Test
public void testSelect() throws IOException {
    //获取第 1 页,3 条内容
    PageHelper.startPage(1,3);
    List studentList = studentDao.selectStudents();
    studentList.forEach( stu -> System.out.println(stu));
}

你可能感兴趣的:(#,SSM框架,mybatis)