天天看点

Mybatis技术一.Mybatis的快速入门二.MapConfig.xml配置文件和mapper.xml映射文件详细解释:3.动态SQL4.mybatis的缓存 5.MyBatis的逆向工程

一.Mybatis的快速入门

1.引入mybatis的坐标,mybatis下载地址:https://github.com/mybatis/mybatis-3

<dependencies>
    <!--mysql驱动坐标-->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.32</version>
    </dependency>
    <!--mybatis的核心坐标-->
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.4.6</version>
    </dependency>
    <!--测试的坐标-->
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
    </dependency>
    <!--日志功能-->
    <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.17</version>
    </dependency>
    <!--lombok-->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.10</version>
    </dependency>
</dependencies>      

2.编写实体类(例子中用User),并且在数据库中建表

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
    private String username;
    private int id;
    private String password;
}
           

Mybatis技术一.Mybatis的快速入门二.MapConfig.xml配置文件和mapper.xml映射文件详细解释:3.动态SQL4.mybatis的缓存 5.MyBatis的逆向工程

后面还要用到物品表,顺便加上:

Mybatis技术一.Mybatis的快速入门二.MapConfig.xml配置文件和mapper.xml映射文件详细解释:3.动态SQL4.mybatis的缓存 5.MyBatis的逆向工程

3.编写MapConfig.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>
    <!--加载外部的properties文件-->
    <properties resource="jdbc.properties"></properties>
    <!--定义别名,注意放置的顺序,不区分大小写,如果不写alias默认别名为类名-->
    <typeAliases>
        <typeAlias type="com.itheima.domain.User" alias="user"></typeAlias>
    </typeAliases>
    <!--配置数据源的环境-->
    <environments default="development">                  <!--目前使用某一个环境-->
        <environment id="development">                    <!--某一个环境的id-->
            <transactionManager type="JDBC"></transactionManager>
            <dataSource type="POOLED">                    <!--表明数据源使用连接池技术-->
                <property name="driver" value="${jdbc.driver}"></property><!--配置数据源-->
                <property name="url" value="${jdbc.url}"></property>
                <property name="username" value="${jdbc.username}"></property>
                <property name="password" value="${jdbc.password}"></property>
            </dataSource>
        </environment>
    </environments>
    <!--加载映射文件-->
    <mappers>
        <!--mapper接口所在的包要和映射文件所在的包一致-->
        <!--mapper要和映射文件的名字一样-->
        <mapper resource="com.itheima.mapper\UserMapper.xml"></mapper>
    </mappers>
</configuration>
           

4.编写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">

<!--配置映射sql语句,namespace要写全类名-->
<mapper namespace="mapper.Usermapper">

    <select id="findUserById" resultType="User">
        select * from user where id= #{id}
    </select>
</mapper>
           
import domin.User;
public interface Usermapper {
    User findUserById(int id);
}
           

5.测试代码:

@Test//简单查询
    public void test1() throws IOException {
        InputStream resourceAsStream = Resources.getResourceAsStream("mybatis_config.xml");
        SqlSessionFactory build = new SqlSessionFactoryBuilder().build(resourceAsStream);
        SqlSession sqlSession = build.openSession();
        Usermapper usermapper = sqlSession.getMapper(Usermapper.class);
        User user = usermapper.findUserById(4);
        System.out.println(user);
        sqlSession.commit();
    }
           

6.【拓展】:reasourses目录下添加log4j.xml的配置文件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
    <appender name="STDOUT" class="org.apache.log4j.ConsoleAppender">
        <param name="Encoding" value="UTF-8" />
        <layout class="org.apache.log4j.PatternLayout">
			<param name="ConversionPattern" value="%-5p %d{MM-dd HH:mm:ss,SSS} %m (%F:%L) \n" />
        </layout>
    </appender>
    <logger name="java.sql">
        <level value="debug" />
    </logger>
    <logger name="org.apache.ibatis">
        <level value="info" />
    </logger>
    <root>
        <level value="debug" />
        <appender-ref ref="STDOUT" />
    </root>
</log4j:configuration>
           

7.【拓展】封装工具类

public class SqlSessionUtil {
    public static SqlSession getSqlSession(){
        InputStream resourceAsStream = null;
        SqlSession sqlSession=null;
        try {
            resourceAsStream = Resources.getResourceAsStream("mybatis_config.xml");
            SqlSessionFactory build = new SqlSessionFactoryBuilder().build(resourceAsStream);
            sqlSession = build.openSession(true);//自动提交事务
        } catch (IOException e) {
            e.printStackTrace();
        }
        return sqlSession;
    }
}
           

二.MapConfig.xml配置文件和mapper.xml映射文件详细解释:

1.MapConfig.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>
    <!--加载外部的properties文件-->
    <properties resource="jdbc.properties"></properties>
    <!--定义别名,注意放置的顺序,不区分大小写;如果不写alias默认别名为类名,且不区分大小写--> 
    <typeAliases>
        <typeAlias type="com.itheima.domain.User" alias="user"></typeAlias>
        <!--给整个包设置别名 -->
        <package name=" com.itheima.domain "></package >
    </typeAliases>
    <!--配置数据源的环境-->
    <environments default="development"><!--使用某一个环境-->
        <environment id="development"> <!--某一个环境的id-->                 
            <transactionManager type="JDBC"></transactionManager>
                                     <!--JDBC/MANAGED-->
                                     <!--JDBC:表示使用原生的事务管理方式,事务的提交靠手动 -->
                                     <!--MANAGED:被管理,例如Spring -->      
            <dataSource type="POOLED"> <!--POOLED/UNPOOLED/JNDI -->
                                       <!--POOLED:表明使用连接池技术-->
                                       <!--UNPOOLED:表明不使用连接池技术-->
                                       <!-- JNDI:表明使用上下文中的数据源-->
               <property name="driver" value="${jdbc.driver}"></property><!--配置数据源-->
               <property name="url" value="${jdbc.url}"></property>
               <property name="username" value="${jdbc.username}"></property>
               <property name="password" value="${jdbc.password}"></property>
            </dataSource>
        </environment>
    </environments>
    <!--加载映射文件-->
    <mappers>
        <mapper resource="com.itheima.mapper\UserMapper.xml"></mapper>
    </mappers>
</configuration>
           

2.mapper.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">
<!--1.这个命名空间的名字要和接口的全限定名相同-->
<!--2.id要和接口的方法名字相同-->
<!--3.parameterType要和接口的输入参数类型一样-->
<!--4.resultType要和接口的输出类型一样-->
<mapper namespace="com.itheima.mapper.myMapper">
    <!--普通查询操作-->
    <select id="search"  resultType="user">
        select * from user where id=#{id}
    </select>
</mapper>
           

五种传参数方式:

1.单个字面量参数

2.多个字面量参数

3.自定义的map集合

4.实体类型参数

5.加了注解(@Param)的参数

<!--下面是五种传递参数的方式-->
    <!--第1种,单个字面量类型的参数:User getUserByUsername(String username)-->
    <select id="getUserByUsername" resultType="User">
        select * from user where username= #{username} <!--这里#{}里面的id可以随便写,写aaa都行-->
    </select>

    <!--第2种,多个字面量类型的参数:User getUser(String username,String password);-->
    <select id="getUser" resultType="User">
        <!--这个是框架进行封装到map集合中,username和password分别封装到arg0和arg1中,或者用param1和param2也能提取到-->
        select * from user where username= #{arg0} and password=#{arg1}
    </select>

    <!--第3种,多个字面量类型的参数:User getUserByMap(Map<String,Object> map);-->
    <select id="getUserByMap" resultType="User">
        <!--自己创建map集合传进参数里,map.put("usermane","admin");map.put("password","123456");-->
        select * from user where username = #{username} and password = #{password}
    </select>

    <!--第4种,实体类型的参数:User getUserByPojo(User user);-->
    <select id="getUserByPojo" resultType="User">
        <!--传一个实体类对象,可以将实体类对象的属性取出来-->
        select * from user where username = #{username} and password = #{password}
    </select>

    <!--第5种,使用注解标识方法中的参数:getUserByParam(@Param("username") String username, @Param("password") String password);-->
    <!--mapper.getUserByParam("admin","123456");-->
    <select id="getUserByParam" resultType="User">
        select * from user where username = #{username} and password = #{password}
    </select>
           
@Test
    public void test3() throws IOException {
        SqlSession sqlSession = SqlSessionUtil.getSqlSession();
        Usermapper usermapper = sqlSession.getMapper(Usermapper.class);
        //第一种
        User user1 = usermapper.getUserByUsername("xueyimeng");
        System.out.println(user1);
        //第二种
        User user2 = usermapper.getUser("xueyimeng","123");
        System.out.println(user2);
        //第三种
        Map<String,Object> map=new HashMap<>();
        map.put("username","lisi");
        map.put("password","123");
        User user3 = usermapper.getUserByMap(map);
        System.out.println(user3);
        //第四种
        User user4 = usermapper.getUserByPojo(new User(4, "xueyimeng", "123"));
        System.out.println(user4);
        //第五种
        User user5 = usermapper.getUserByParam("xueyimeng", "123");
        System.out.println(user5);
    }
           

五种返回结果:

1.返回单个对象

2.返回多个对象(实体类的List集合)

3.返回单个数据

4.一条数据返回map集合

5.多条数据返回map集合(map集合的map集合)

<!--第1种 返回值为单个对象:User getUserByUsername(String username)-->
    <select id="getUserByUsername" resultType="User">
        select * from user where username= #{username}
    </select>
    <!--第2种 返回对象集合 List<User> getUsers();-->
    <select id="getUsers" resultType="User">
        select * from user
    </select>

    <!--第3种 返回单个数据 int getCount();-->
    <select id="getCount" resultType="_integer">
        select count(id) from user
    </select>

    <!--第4种 查一条数据返回map集合 Map<String,Object> getUserToMap(@Param("id") int id);-->
    <select id="getUserToMap" resultType="map">
        select * from user where id=#{id}
    </select>

    <!--第5种 查多条数据返回map集合 -->
      <!--第一种方式 Map<String,Object> Map<String,Object> getUsersToMapOne();-->
      <!--一条数据对应一个map;若有多条数据,就会产生多个map集合,此时可以将这些map放在一个list集合中获取-->
      <select id="getUsersToMapOne" resultType="map">
         select * from user
      </select>
      <!--第二种方式 @MapKey("id") Map<String,Object> getUsersToMapTwo();-->
      <!--相当于在map外面又套了一个map,最外面的map是用id(主键)作为键的-->
      <select id="getUsersToMapTwo" resultType="map">
         select * from user
      </select>
           
@Test//五种返回结果
    public void test4() throws IOException {
        SqlSession sqlSession = SqlSessionUtil.getSqlSession();
        Usermapper usermapper = sqlSession.getMapper(Usermapper.class);
        //第一种  返回一个对象
        User user1 = usermapper.getUserByUsername("xueyimeng");
        System.out.println(user1);
        //第二种  返回对象集合
        List<User> users = usermapper.getUsers();
        System.out.println(users);
        //第三种  返回单个数据
        int count = usermapper.getCount();
        System.out.println(count);
        //第四种  查一条数据返回map集合
        Map<String, Object> map = usermapper.getUserToMap(4);
        System.out.println(map);
        //第五种  查多条数据返回map集合
          //5.1
        List<Map<String, Object>> mapsOne = usermapper.getUsersToMapOne();
        System.out.println(mapsOne);
          //5.2
        Map<String, Object> mapsTwo = usermapper.getUsersToMapTwo();
        System.out.println(mapsTwo);
    }
           

特殊的SQL执行:

1.模糊查询

2.批量删除

3.动态获取表名

4.添加功能获取自增的主键

<!--特殊SQL-->
    <!--模糊查询  List<User> getUserByLike(@Param("username") String username);-->
    <select id="getUserByLike" resultType="User">
        <!--select * from t_user where username like '%${username}%'-->
        <!--select * from t_user where username like concat('%',#{username},'%')-->
        select * from user where username like "%"#{username}"%"
    </select>
    <!--批量删除  int deleteMore(@Param("ids") String ids);-->
    <delete id="deleteMore" >
        delete from user where id in (${ids})
    </delete>
    <!--动态获取表名  getUserByTable(@Param("tableName") String tableName)-->
    <select id="getUserByTable" resultType="User">
        select * from ${tableName}
    </select>
    <!--添加功能获取自增的主键 void insertUser(User user);-->
    <!--useGeneratedKeys:设置使用自增的主键;keyProperty:因为增删改有统一的返回值是受影响的行数,
    因此只能将获取的自增的主键放在传输的参数user对象的某个属性中-->
    <insert id="insertUser" useGeneratedKeys="true" keyProperty="id">
        insert into user values (null,#{username},#{password})
    </insert>
           
@Test//特殊Sql
    public void test5() throws IOException {
        SqlSession sqlSession = SqlSessionUtil.getSqlSession();
        Usermapper usermapper = sqlSession.getMapper(Usermapper.class);
        //第一种 模糊查询
        List<User> users = usermapper.getUserByLike("梨");
        System.out.println(users);
        //第二种 批量删除
        int count = usermapper.deleteMore("1,2");
        System.out.println(count);
        //第三种 动态获取表名
        List<User> users2 = usermapper.getUserByTable("user");
        System.out.println(users2);
        //第四种 添加功能获取自增的主键
        User user = new User("lisi", "123");
        usermapper.insertUser(user);
        System.out.println(user);
    }
           

resultMap的映射

1.普通的映射:

Mybatis技术一.Mybatis的快速入门二.MapConfig.xml配置文件和mapper.xml映射文件详细解释:3.动态SQL4.mybatis的缓存 5.MyBatis的逆向工程
<!-- resultMap处理映射  List<Goods> getAllgoods();-->
    <resultMap id="AllgoodsMap" type="Goods"><!--type:查询的数据要映射的实体类的类型-->
        <id property="id" column="id"></id><!--id:设置主键的映射关系;result:设置普通字段的映射关系-->
        <result property="userId" column="user_id"></result><!--property:设置映射关系中实体类中的属性名-->
        <result property="name" column="name"></result><!--column:设置映射关系中表中的字段名-->
    </resultMap>
    <select id="getAllgoods" resultMap="AllgoodsMap">
        select * from goods
    </select>
           
@Test//resultMap
    public void test6() throws IOException {
        SqlSession sqlSession = SqlSessionUtil.getSqlSession();
        goodsMapper goodsMapper = sqlSession.getMapper(goodsMapper.class);
        List<Goods> allgoods = goodsMapper.getAllgoods();
        System.out.println(allgoods);
    }
           

2.多对一映射(物品类里加唯一主人对象,三种解决方式)

@Test//resultMap
    public void test6() throws IOException {
        SqlSession sqlSession = SqlSessionUtil.getSqlSession();
        goodsMapper goodsMapper = sqlSession.getMapper(goodsMapper.class);
        List<Goods> allgoodsByMap = goodsMapper.getAllgoodsByMap();
        System.out.println(allgoodsByMap);
    }
           
<!--多表联查映射,级联方式处理  List<Goods> getAllgoodsByMap();-->
    <resultMap id="jilian" type="Goods">
        <id property="id" column="goods_id"></id>
        <result property="userId" column="user_id"></result>
        <result property="name" column="name"></result>
        <result property="user.id" column="user_id"></result>
        <result property="user.username" column="username"></result>
        <result property="user.password" column="password"></result>
    </resultMap>
    <select id="getAllgoodsByMap" resultMap="jilian">
        SELECT *,goods.`id` goods_id FROM goods,USER WHERE goods.`user_id`=user.`id`
    </select>


 <!--多表联查映射,association方式处理  List<Goods> getAllgoodsByMap();-->
    <resultMap id="jilian" type="Goods">
        <id property="id" column="goods_id"></id>
        <result property="userId" column="user_id"></result>
        <result property="name" column="name"></result>
        <association property="user" javaType="User"> 
             <!--association:处理多对一的映射关系;property:需要处理多对的映射关系的属性名;javaType:该属性的类型-->
            <id property="id" column="user_id"></id>
            <result property="username" column="username"></result>
            <result property="password" column="password"></result>
        </association>
    </resultMap>
    <select id="getAllgoodsByMap" resultMap="jilian">
        SELECT *,goods.`id` goods_id FROM goods,USER WHERE goods.`user_id`=user.`id`
    </select>


    <!--多表联查,第一步就是根据物品的id查物品的信息多表分步联查 Goods getGoodsAndUserByStepOne(@Param("id") Integer id);-->
    <resultMap id="StepOnetest" type="Goods">
        <id property="id" column="id"></id><!--id:设置主键的映射关系;result:设置普通字段的映射关系-->
        <result property="userId" column="user_id"></result><!--property:设置映射关系中实体类中的属性名-->
        <result property="name" column="name"></result><!--column:设置映射关系中表中的字段名-->
        <!--select:设置分布查询的sql的唯一标识(namespace.SQLId或mapper接口的全类名.方法名)-->
        <!--column:设置分步查询的条件,将查到的物品对应的使用者id的字段名填进第二个方法的参数里-->
        <association property="user"
                     select="mapper.goodsMapper.getGoodsAndUserByStepTwo"
                     column="user_id" ></association>
    </resultMap>
    <select id="getGoodsAndUserByStepOne" resultMap="StepOnetest">
        select * from goods where id=#{id}
    </select>
    <!--多表联查,第二步查物品里的user属性 User getGoodsAndUserByStepTwo(@Param("id") Integer id);-->
    <resultMap id="StepTwotest" type="User">
        <id property="id" column="id"></id>
        <result property="username" column="username"></result>
        <result property="password" column="password"></result>
    </resultMap>
    <select id="getGoodsAndUserByStepTwo" resultMap="StepTwotest">
        select * from user where id=#{id}
    </select>
           

3.一对多映射

@Test//一对多映射
    public void test6() throws IOException {
        SqlSession sqlSession = SqlSessionUtil.getSqlSession();
        Usermapper mapper = sqlSession.getMapper(Usermapper.class);
        User goodsAndUser = mapper.getGoodsAndUser(5);
        System.out.println(goodsAndUser);
    }
           
<!--第一种方式:用collection-->
    <resultMap id="GoodsAndUserMap" type="User">
        <id property="id" column="user_id"></id>
        <result property="username" column="username"></result>
        <result property="password" column="password"></result>
        <collection property="goodsList" ofType="Goods">
            <id property="id" column="goods_id"></id><!--前面的是属性,后面的是数据库字段-->
            <result property="userId" column="user_id"></result>
            <result property="name" column="name"></result>
        </collection>
    </resultMap>
    <!--User getGoodsAndUser(@Param("id") int id);-->
    <select id="getGoodsAndUser" resultMap="GoodsAndUserMap">
        SELECT *,goods.`id` goods_id FROM USER,goods WHERE goods.`user_id`=user.`id` AND user.`id`=#{id}
    </select>


    <!--第2种方式:分布查询,第一步首先根据id查到某个使用者-->
    <resultMap id="GoodsAndUserByStepFirstMap" type="User">
        <id property="id" column="id"></id>
        <result property="username" column="username"></result>
        <result property="password" column="password"></result>
        <collection property="goodsList"
                    select="mapper.Usermapper.getGoodsAndUserByStepSecond"
                    column="id"></collection>
    </resultMap>
    <!--User getGoodsAndUserByStepFirst(@Param("id") int id);-->
    <select id="getGoodsAndUserByStepFirst" resultMap="GoodsAndUserByStepFirstMap">
        select * from user where id = #{id}
    </select>
    <!--第二步,将第一步查到的使用者的id字段值填进第二个sql语句里-->
    <!--List<Goods> getGoodsAndUserByStepSecond(@Param("id") int id);-->
    <select id="getGoodsAndUserByStepSecond" resultType="Goods">
        select * from goods where user_id = #{id}
    </select>
           

延迟加载

3.动态SQL

if:

@Test//动态sql_if
    public void test() throws IOException {
        SqlSession sqlSession = SqlSessionUtil.getSqlSession();
        Usermapper mapper = sqlSession.getMapper(Usermapper.class);
        List<User> userByCondition = mapper.getUserByCondition(new User());
        System.out.println(userByCondition);
    }
           
<!--if User getUserByCondition(User user);-->
    <select id="getUserByCondition" resultType="User"><!--这里的1=1相当于select * from user where 1=1 and id = ? -->
        select * from user where 1=1
        <if test="username != null and username !=''"><!--通过test属性的表达式进行判断,若表达式的结果为true,则标签中的内容会执行;-->
            and username = #{username}
        </if>
        <if test="password != null and password !=''">
            and password = #{password}
        </if>
        <if test="id != null and id !=''">
            and id = #{id}
        </if>
    </select>
           

where:

@Test//动态sql_where
    public void test() throws IOException {
        SqlSession sqlSession = SqlSessionUtil.getSqlSession();
        Usermapper mapper = sqlSession.getMapper(Usermapper.class);
        List<User> userByCondition = mapper.getUserByCondition(new User(5));
        System.out.println(userByCondition);
    }
           
<!--where关键字 List<User> getUserByCondition(User user);-->
    <select id="getUserByCondition" resultType="User"> <!--该关键字一般和if连用,用了之后就不用1=1了-->
    select * from user
    <where>
        <if test="username != null and username !=''">
            and username = #{username}
        </if>
        <if test="password != null and password !=''">
            and password = #{password}
        </if>
        <if test="id != null and id !=''">
            and id = #{id}
        </if>
    </where>
    </select>
           

trim:

@Test//动态sql_trim
    public void test() throws IOException {
        SqlSession sqlSession = SqlSessionUtil.getSqlSession();
        Usermapper mapper = sqlSession.getMapper(Usermapper.class);
        List<User> userByCondition = mapper.getUserByCondition(new User(5));
        System.out.println(userByCondition);
    }
           
<!--trim关键字用于去掉或添加标签中的内容 List<User> getUserByCondition(User user);-->
    <select id="getUserByCondition" resultType="User">
        <!--prefix:在trim标签中的内容的前面添加某些内容-->
        <!--suffix:在trim标签中的内容的后面添加某些内容-->
        <!--prefixOverrides:在trim标签中的内容的前面去掉某些内容-->
        <!--suffixOverrides:在trim标签中的内容的后面去掉某些内容-->
        select * from user
        <trim prefix="where" suffixOverrides="and|or">
            <if test="username != null and username !=''">
                 username = #{username} and
            </if>
            <if test="password != null and password !=''">
                 password = #{password} and
            </if>
            <if test="id != null and id !=''">
                 id = #{id}
            </if>
        </trim>
           

choose otherwise when

@Test//动态sql_choose
    public void test() throws IOException {
        SqlSession sqlSession = SqlSessionUtil.getSqlSession();
        Usermapper mapper = sqlSession.getMapper(Usermapper.class);
        List<User> userByCondition = mapper.getUserByChoose(null);
        System.out.println(userByCondition);
    }
           
<select id="getUserByChoose" resultType="User">
 <!--这个相当于if else,一旦满足其中的一个条件就不会看别的条件了,otherwise是在所有的条件都不满足时候会执行的条件-->
        select * from user
        <where>
            <choose>
                <when test="username != null and username != ''">
                    username = #{username}
                </when>
                <when test="password != null and password != ''">
                    password = #{password}
                </when>
                <when test="id != null and id != ''">
                    id = #{id}
                </when>
                <otherwise>
                    username="xueyimeng"
                </otherwise>
            </choose>
        </where>
    </select>
           

foreach

@Test//动态sql_foreach
    public void test() throws IOException {
        SqlSession sqlSession = SqlSessionUtil.getSqlSession();
        Usermapper mapper = sqlSession.getMapper(Usermapper.class);
        int[] ids={3,7};
        int deleteMoreByArray = mapper.deleteMoreByArray(ids);
        System.out.println(deleteMoreByArray);
    }
           
<!--int deleteMoreByArray(int[] ids);-->
    <!--collection:设置要循环的数组或集合array是数组,list是集合
    item:表示集合或数组中的每一个数据
    separator:设置循环体之间的分隔符,分隔符前后默认有一个空格,如,
    open:设置foreach标签中的内容的开始符
    close:设置foreach标签中的内容的结束符-->
    <delete id="deleteMoreByArray">
        delete from user where id in
        <foreach collection="array" item="id" separator="," open="(" close=")">
            #{id}
        </foreach>
    </delete>
           

SQL片段

<!--List<User> search();-->
    <sql id="select">select * from user </sql><!--这是声明,下面的是引用-->
    <select id="search" resultType="User">
        <include refid="select"></include>
    </select>
           

4.mybatis的缓存

一级缓存

       一级缓存是SqlSession级别的,通过同一个SqlSession查询的数据会被缓存,下次查询相同的数据,就会从缓存中直接获取,不会从数据库重新访问

使一级缓存失效的四种情况:

       1.不同的SqlSession对应不同的一级缓存

       2.同一个SqlSession但是查询条件不同

       3.同一个SqlSession两次查询期间执行了任何一次增删改操作

       4.同一个SqlSession两次查询期间手动清空了缓存

二级缓存

       二级缓存是SqlSessionFactory级别,通过同一个SqlSessionFactory创建的SqlSession查询的结果会被缓存;此后若再次执行相同的查询语句,结果就会从缓存中获取

二级缓存开启的条件:

        1.在核心配置文件中,设置全局配置属性cacheEnabled=“true”,默认为true,不需要设置

        2.在映射文件中设置标签

        3.二级缓存必须在SqlSession关闭或提交之后有效

        4.查询的数据所转换的实体类类型必须实现序列化的接口

使二级缓存失效的情况:两次查询之间执行了任意的增删改,会使一级和二级缓存同时失效

二级缓存的相关配置

    在mapper配置文件中添加的cache标签可以设置一些属性

    eviction属性:缓存回收策略

        LRU(Least Recently Used) – 最近最少使用的:移除最长时间不被使用的对象。

        FIFO(First in First out) – 先进先出:按对象进入缓存的顺序来移除它们。

        SOFT – 软引用:移除基于垃圾回收器状态和软引用规则的对象。

        WEAK – 弱引用:更积极地移除基于垃圾收集器状态和弱引用规则的对象。

        默认的是 LRU

    flushInterval属性:刷新间隔,单位毫秒

        默认情况是不设置,也就是没有刷新间隔,缓存仅仅调用语句(增删改)时刷新

    size属性:引用数目,正整数

        代表缓存最多可以存储多少个对象,太大容易导致内存溢出

    readOnly属性:只读,true/false

        true:只读缓存;会给所有调用者返回缓存对象的相同实例。因此这些对象不能被修改。这

                  提供了很重要的性能优势。

        false:读写缓存;会返回缓存对象的拷贝(通过序列化)。这会慢一些,但是安全,因此默

                   认是false

整合EHCache

5.MyBatis的逆向工程

      逆向工程:先创建数据库表,由框架负责根据数据库表,反向生成如下资源:

(1)导入Maven依赖

<dependencies>
        <!--mysql驱动坐标-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.32</version>
        </dependency>
        <!--mybatis的核心坐标-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.4.6</version>
        </dependency>
        <!--测试的坐标-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
        <!--日志功能-->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
        <!--lombok-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.10</version>
        </dependency>
    </dependencies>
    <!-- 控制Maven在构建过程中相关配置 -->
    <build>
        <!-- 构建过程中用到的插件 -->
        <plugins>
            <!-- 具体插件,逆向工程的操作是以构建过程中插件形式出现的 -->
            <plugin>
                <groupId>org.mybatis.generator</groupId>
                <artifactId>mybatis-generator-maven-plugin</artifactId>
                <version>1.3.0</version>
                <!-- 插件的依赖 -->
                <dependencies>
                    <!-- 逆向工程的核心依赖 -->
                    <dependency>
                        <groupId>org.mybatis.generator</groupId>
                        <artifactId>mybatis-generator-core</artifactId>
                        <version>1.3.2</version>
                    </dependency>
                    <!-- 数据库连接池 -->
                    <dependency>
                        <groupId>com.mchange</groupId>
                        <artifactId>c3p0</artifactId>
                        <version>0.9.2</version>
                    </dependency>
                    <!-- MySQL驱动 -->
                    <dependency>
                        <groupId>mysql</groupId>
                        <artifactId>mysql-connector-java</artifactId>
                        <version>8.0.27</version>
                    </dependency>
                </dependencies>
            </plugin>
        </plugins>
    </build>
           

 (2)创建核心配置文件mybatis_config.xml,上面有我就不写了

 (3)创建逆向工程的配置文件,名字必须是

generatorConfig.xml

<?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>
    <!--
    targetRuntime: 执行生成的逆向工程的版本
    MyBatis3Simple: 生成基本的CRUD(清新简洁版)
    MyBatis3: 生成带条件的CRUD(奢华尊享版)
    -->
    <context id="DB2Tables" targetRuntime="MyBatis3Simple">
        <!-- 数据库的连接信息 -->
        <jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"
                        connectionURL="jdbc:mysql://localhost:3306/student"
                        userId="root"
                        password="123456">
        </jdbcConnection>
        <!-- javaBean的生成策略-->
        <javaModelGenerator targetPackage="com.atguigu.mybatis.pojo" targetProject=".\src\main\java">
            <property name="enableSubPackages" value="true" /><!--如果是true上面的com.atguigu就会创建出层级关系-->
            <property name="trimStrings" value="true" />
        </javaModelGenerator>
        <!-- SQL映射文件的生成策略 -->
        <sqlMapGenerator targetPackage="com.atguigu.mybatis.mymapper"
                         targetProject=".\src\main\resources">
            <property name="enableSubPackages" value="true" />
        </sqlMapGenerator>
        <!-- Mapper接口的生成策略 -->
        <javaClientGenerator type="XMLMAPPER"
                             targetPackage="com.atguigu.mybatis.mymapper" targetProject=".\src\main\java">
            <property name="enableSubPackages" value="true" />
        </javaClientGenerator>
        <!-- 逆向分析的表 -->
        <!-- tableName设置为*号,可以对应所有表,此时不写domainObjectName -->
        <!-- domainObjectName属性指定生成出来的实体类的类名 -->
        <table tableName="user" domainObjectName="User"/>
        <table tableName="goods" domainObjectName="Goods"/>
    </context>
</generatorConfiguration>
           

(4)执行MBG插件的generate目标

(5)测试

@Test
    public void testMBG() throws IOException {
        InputStream is = Resources.getResourceAsStream("mybatis_config.xml");
        SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
        SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(is);
        SqlSession sqlSession = sqlSessionFactory.openSession(true);
        GoodsMapper mapper = sqlSession.getMapper(GoodsMapper.class);
        GoodsExample goodsExample = new GoodsExample();
        goodsExample.createCriteria().andIdBetween(1, 9);
        List<Goods> goods = mapper.selectByExample(goodsExample);
        System.out.println(goods);
    }