Mybatis快速入门

mybatis

使用到的依赖(gradle)

   //mybatis依赖
   compile group: 'org.mybatis', name: 'mybatis', version: '3.5.6'
    // mysql
    compile group: 'mysql', name: 'mysql-connector-java', version: '8.0.22'
    // mybatis分页插件
    compile group: 'com.github.pagehelper', name: 'pagehelper', version: '5.2.0'

接口类

{
    /**
     * 查询所有
     *
     * @return
     */
    List<School> findSchools();

    /**
     * 条件查询方式1
     *
     * @param jj
     * @return
     */
    List<School> findSchool(@Param("age") int jj);

    /**
     * 条件查询方式2
     * 对象传参
     * 返回其他类型
     *
     * @param s
     * @return
     */
    int findSchoolBySchool(School s);

    /**
     * 使用占位符的方式
     *
     * @param name
     * @return
     */
    List<School> findSchoolByPlaceholder(String name);

    /**
     * 使用map传参
     *
     * @param map
     * @return
     */
    List<School> findSchoolByMap(Map<String, Object> map);

    /**
     * 返回一个map类型
     *
     * @param name
     * @return
     */
    List<Map<Object, Object>> findSchoolReturnMap(@Param("name") String name);

    /**
     * 解决返回值名称  和类的属性名不匹配问题
     *
     * @param name
     * @return
     */
    List<School> findSchoolResolveNameMismatch(@Param("name") String name);

    /**
     * 插入数据
     *
     * @param school
     * @return
     */
    int insertOne(School school);

    /**
     * 模糊查询
     * 方式1: 使用java拼接
     *
     * @param s
     * @return
     */
    List<School> findSchoolByLike1(@Param("name") String s);

    /**
     * 模糊查询
     * 方式2:在mapper.xml中配置拼接
     *
     * @param s
     * @return
     */
    List<School> findSchoolByLike2(@Param("name") String s);

    /**
     * if标签的使用
     *
     * @param map
     * @return
     */
    List<School> findSchoolToIf(Map<String, Object> map);

    /**
     * where标签的使用
     *
     * @param map
     * @return
     */
    List<School> findSchoolToWhere(Map<String, Object> map);

    /**
     * foreach标签的使用
     *
     * @param list
     * @return
     */
    List<School> findSchoolToForeach(List<Integer> list);
}

配置文件

mpaaer.xml

每一个DAO类对应一个Mapper.xml(每一个表的查询方法对应一个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="Mybatis.Dao.SchoolDAO">
    <!--    代码片段   高复用的sql语句可以使用-->
    <sql id="school">
        select * from school
    </sql>

    <!--  查询全部-->
    <select id="findSchools" resultType="Mybatis.bean.School">
    select * from school
  </select>

    <!--  设置参数形式  参数名为@param(value="")中value的值-->
    <!--    使用到了代码的复用   include标签-->
    <select id="findSchool" resultType="Mybatis.bean.School">
        <include refid="school"/>
        where age=#{age}
    </select>

    <!--  对象传参   参数名为对象中的字段         这里要说一下resultType可以是任何java类-->
    <select id="findSchoolBySchool" resultType="int">
    select count(*) from school where age=#{age}
  </select>

    <!--  使用占位符传参      参数名为  arg0   arg1 ....    用到了别名机制-->
    <select id="findSchoolByPlaceholder" resultType="School">
    select * from school where name=#{arg0}
  </select>

    <!--使用map传参 参数名为   map中的字段key值    用到了别名机制-->
    <select id="findSchoolByMap" resultType="s">
    select * from school where name=#{name}
  </select>

    <!--返回一个map类型-->
    <select id="findSchoolReturnMap" resultType="java.util.Map">
    select * from school where name=#{name}
  </select>

    <!--  解决查询值和类中的值不匹配的问题  -->
    <!--  第一种声明resultMap-->
    <!--  第二种修改sql  让返回字段名和类字段名相同-->
    <!--
      id是定义的一个resultMap的名称
      type:是类的全限定名
    -->
    <resultMap id="toSchool" type="Mybatis.bean.School">
        <!--    定义列名和属性名的关系   column列名   property对应属性名-->
        <id column="n" property="name"/>
        <id column="a" property="age"/>
    </resultMap>
    <!-- 这样的sql就是第二种-->
    <select id="findSchoolResolveNameMismatch" resultMap="toSchool">
    select name n,age a from school where name=#{name}
  </select>
    <!--模糊查询方式1-->
    <select id="findSchoolByLike1" resultType="s">
        select * from school where name like #{name}
  </select>
    <!--    模糊查询方式2      % 空格 #{参数} 空格 %-->
    <select id="findSchoolByLike2" resultType="s">
        select * from school where name like '%' #{name} '%'
  </select>

    <!--    动态Sql-->
    <!--if   记得写一个恒成立的条件    防止条件都不成立时  sql语句报错-->
    <select id="findSchoolToIf" resultType="s">
        select * from school where 1=1
        <if test="name!=null and name!=''">
            and name=#{name}
        </if>
        <if test="age!=null and age>=0">
            and age>#{age}
        </if>
    </select>
    <!--    where   可以防止sql报错  自动拼接where条件   或者不拼接-->
    <select id="findSchoolToWhere" resultType="s">
        select * from school
        <where>
            <if test="name!=null and name!=''">
                and name=#{name}
            </if>
            <if test="age!=null and age>=0">
                and age>#{age}
            </if>
        </where>
    </select>
    <!--    foreach-->
    <select id="findSchoolToForeach" resultType="s">
        select * from school
        <where>
            <if test="list!=null">
                age in
                <foreach collection="list" item="i" close=")" open="(" separator=",">
                    #{i}
                </foreach>
            </if>
        </where>
    </select>


    <!--  插入-->
    <insert id="insertOne">
    insert  into school value(#{name},#{age});
  </insert>
</mapper>
mybatis配置文件
<?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>
    <!--    设置db配置文件的位置-->
    <properties resource="db.properties"/>
    <!--    设置日志输出-->
    <settings>
        <setting name="cacheEnabled" value="true"/>
        <setting name="useGeneratedKeys" value="true"/>
        <setting name="defaultExecutorType" value="REUSE"/>
        <setting name="logImpl" value="STDOUT_LOGGING"/>
    </settings>

    <!--    别名机制-->
    <typeAliases>
        <!-- 第一种
             type是类的全限定名
             alias是类的别名
        -->
        <typeAlias type="Mybatis.bean.School" alias="s"/>
        <!--
            第二种
            配置类的所在包
            类的别名:是类的名字不分大小写
            问题:
            如果配置多个包,多个包下存在同名的类,会报错
        -->
        <package name="Mybatis.bean"/>
    </typeAliases>

    <!--    插件配置-->
    <plugins>
        <plugin interceptor="com.github.pagehelper.PageInterceptor"/>
    </plugins>

    <!--    环境配置   数据库连接信息  default表示默认数据库配置  -->
    <environments default="development">
        <!--        数据库配置  id  为该配置的名称  自义定-->
        <environment id="development">
            <!--            处理事务的类型
                    1.JDBC:底层使用的是JDBC方式   调用connection  的rollback  和commit
                    2.MANAGED:把 事务托管给一个容器  比如 spring
            -->

            <transactionManager type="JDBC"/>
            <!--            数据源  type连接方式
                    所有实现了  javax.sql.DataSource的数据源
                    1.POOLED:使用连接池,mybatis会创建一个PooledDataSource类
                    2.UPOOLED:不使用连接池,在每次执行sql时,先创建连接,执行sql,关闭连接
                                mybatis会创建一个UnPooledDataSource
                    3.JNDI:(知道就行) java命名和目录服务(windows注册表)
             -->
            <dataSource type="POOLED">
                <!--读取配置文件中的信息  ${配置文件中的字段名}-->
                <property name="driver" value="${driver}"/>
                <property name="url" value="${url}"/>
                <property name="username" value="${user}"/>
                <property name="password" value="a"/>
            </dataSource>
        </environment>
    </environments>

    <!--    设置mapper所在位置-->
    <mappers>
        <!--        第一种方式-->
        <mapper resource="Mapper/SchoolDAO.xml"/>
        <!--        第二种方式
                配置xml所在的包的全限定名
                要求:
                1.接口和mapper.xml文件同名
                2.接口和mapper.xml在同一文件夹下
        -->
        <!--        <package name="Mapper"/>-->
    </mappers>

</configuration>

创建方法(普通)

String config="mybatis.xml";
//读取这个config表示的文件
InputStream in= Resources.getResourceAsStream(config);
//创建SqlSessionFactoryBuilder
SqlSessionFactoryBuilder builder=new SqlSessionFactoryBuilder();
//通过 builder 创建SqlSessionFactory
SqlSessionFactory factory=builder.build(in);
//创建sqlSession
SqlSession sqlSession=factory.openSession();
//设置查询语句      mapper文件中的命名空间  +.   +语句id
String sqlId="xmlSpring.Dao.SchoolDAO.findSchools";
//查询
List<School> objects = sqlSession.selectList(sqlId);
sqlSession.close();
objects.forEach(System.out::println);
    //读取这个config表示的文件
	InputStream in= Resources.getResourceAsStream(config);
	//创建SqlSessionFactoryBuilder
	SqlSessionFactoryBuilder builder=new SqlSessionFactoryBuilder();
	//通过 builder 创建SqlSessionFactory
	SqlSessionFactory factory=builder.build(in);
	//创建sqlSession
	SqlSession sqlSession=factory.openSession();
    /**
     * mybatis动态代理
     * 要求
     * mapper中的namespace是接口限定名
     * SQL语句的id为方法名
     */
    SchoolDAO dao=sqlSession.getMapper(SchoolDAO.class);
       //查询
        List<School> objects = dao.findSchools();
        objects.forEach(System.out::println);
        System.out.println("-=======================================");
        //条件查询  使用了@param()注解   作用设置对应参数名   赋值给sql语句   建议使用
        List<School> school = dao.findSchool(1);
        school.forEach(System.out::println);
        System.out.println("-=======================================");
        //使用对象查找
        int schoolBySchool = dao.findSchoolBySchool(s);
        System.out.println(schoolBySchool);
        System.out.println("-=======================================");
        //还可以使用占位符
        List<School> schoolByPlaceholder = dao.findSchoolByPlaceholder("2020-11-15");
        schoolByPlaceholder.forEach(System.out::println);
        System.out.println("-=======================================");
        //使用map传参
        Map<String, Object> map = new HashMap<>();
        map.put("name", "2020-11-15");
        List<School> schoolByMap = dao.findSchoolByMap(map);
        schoolByPlaceholder.forEach(System.out::println);
        System.out.println("-=======================================");
        //返回map
        List<Map<Object, Object>> schooReturnMap = dao.findSchoolReturnMap("2020-11-15");
        schooReturnMap.forEach(System.out::println);
        System.out.println("-=======================================");
        //解决返回值名称  和类的属性名不匹配问题
        List<School> SchoolResolveNameMismatch = dao.findSchoolResolveNameMismatch("2020-11-15");
        schooReturnMap.forEach(System.out::println);
        System.out.println("-=======================================");
        //模糊查询
        //方式1  在java中拼接模糊条件
        List<School> SchoolByLike1 = dao.findSchoolByLike1("马%");
        SchoolByLike1.forEach(System.out::println);
        System.out.println("-=======================================");
        //方式2  在mapper中拼接模糊条件
        List<School> SchoolByLike2 = dao.findSchoolByLike2("马");
        SchoolByLike2.forEach(System.out::println);
        System.out.println("-=======================================");
        /*
          动态sql
         */
//        if
        Map<String, Object> map1 = new HashMap<>();
        map1.put("name", "2020-11-15");
        map1.put("age", 2);
        List<School> schoolToIf = dao.findSchoolToIf(map1);
        schoolToIf.forEach(System.out::println);
        System.out.println("-=======================================");
        //where
        Map<String, Object> map2 = new HashMap<>();
        map2.put("name", "2020-11-15");
        List<School> schoolToWhere = dao.findSchoolToWhere(map2);
        schoolToWhere.forEach(System.out::println);
        System.out.println("-=======================================");
        //foreach
        List<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(2);
        list.add(3);
        List<School> schoolToForeach = dao.findSchoolToForeach(list);
        schoolToForeach.forEach(System.out::println);
        System.out.println("-=======================================");

        //pageHelper分页插件测试
        PageHelper.startPage(2,3);
        List<School> schools = dao.findSchools();
        schools.forEach(System.out::println);
        System.out.println("-=======================================");

        //插入使用对象插入
        int i = dao.insertOne(s);
        System.out.println("对象插入结果:" + i);

#和$的区别

  1. #使用 ? 在sql语句中是占位符 , 底层使用的是 preparedStatement 执行sql 效率高
  2. #能有效避免sql注入风险
  3. $不使用占位符 是字符串连接的方式 使用的是Statement 执行sql 效率低
  4. $有sql注入的风险
  5. $可以替换表名或者列名

pageHelper使用

  1. 静态方法,传递两个参数(当前页码,每页查询条数)
  2. 使用pageHelper 分页的时候,不再关注分页语句,查询全部的语句
  3. 自动的对PageHelper.startPage 方法下的第一个sql 查询进行分页
    PageHelper.startPage(1,5);
    //紧跟着的第一个select 方法会被分页
    List list = countryMapper.findAll();

也就是说再Service层PageHelper.startPage(1,5);语句后一定是紧跟查询语句。

Service层示例代码

public PageInfo findPage(int page,int pageSize){
  PageHelper.startPage(page,pageSize);
  List<Company> List=companyDao.selectAll();
  PageInfo pageInfo = new PageInfo(list);
  return pageInfo;
 }

返回的信息就是pageInfo对象,该类是插件里的类,这个类里面的属性还是值得看一看

public class PageInfo<T> implements Serializable {
private static final long serialVersionUID = 1L;
//当前页
private int pageNum;
//每页的数量
private int pageSize;
//当前页的数量
private int size;
//由于startRow 和endRow 不常用,这里说个具体的用法
//可以在页面中"显示startRow 到endRow 共size 条数据"
//当前页面第一个元素在数据库中的行号
private int startRow;
//当前页面最后一个元素在数据库中的行号
private int endRow;
//总记录数
private long total;
//总页数
private int pages;
//结果集
private List<T> list;
//前一页
private int prePage;
//下一页
private int nextPage;
//是否为第一页
private boolean isFirstPage = false;
//是否为最后一页
private boolean isLastPage = false;
//是否有前一页
private boolean hasPreviousPage = false;
//是否有下一页
private boolean hasNextPage = false;
//导航页码数
private int navigatePages;
传智播客——专注于Java、.Net 和Php、网页平面设计工程师的培训
北京市昌平区建材城西路金燕龙办公楼一层电话:400-618-9090
//所有导航页号
private int[] navigatepageNums;
//导航条上的第一页
private int navigateFirstPage;
//导航条上的最后一页
private int navigateLastPage;
}

设置(settings)

这是 MyBatis 中极为重要的调整设置,它们会改变 MyBatis 的运行时行为。 下表描述了设置中各项设置的含义、默认值等。

设置名 描述 有效值 默认值
cacheEnabled 全局性地开启或关闭所有映射器配置文件中已配置的任何缓存。 true | false true
lazyLoadingEnabled 延迟加载的全局开关。当开启时,所有关联对象都会延迟加载。 特定关联关系中可通过设置 fetchType 属性来覆盖该项的开关状态。 true | false false
aggressiveLazyLoading 开启时,任一方法的调用都会加载该对象的所有延迟加载属性。 否则,每个延迟加载属性会按需加载(参考 lazyLoadTriggerMethods)。 true | false false (在 3.4.1 及之前的版本中默认为 true)
multipleResultSetsEnabled 是否允许单个语句返回多结果集(需要数据库驱动支持)。 true | false true
useColumnLabel 使用列标签代替列名。实际表现依赖于数据库驱动,具体可参考数据库驱动的相关文档,或通过对比测试来观察。 true | false true
useGeneratedKeys 允许 JDBC 支持自动生成主键,需要数据库驱动支持。如果设置为 true,将强制使用自动生成主键。尽管一些数据库驱动不支持此特性,但仍可正常工作(如 Derby)。 true | false False
autoMappingBehavior 指定 MyBatis 应如何自动映射列到字段或属性。 NONE 表示关闭自动映射;PARTIAL 只会自动映射没有定义嵌套结果映射的字段。 FULL 会自动映射任何复杂的结果集(无论是否嵌套)。 NONE, PARTIAL, FULL PARTIAL
autoMappingUnknownColumnBehavior 指定发现自动映射目标未知列(或未知属性类型)的行为。NONE: 不做任何反应WARNING: 输出警告日志('org.apache.ibatis.session.AutoMappingUnknownColumnBehavior' 的日志等级必须设置为 WARNFAILING: 映射失败 (抛出 SqlSessionException) NONE, WARNING, FAILING NONE
defaultExecutorType 配置默认的执行器。SIMPLE 就是普通的执行器;REUSE 执行器会重用预处理语句(PreparedStatement); BATCH 执行器不仅重用语句还会执行批量更新。 SIMPLE REUSE BATCH SIMPLE
上一篇:mybatis


下一篇:学习MyBatis必知必会(6)~Mapper基础的拓展