一,SqlSessionFactory简介

  1. SqlSessionFactory是mybatis的核心对象
  2. 用于初始化mybatis,创建SqlSession对象
  3. 保证SqlSessionFactory在应用中全局唯一,通常我们通过静态类方式对它进行初始化,SqlSessionFactory本质就是通过加载配置文件,来完成mybatis框架的初始化工作

二,SqlSession简介

  1. SqlSession是mybatis操作数据库的核心对象
  2. SqlSession使用jdbc方式与数据库交互,不那么严谨的我们可以把一个SqlSession是一个扩展过的connection数据库连接对象,在原有的connection基础上封装了大量实用方法
  3. SqlSession对象提供了数据表CRUD对应方法

下面我们演示SqlSessionFactory,SqlSession的创建过程,顺带也验证下之前的配置是否有效

/**
 * 初始化SqlSessionFactory并得到SqlSession对象
 */
public class SqlSessionFactoryTest {
    @Test
    public void test() throws IOException {
        // 利用Reader读取mybatis核心配置文件
        Reader reader = Resources.getResourceAsReader("mybatis-config.xml");
        // 初始化SqlSessionFactory对象并进行配置文件解析
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
        System.out.println("SqlSessionFactory加载成功");
        // 创建SqlSession对象,SqlSession是jdbc扩展类,用于和数据库进行交互
        SqlSession sqlSession = null;
        try {
            sqlSession = sqlSessionFactory.openSession();
            // 创建数据库连接的过程(这里只是测试使用,非必要,正常开发时是由mybatis帮我们自动完成的)
//            Connection connection = sqlSession.getConnection();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (sqlSession != null) {
                // 如果是“POOLED",代表使用连接池,close则是将连接回收到连接池中
                // 如果是“UNPOOLED",代表直连,close则会调用connection.close()方法
                sqlSession.close();
            }
        }
    }
}

如果配置信息有误,系统会报错

mybatis plus java中查询器怎么分组 mybatis查询列表_xml


三,初始化工具类MyBatisUtils

MyBatisUtils工具的主要职责就是帮我们初始化SqlSessionFactory核心对象,保证SqlSessionFactory全局唯一,我们通过程序直接进行演示

/**
 * MyBatisUtils工具类,创建全局唯一SqlSessionFactory对象
 */
public class MyBatisUtils {
    // 利用static属于类不属于对象,且全局唯一
    private static SqlSessionFactory sqlSessionFactory = null;
    // 利用静态块在初始化类时实例化sqlSessionFactory
    static {
        Reader reader = null;
        try {
            reader = Resources.getResourceAsReader("mybatis-config.xml");
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
        } catch (IOException e) {
            e.printStackTrace();
            // 初始化错误时抛出异常ExceptionInInitializerError通知调用者
            throw new ExceptionInInitializerError();
        }
    }

    //创建一个新的SqlSession对象
    public static SqlSession openSession() {
        return sqlSessionFactory.openSession();
    }

    //关闭SqlSession对象
    public static void closeSqlSession(SqlSession sqlSession) {
        if (sqlSession != null) {
            sqlSession.close();
        }
    }
}

错误时的报错提示

mybatis plus java中查询器怎么分组 mybatis查询列表_xml_02

四,MyBatis数据查询

1,创建实体类(Entity)

// 创建实体类
public class Goods {
    private int id;
    private String title;
    private String subTitle;
    private float originalCost;
    private float currentPrice;
    private float discount;
    private int isFreeDelivery;
    private int categoryId;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getSubTitle() {
        return subTitle;
    }

    public void setSubTitle(String subTitle) {
        this.subTitle = subTitle;
    }

    public float getOriginalCost() {
        return originalCost;
    }

    public void setOriginalCost(float originalCost) {
        this.originalCost = originalCost;
    }

    public float getCurrentPrice() {
        return currentPrice;
    }

    public void setCurrentPrice(float currentPrice) {
        this.currentPrice = currentPrice;
    }

    public float getDiscount() {
        return discount;
    }

    public void setDiscount(float discount) {
        this.discount = discount;
    }

    public int getIsFreeDelivery() {
        return isFreeDelivery;
    }

    public void setIsFreeDelivery(int isFreeDelivery) {
        this.isFreeDelivery = isFreeDelivery;
    }

    public int getCategoryId() {
        return categoryId;
    }

    public void setCategoryId(int categoryId) {
        this.categoryId = categoryId;
    }
}

2,创建Mapper XML :说明实体类和哪个表,属性和表里哪个字段对应
3,在Mapper XML中编写sql标签,书写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 XML :说明实体类和哪个表,属性和表里哪个字段对应,当前SQL语句是什么-->
<!--namespace功能类似java中的包,不同的功能可以指定不同的namespace。
namespace名称必须是惟一的,
底下的id可以不是唯一,不同的namespace可以存在同名id-->
<mapper namespace="goods">
    <!--id功能相当于sql的别名-->
    <!--resultType表示数据查询出来后用什么对象保存记录-->
    <select id="selectAll" resultType="com.imooc.mybatis.entity.Goods">
        select * from t_goods order by goods_id desc limit 10
    </select>
</mapper>

4,在mabatis-config.xml配置文件中设置驼峰命名映射
5,在mabatis-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="mapUnderscoreToCamelCase" value="true"/>
    </settings>
    <!--默认环境配置-->
    <environments default="dev">
        <!--支持配置多套环境-->
        <environment id="dev">
            <transactionManager type="JDBC"></transactionManager>
            <!--采用连接池方式管理数据库连接-->
            <dataSource type="POOLED">
                <!--配置数据库连接信息-->
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <property name="url"
                          value="jdbc:mysql://localhost:3306/babytun?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=GMT"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
        <environment id="prd">
            <transactionManager type="JDBC"></transactionManager>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <property name="url"
                          value="jdbc:mysql//192.168.0.1:3306/babytun?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=GMT"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
    </environments>
    <!--声明goods.xml类,让mybatis认识这个文件-->
    <mappers>
        <mapper resource="mappers/goods.xml"/>
    </mappers>

</configuration>

6,在SqlSession执行select语句

@Test
public void testSelectGoods(){
    SqlSession sqlSession = null;
    try {
        sqlSession = MyBatisUtils.openSession();
        // 进行查询,传入的参数取的是在goods.xml文件的namespace名称和select id
        List<Goods> list = sqlSession.selectList("goods.selectAll");
        for (Goods goods : list) {
            System.out.println(goods.getTitle());
        }
    } catch (Exception e) {
        throw e;
    } finally {
        MyBatisUtils.closeSqlSession(sqlSession);
    }
}

五,SQL传参

  1. 我们把需要动态传入参数的情况称为SQL传参
  2. sql传参支持单参数和多参数查询

1,单参数查询
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="goods">
    <!--传入单参数-->
    <select id="selectById" parameterType="int" resultType="com.imooc.mybatis.entity.Goods">
        select * from t_goods where goods_id=#{value }
    </select>
</mapper>

2)书写查询语句

@Test
public void testSelectById() {
    SqlSession sqlSession = null;
    try {
        sqlSession = MyBatisUtils.openSession();
        // 查询单个(第一个参数表示是要查询的对象,第二个表示要动态传递的参数
        Goods goods = sqlSession.selectOne("goods.selectById",739);
        System.out.println(goods.getTitle());
    } catch (Exception e) {
        throw e;
    } finally {
        MyBatisUtils.closeSqlSession(sqlSession);
    }
}

2,多参数查询

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="goods">
    <!--传递多参数,使用parameterType指定map接口,sql中的#{key}提取参数-->
    <select id="selectParams" parameterType="java.util.Map" resultType="com.imooc.mybatis.entity.Goods">
        select * from t_goods
         where current_price between #{min} and #{max }
          order by current_price
          limit 0,#{limt}
    </select>
</mapper>

2)书写查询语句

// 多参数查询
    @Test
    public void testSelectParams() {
        SqlSession sqlSession = null;
        try {
            sqlSession = MyBatisUtils.openSession();
            // 配置xml文件里的所有值都需要传入
            Map map = new HashMap();
            map.put("min", 100);
            map.put("max", 200);
            map.put("limt", 10);
            List<Goods> list = sqlSession.selectList("goods.selectParams", map);
            for (Goods lists : list) {
                System.out.println(lists.getTitle() + ":" + lists.getCurrentPrice());
            }

        } catch (Exception e) {
            throw e;
        } finally {
            MyBatisUtils.closeSqlSession(sqlSession);
        }
    }

六,获取多表关联查询结果

  1. 之前在多表查询时配置xml文件,resultType使用的map类型,产生的结果是无序的。所以更推荐使用LinkedHashMap。
  2. 使用LinkedHashMap时,Mybatis会将每一条记录包装为LinkedHashMap对象,key是字段名,value是字段对应的值,字段类型根据表结构进行自动判断
    优点:易于扩展,易于使用。缺点:太过灵活,无法进行编译时检查
  3. 这里查询出的结果也是原始的字段名,不再是实体的包含大小写的名称
  4. 具体配置如下
<?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="goods">
    <select id="selectByMap" resultType="java.util.LinkedHashMap">
        select * from t_goods g,t_category c where g.category_id=c.category_id;
    </select>
</mapper>
@Test
public void testSelectByMap() {
    SqlSession sqlSession = null;
    try {
        sqlSession = MyBatisUtils.openSession();
        List<Map> list = sqlSession.selectList("goods.selectByMap");
        for (Map map : list) {
            System.out.println(map);
        }
    } catch (Exception e) {
        throw e;
    } finally {
        MyBatisUtils.closeSqlSession(sqlSession);
    }
}