Mybatis(初级)学习笔记

       Mybatis是一个持久层的框架,是一个不完全的ORM框架。特点是让程序员将主要精力放到sql上,通过Mybatis提供的映射方式,自由灵活的生成满足需要的sql语句。

原理图

                                        SqlMapCogfig.xml(是Mybatis的全局配置文件)配置了数据源,事务等运行环境

                                                    配置映射文件(配置sql语句)mapper.xml、mapper.xml...

                                                                                                    ↓

                                         SqlSessionFactory (会话工厂)  根据配置文件创建会话工厂    作用:得到会话

                                                                                                    ↓

                                                                  SqlSession(会话)  它是一个面向程序员的接口   

                                                                        作用:操作数据库(发出CRUD的sql操作)                    

                                                                                                    ↓

                                                  Executor(执行器) 它也是一个接口( 基本执行器、缓存执行器) 

                                                                    作用:SqlSession内部通过执行器操作数据库

                                                                                                    ↓     

                                                                    mapped    statement(底层封装对象)

                                                                                                    ↓ 
                                                                                                mysql   

入门程序

需求:使用Mybatis操作数据库

流程:

1.配置Mybatis的配置文件,SqlMapConfig.xml(名称不是固定的),SqlMapConfig.xml需要配置环境(数据源),  mapper的加载和事务。

2. 通过配置文件,加载mybatis的运行环境,创建会话工厂SqlSessionFactory,SqlSessionFactory实际使用时按照单例进行管理

3.通过SqlSessionFactory创建SqlSession,SqlSession是一个面向用户的接口(提供操作数据库的方法),实现对象是线程不安全的,建议SqlSession应用场合放到方法体内部。

4.调用sqlSession的方法去操作数据

如果需要提交事务,需要执行SqlSession的commit()方法。

5.释放资源,关闭SqlSession。

数据库内容如下

Mybatis(初级)学习笔记

1.配置Mybatis的全局配置文件SqlMapConfig.xml

(1)配置相关环境,数据源事务等

(2)配置加载sql语句的配置文件

<?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">        <!--配置环境,与Spring整合后由Spring进行管理-->
        <environment id="development">
            <!--启用jdbc事务管理,事务控制由Mybatis管理(后面交由Spring管理)-->
            <transactionManager type="JDBC"/>
            <!--配置数据库连接池参数,由Mybatis管理(后面交由Spring管理)-->
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/how2j?characterEncoding=UTF-8"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
    </environments>

    <!--加载sql语句的配置文件-->
    <mappers>
        <!--使用class按包加载-->
        <mapper resource="Config/sqlmap/User.xml"/>
    </mappers>
</configuration>

2.配置sql语句的配置文件User.xml

相关配置的作用在代码中作出了解释

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


<!--在此配置文件中配置Sql语句-->

<!--namespace为命名空间,其中填写的是Mapper接口的路径,但是这里不用Mapper接口,所以随意填写-->
<mapper namespace="test">
    <!-- #{}表示一个占位符,
         #{id}表示接收的参数,如果输入参数为简单类型则可以随意填写
         resultType是用来指定输出结果所映射的Java对象-->
    <select id="findCategoryById" parameterType="int" resultType="Pojo.Category">
        SELECT * FROM category_ WHERE id = #{id}
    </select>
</mapper>

3.编写输出映射的Pojo对象类(这个是根据数据库查找的数据所写)

package Pojo;

public class Category {

    private int id;

    private String name;

    public int getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Category{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }
}

4.进行Test


public class MybatisTest {
    @Test
    public void findUserById() throws IOException{

        /*定义Mybatis的配置文件*/
        String resource = "SqlMapConfig.xml";

        /*得到配置文件流*/
        InputStream inputStream = Resources.getResourceAsStream(resource);

        /*创建会话工厂,传入Mybatis配置参数*/
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

        /*通过会话工厂得到会话*/
        SqlSession sqlSession = sqlSessionFactory.openSession();

        /*通过SqlSession操作数据库
          第一个参数,映射文件中statement的id,等于=namespace+“.”+id
          第二个参数,指定和映射文件中所匹配的parameterType类型参数*/
        Category category = sqlSession.selectOne("test.findCategoryById",1);
        System.out.println(category);

        /*关闭会话,释放资源*/
        sqlSession.close();

    }
}

5.得到结果

Mybatis(初级)学习笔记


模糊查询

1.在User.xml中加入模糊查询的Sql语句

<!--${}表示拼接sql串,将接收到参数的内容不加修饰拼接在sql语句中,但是可能导致sql注入
    ${value}:接收到如数参数内容,如果传入的是简单类型,${}中只能写value
-->
<select id="findCategoryByName" parameterType="String" resultType="Pojo.Category">
    SELECT * FROM category_ WHERE name like '%${value}%'
</select>

2.写Test程序


public class MybatisTest {
    @Test
    public void findUserById() throws IOException{

        /*定义Mybatis的配置文件*/
        String resource = "SqlMapConfig.xml";

        /*得到配置文件流*/
        InputStream inputStream = Resources.getResourceAsStream(resource);

        /*创建会话工厂,传入Mybatis配置参数*/
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

        /*通过会话工厂得到会话*/
        SqlSession sqlSession = sqlSessionFactory.openSession();

        /*通过SqlSession操作数据库
          第一个参数,映射文件中statement的id,等于=namespace+“.”+id
          第二个参数,指定和映射文件中所匹配的parameterType类型参数*/
        List<Category> list = sqlSession.selectList("test.findCategoryByName","ca");
        System.out.println(list);

        /*关闭会话,释放资源*/
        sqlSession.close();

    }
}

3.得到结果

Mybatis(初级)学习笔记


插入用户

1.在User.xml中加入插入的Sql语句

<!--#{}中填写的是传入pojo中的属性名-->
<insert id="insertCategory" parameterType="Pojo.Category">
    INSERT INTO category_(id,name) value(${id},"${name}")
</insert>

2.写Test程序


public class MybatisTest {
    @Test
    public void findUserById() throws IOException{

        /*定义Mybatis的配置文件*/
        String resource = "SqlMapConfig.xml";

        /*得到配置文件流*/
        InputStream inputStream = Resources.getResourceAsStream(resource);

        /*创建会话工厂,传入Mybatis配置参数*/
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

        /*通过会话工厂得到会话*/
        SqlSession sqlSession = sqlSessionFactory.openSession();

        /*设置插入Pojo*/
        Category category = new Category();
        category.setName("cxx");

        /*通过SqlSession操作数据库
          第一个参数,映射文件中statement的id,等于=namespace+“.”+id
          第二个参数,指定和映射文件中所匹配的parameterType类型参数*/
        sqlSession.insert("test.insertCategory",category);

        sqlSession.commit();

        /*关闭会话,释放资源*/
        sqlSession.close();

    }

3.得到结果

Mybatis(初级)学习笔记

删除用户

1.在User.xml中加入插入的Sql语句

<!--根据id值删除信息,需要输入id值-->
<delete id="deleteCategory" parameterType="int">
    DELETE FROM Category_ WHERE id=#{id}
</delete>

2.写Test程序


public class MybatisTest {
    @Test
    public void findUserById() throws IOException{

        /*定义Mybatis的配置文件*/
        String resource = "SqlMapConfig.xml";

        /*得到配置文件流*/
        InputStream inputStream = Resources.getResourceAsStream(resource);

        /*创建会话工厂,传入Mybatis配置参数*/
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

        /*通过会话工厂得到会话*/
        SqlSession sqlSession = sqlSessionFactory.openSession();

        /*通过SqlSession操作数据库
          第一个参数,映射文件中statement的id,等于=namespace+“.”+id
          第二个参数,指定和映射文件中所匹配的parameterType类型参数*/
        sqlSession.delete("test.deleteCategory",5);

        sqlSession.commit();

        /*关闭会话,释放资源*/
        sqlSession.close();

    }
}

3.得到结果

Mybatis(初级)学习笔记

更新用户

1.在User.xml中加入插入的Sql语句

<!--设置好传入的pojo,里面包括id和更新的信息-->
<update id="updateCategory" parameterType="Pojo.Category">
    UPDATE Category_ set name=#{name} where id=#{id}
</update>

2.Test

public class MybatisTest {
    @Test
    public void findUserById() throws IOException{

        /*定义Mybatis的配置文件*/
        String resource = "SqlMapConfig.xml";

        /*得到配置文件流*/
        InputStream inputStream = Resources.getResourceAsStream(resource);

        /*创建会话工厂,传入Mybatis配置参数*/
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

        /*通过会话工厂得到会话*/
        SqlSession sqlSession = sqlSessionFactory.openSession();

        Category category = new Category();
        category.setId(3);
        category.setName("lalaala");

        /*通过SqlSession操作数据库
          第一个参数,映射文件中statement的id,等于=namespace+“.”+id
          第二个参数,指定和映射文件中所匹配的parameterType类型参数*/
        sqlSession.update("test.updateCategory",category);

        sqlSession.commit();

        /*关闭会话,释放资源*/
        sqlSession.close();

    }
}

3.得到结果

Mybatis(初级)学习笔记


别名定义

在sqlMapconfig.xml中可以定义别名,让Statement中的参数可以直接写类名,而不是全路径。

<!--定义别名,在写Statement的时候就可以直接输入类名-->
<typeAliases>
    <package name="Pojo"></package>
</typeAliases>

Mapper代理开发

1.编写Mapper接口

public interface CategoryMapper {

    public Category findCategoryById(int id) throws Exception;

    public List<Category> findCategoryByName(String name) throws Exception;

    public void insertCategory (Category category)throws Exception;
}

2.配置Sql语句

<!--Mapper代理开发,namespace等于Mapper接口的地址-->
<mapper namespace="Mapper.CategoryMapper">
    <!-- #{}表示一个占位符,
         #{id}表示接收的参数,如果输入参数为简单类型则可以随意填写
         resultType是用来指定输出结果所映射的Java对象-->
    <select id="findCategoryById" parameterType="int" resultType="Pojo.Category">
        SELECT * FROM category_ WHERE id = #{id}
    </select>

    <!--${}表示拼接sql串,将接收到参数的内容不加修饰拼接在sql语句中,但是可能导致sql注入
        ${value}:接收到如数参数内容,如果传入的是简单类型,${}中只能写value
    -->
    <select id="findCategoryByName" parameterType="String" resultType="Pojo.Category">
        SELECT * FROM category_ WHERE name like '%${value}%'
    </select>

    <!--#{}中填写的是传入pojo中的属性名-->
    <insert id="insertCategory" parameterType="Pojo.Category">
        INSERT INTO category_(id,name) value(${id},"${name}")
    </insert>

    <!--根据id值删除信息,需要输入id值-->
    <delete id="deleteCategory" parameterType="int">
        DELETE FROM Category_ WHERE id=#{id}
    </delete>

    <!--设置好传入的pojo,里面包括id和更新的信息-->
    <update id="updateCategory" parameterType="Pojo.Category">
        UPDATE Category_ set name=#{name} where id=#{id}
    </update>
</mapper>

3.写Test实现

public class MapperTest {

    /*通过单例方式管理SqlSessionFactory*/
    /*通过单例方式管理SqlSessionFactory*/
    private SqlSessionFactory sqlSessionFactory;

    @Before
    public void serUp() throws Exception{

        /*重复的代码抽取*/
        String resource = "SqlMapConfig.xml";

        InputStream inputStream = Resources.getResourceAsStream(resource);

        sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    }



    @Test
    public void findCategoryByID()throws Exception{

        SqlSession sqlSession = sqlSessionFactory.openSession();

        /*加载Mapper文件*/
        CategoryMapper categoryMapper = sqlSession.getMapper(CategoryMapper.class);

        Category category = categoryMapper.findCategoryById(1);

        System.out.println(category);

        sqlSession.close();
    }
}

4.结果

Mybatis(初级)学习笔记

总结:

    编写Mapper接口的时候需要遵循的一些开发规范:

    1.接口中的方法名称需要和statement中的id一致

    2.接口中的方法参数需要和statement中的parametertype一致

    3.接口中的方法返回值需要和statement中的resultType一致

    4.mapper的namespace中需要传入Mapper接口的全路径


Mybatis的核心:动态sql

通过if表达式判断,对sql进行灵活的拼接,组装。

需求:使用动态sql进行用户信息的综合查询列表statement的定义

<select id="findCategoryById" parameterType="Pojo.Category" resultType="Pojo.Category">
    SELECT * FROM category_
    <where>                      
        <if test="id!=null">
             id = #{id}
        </if>
    </where>
</select>

sql片段的使用

在mapper.xml中定义抽取重复的sql代码,组成一个sql片段,这样在其他的statement中就可以使用sql片段

1.定义sql片段

<!--定义sql片段,但是不要包括where-->
<sql id="query">
    <if test="id!=null">
        id = #{id}
    </if>
</sql>

2.引用使用include标签来引用sql片段,如果引用的sql片段不在本个mapper的namespace里面,则前面需要加上其他namespace的名称

<select id="findCategoryById" parameterType="Pojo.Category" resultType="Pojo.Category">
    SELECT * FROM category_
    <where>
        <include refid="query"/>     /*y用include标签引用sql片段*/
    </where>
</select>

Sql的遍历集合操作Foreach

Mybatis(初级)学习笔记