Mybatis的使用

前言

整个实验使用Maven 来管理项目,编译器IDEA,github仓库 https://github.com/pallcard/mybatis

JDBC连接数据库

1.引入依赖(pom.xml)

<dependencies>
	<dependency>
	    <groupId>mysql</groupId>
	    <artifactId>mysql-connector-java</artifactId>
	    <version>5.1.32</version>
	</dependency>
</dependencies>	

说明:(pom.xml)
Maven 项目默认编译项目为JDK 1.5,通过引入以下依赖来指定Maven 编译版本

<build>
	  <plugins>
	        <plugin>
	            <groupId>org.apache.maven.plugins</groupId>
	            <artifactId>maven-compiler-plugin</artifactId>
	            <version>3.1</version>
	            <configuration>
	                <source>1.8</source>
	                <target>1.8</target>
	            </configuration>
	        </plugin>
	  </plugins>
</build>

2.JDBC测试类JDBCTest.java

public class JDBCTest {
    public static void main(String[] args) throws Exception {
        Connection connection = null;
        PreparedStatement prepareStatement = null;
        ResultSet rs = null;

        try {
            // 加载驱动(每次加载驱动,驱动名硬编码)
            Class.forName("com.mysql.jdbc.Driver");
            // 获取连接(每次获取连接,连接信息硬编码)
            String url = "jdbc:mysql://127.0.0.1:3306/mybatis_demo";
            String user = "root";
            String password = "";
            connection = DriverManager.getConnection(url, user, password);
            // 获取statement,preparedStatement (sql和java代码耦合)
            String sql = "select * from tb_user where id=?";
            prepareStatement = connection.prepareStatement(sql);
            // 设置参数(参数类型手动判断、设置)
            prepareStatement.setLong(1, 1l);
            // 执行查询
            rs = prepareStatement.executeQuery();
            // 处理结果集(结果集中数据类型、下标、列名要手动判断)
            while (rs.next()) {
                System.out.println(rs.getString("user_name"));
                System.out.println(rs.getString("name"));
                System.out.println(rs.getInt("age"));
                System.out.println(rs.getDate("birthday"));
            }
        } finally {
            //(每次都要打开或关闭连接,浪费资源)
            // 关闭连接,释放资源
            if (rs != null) {
                rs.close();
            }
            if (prepareStatement != null) {
                prepareStatement.close();
            }
            if (connection != null) {
                connection.close();
            }
        }
    }
}
Mybaits整体架构

Mybaits整体架构

Mybaits快速入门

1.引入依赖(pom.xml)

<!--mybatis-->
<dependency>
     <groupId>org.mybatis</groupId>
     <artifactId>mybatis</artifactId>
     <version>3.2.8</version>
 </dependency>
<!--引入日志依赖包-->
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-log4j12</artifactId>
    <version>1.7.5</version>
</dependency>

2.User.java

public class User {
    private int id;
    private String userName;
    private String password;
    private String name;
    private Integer age;
    private Integer sex;
    private Date birthday;
    private String created;
    private String updated;
	// get、set、toString省
}

添加log4j.properties

log4j.rootLogger=DEBUG,A1
log4j.logger.org.apache=DEBUG
log4j.appender.A1=org.apache.log4j.ConsoleAppender
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss,SSS} [%t] [%c]-[%p] %m%n

3.全局配置文件(mybatis-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>
    <properties>
        <property name="driver" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://127.0.0.1:3306/mybatis_demo?useUnicode=true&amp;characterEncoding=utf-8&amp;allowMultiQueries=true"/>
        <property name="username" value="root"/>
        <property name="password" value=""/>
    </properties>

    <!-- 环境,可以配置多个,default:指定采用哪个环境 -->
    <environments default="test">
        <!-- id:唯一标识 -->
        <environment id="test">
            <!-- 事务管理器,JDBC类型的事务管理器 -->
            <transactionManager type="JDBC" />
            <!-- 数据源,池类型的数据源 -->
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver" />
                <property name="url" value="jdbc:mysql://127.0.0.1:3306/mybatis_demo?useUnicode=true&amp;characterEncoding=utf-8&amp;allowMultiQueries=true" />
                <property name="username" value="root" />
                <property name="password" value="" />
            </dataSource>
        </environment>
        <environment id="development">
            <!-- 事务管理器,JDBC类型的事务管理器 -->
            <transactionManager type="JDBC" />
            <!-- 数据源,池类型的数据源 -->
            <dataSource type="POOLED">
                <property name="driver" value="${driver}" /> <!-- 配置了properties,所以可以直接引用 -->
                <property name="url" value="${url}" />
                <property name="username" value="${username}" />
                <property name="password" value="${password}" />
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="mappers/UserMapper.xml" />
    </mappers>
</configuration>

4.配置Map.xml(UserMapper.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">
<!-- mappers:根标签,namespace:命名空间,随便写,一般保证命名空间唯一 -->
<mapper namespace="UserMapper">
    <!-- statement,内容:sql语句。id:唯一标识,随便写,在同一个命名空间下保持唯一
       resultType:sql语句查询结果集的封装类型,tb_user即为数据库中的表
     -->
    <select id="selectUser" resultType="cn.wishhust.mybatis.first.User">
      select * from tb_user where id = #{id};
   </select>
</mapper>

5.MybatisTest.java

public class MybatisTest {
    public static void main(String[] args) throws Exception {
        // 指定全局配置文件
        String resource = "mybatis-config.xml";
        // 读取配置文件
        InputStream inputStream = Resources.getResourceAsStream(resource);
        // 构建sqlSessionFactory
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        // 获取sqlSession
        SqlSession sqlSession = sqlSessionFactory.openSession();
        try {
            // 操作CRUD,第一个参数:指定statement,规则:命名空间+“.”+statementId
            // 第二个参数:指定传入sql的参数:这里是用户id
            User user = sqlSession.selectOne("UserMapper.selectUser", 1);
            System.out.println(user);
        } finally {
            sqlSession.close();
        }
    }
}

6.Mybatis步骤

1)配置mybatis-config.xml 全局的配置文件 (1、数据源,2、外部的mapper)

2)创建SqlSessionFactory

3)通过SqlSessionFactory创建SqlSession对象

4)通过SqlSession操作数据库 CRUD

5)调用session.commit()提交事务

6)调用session.close()关闭会话

Mybatis实现CRUD

1.UserDao接口

public interface UserDao {
    /**
     * 根据id查询用户信息
     *
     * @param id
     * @return
     */
    public User queryUserById(int id);

    /**
     * 查询所有用户信息
     *
     * @return
     */
    public List<User> queryUserAll();

    /**
     * 新增用户
     *
     * @param user
     */
    public void insertUser(User user);

    /**
     * 更新用户信息
     *
     * @param user
     */
    public void updateUser(User user);

    /**
     * 根据id删除用户信息
     *
     * @param id
     */
    public void deleteUser(int id);
}

2.UserDaoImpl

public class UserDaoImpl implements UserDao {
    public SqlSession sqlSession;

    public UserDaoImpl(SqlSession sqlSession) {
        this.sqlSession = sqlSession;
    }

    @Override
    public User queryUserById(int id) {
        return this.sqlSession.selectOne("UserDao.queryUserById", id);
    }

    @Override
    public List<User> queryUserAll() {
        return this.sqlSession.selectList("UserDao.queryUserAll");
    }

    @Override
    public void insertUser(User user) {
        this.sqlSession.insert("UserDao.insertUser", user);
    }

    @Override
    public void updateUser(User user) {
        this.sqlSession.update("UserDao.updateUser", user);
    }

    @Override
    public void deleteUser(int id) {
        this.sqlSession.delete("UserDao.deleteUser", id);
    }
}

3.UserDaoMapper.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">
<!-- mapper:根标签,namespace:命名空间,随便写,一般保证命名空间唯一 -->
<mapper namespace="UserDao">
    <!-- statement,内容:sql语句。id:唯一标识,随便写,在同一个命名空间下保持唯一
       resultType:sql语句查询结果集的封装类型,tb_user即为数据库中的表
     -->
    <!--<select id="queryUserById" resultType="com.zpc.mybatis.pojo.User">-->
    <!--select * from tb_user where id = #{id}-->
    <!--</select>-->

    <!--使用别名-->
    <select id="queryUserById" resultType="cn.wishhust.mybatis.pojo.User">
      select
       tuser.id as id,
       tuser.user_name as userName,
       tuser.password as password,
       tuser.name as name,
       tuser.age as age,
       tuser.birthday as birthday,
       tuser.sex as sex,
       tuser.created as created,
       tuser.updated as updated
       from
       tb_user tuser
       where tuser.id = #{id};
   </select>

    <select id="queryUserAll" resultType="cn.wishhust.mybatis.pojo.User">
        select * from tb_user;
    </select>

    <!--插入数据-->
    <insert id="insertUser" parameterType="cn.wishhust.mybatis.pojo.User">
        INSERT INTO tb_user (
        user_name,
        password,
        name,
        age,
        sex,
        birthday,
        created,
        updated
        )
        VALUES
        (
        #{userName},
        #{password},
        #{name},
        #{age},
        #{sex},
        #{birthday},
        now(),
        now()
        );
    </insert>

    <update id="updateUser" parameterType="cn.wishhust.mybatis.pojo.User">
        UPDATE tb_user
        <trim prefix="set" suffixOverrides=",">
            <if test="userName!=null">user_name = #{userName},</if>
            <if test="password!=null">password = #{password},</if>
            <if test="name!=null">name = #{name},</if>
            <if test="age!=null">age = #{age},</if>
            <if test="sex!=null">sex = #{sex},</if>
            <if test="birthday!=null">birthday = #{birthday},</if>
            updated = now(),
        </trim>
        WHERE
        (id = #{id});
    </update>

    <delete id="deleteUser">
        delete from tb_user where id=#{id}
    </delete>
</mapper>

4.mybatis-config.xml

<mappers>
    <mapper resource="mappers/UserMapper.xml" />
    <mapper resource="mappers/UserDaoMapper.xml" />
</mappers>

5.测试
引入依赖

<!--junit-->
<dependency>
  <groupId>junit</groupId>
  <artifactId>junit</artifactId>
  <version>4.12</version>
</dependency>

UserDaoTest .java(测试类的生成可以在UserDao上Alt+enter,选择创建测试类)

public class UserDaoTest {

    public UserDao userDao;
    public SqlSession sqlSession;

    @Before
    public void setUp() throws Exception {
        // mybatis-config.xml
        String resource = "mybatis-config.xml";
        // 读取配置文件
        InputStream is = Resources.getResourceAsStream(resource);
        // 构建SqlSessionFactory
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
        // 获取sqlSession
        sqlSession = sqlSessionFactory.openSession();
        this.userDao = new UserDaoImpl(sqlSession);
    }

    @Test
    public void queryUserById() {
        System.out.println(this.userDao.queryUserById(1));
    }

    @Test
    public void queryUserAll() {
        List<User> userList = this.userDao.queryUserAll();
        for (User user : userList) {
            System.out.println(user);
        }
    }

    @Test
    public void insertUser() {
        User user = new User();
        user.setAge(16);
        user.setBirthday(new Date("1990/09/02"));
        user.setName("大鹏");
        user.setPassword("123456");
        user.setSex(1);
        user.setUserName("evan");
        this.userDao.insertUser(user);
        this.sqlSession.commit();

    }

    @Test
    public void updateUser() {
        User user = new User();
        user.setBirthday(new Date());
        user.setName("www");
        user.setPassword("654321");
        user.setSex(1);
        user.setUserName("www");
        user.setId(1);
        this.userDao.updateUser(user);
        this.sqlSession.commit();

    }

    @Test
    public void deleteUser() {
        this.userDao.deleteUser(4);
        this.sqlSession.commit();
    }
}
动态代理Mapper实现类

1.UserMapper(对应原UserDao)

public interface UserMapper {
    /**
     * 登录(直接使用注解指定传入参数名称)
     * @param userName
     * @param password
     * @return
     */
    public User login(@Param("userName") String userName, @Param("password") String password);

    /**
     * 根据表名查询用户信息(直接使用注解指定传入参数名称)
     * @param tableName
     * @return
     */
    public List<User> queryUserByTableName(@Param("tableName") String tableName);

    /**
     * 根据Id查询用户信息
     * @param id
     * @return
     */
    public User queryUserById(int id);

    /**
     * 查询所有用户信息
     * @return
     */
    public List<User> queryUserAll();

    /**
     * 新增用户信息
     * @param user
     */
    public void insertUser(User user);

    /**
     * 根据id更新用户信息
     * @param user
     */
    public void updateUser(User user);

    /**
     * 根据id删除用户信息
     * @param id
     */
    public void deleteUserById(int id);
}

2.UserMapper.xml
mapper:根标签,namespace:命名空间,为了使用接口动态代理,这里必须是接口的全路径名

<?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:命名空间,随便写,一般保证命名空间唯一 ,为了使用接口动态代理,这里必须是接口的全路径名-->
<mapper namespace="cn.wishhust.mybatis.mappers.UserMapper">
    <!--
       1.#{},预编译的方式preparedstatement,使用占位符替换,防止sql注入,一个参数的时候,任意参数名可以接收
       2.${},普通的Statement,字符串直接拼接,不可以防止sql注入,一个参数的时候,必须使用${value}接收参数
     -->
    <select id="queryUserByTableName" resultType="cn.wishhust.mybatis.pojo.User">
        select * from ${tableName}
    </select>

    <select id="login" resultType="cn.wishhust.mybatis.pojo.User">
        select * from tb_user where user_name = #{userName} and password = #{password}
    </select>

    <!-- statement,内容:sql语句。
       id:唯一标识,随便写,在同一个命名空间下保持唯一,使用动态代理之后要求和方法名保持一致
       resultType:sql语句查询结果集的封装类型,使用动态代理之后和方法的返回类型一致;resultMap:二选一
       parameterType:参数的类型,使用动态代理之后和方法的参数类型一致
     -->
    <select id="queryUserById" resultType="cn.wishhust.mybatis.pojo.User">
        select * from tb_user where id = #{id}
    </select>
    <select id="queryUserAll" resultType="cn.wishhust.mybatis.pojo.User">
        select * from tb_user
    </select>
    <!-- 新增的Statement
       id:唯一标识,随便写,在同一个命名空间下保持唯一,使用动态代理之后要求和方法名保持一致
       parameterType:参数的类型,使用动态代理之后和方法的参数类型一致
       useGeneratedKeys:开启主键回写
       keyColumn:指定数据库的主键
       keyProperty:主键对应的pojo属性名
     -->
    <insert id="insertUser" useGeneratedKeys="true" keyColumn="id" keyProperty="id"
            parameterType="cn.wishhust.mybatis.pojo.User">
        INSERT INTO tb_user (
            id,
            user_name,
            password,
            name,
            age,
            sex,
            birthday,
            created,
            updated
        )
        VALUES
        (
            null,
            #{userName},
            #{password},
            #{name},
            #{age},
            #{sex},
            #{birthday},
            NOW(),
            NOW()
        );
    </insert>
    <!--
       更新的statement
       id:唯一标识,随便写,在同一个命名空间下保持唯一,使用动态代理之后要求和方法名保持一致
       parameterType:参数的类型,使用动态代理之后和方法的参数类型一致
     -->
    <update id="updateUser" parameterType="cn.wishhust.mybatis.pojo.User">
        UPDATE tb_user
        <trim prefix="set" suffixOverrides=",">
            <if test="userName!=null">user_name = #{userName},</if>
            <if test="password!=null">password = #{password},</if>
            <if test="name!=null">name = #{name},</if>
            <if test="age!=null">age = #{age},</if>
            <if test="sex!=null">sex = #{sex},</if>
            <if test="birthday!=null">birthday = #{birthday},</if>
            updated = now(),
        </trim>
        WHERE
        (id = #{id});
    </update>
    <!--
       删除的statement
       id:唯一标识,随便写,在同一个命名空间下保持唯一,使用动态代理之后要求和方法名保持一致
       parameterType:参数的类型,使用动态代理之后和方法的参数类型一致
     -->
    <delete id="deleteUserById" parameterType="java.lang.Integer">
        delete from tb_user where id=#{id}
    </delete>
</mapper>

3.mybatis-config.xml

<mappers>
    <mapper resource="mappers/UserMapper.xml" />
    <mapper resource="mappers/UserDaoMapper.xml" />
    <mapper resource="mappers/UserMapper2.xml" />
</mappers>

4.测试
a.映射文件的命名空间(namespace)必须是mapper接口的全路径
b.映射文件的statement的id必须和mapper接口的方法名保持一致
c.Statement的resultType必须和mapper接口方法的返回类型一致
d.statement的parameterType必须和mapper接口方法的参数类型一致(不一定)

public class UserMapperTest {

    public UserMapper userMapper;

    @Before
    public void setUp() throws Exception {
        // 指定配置文件
        String resource = "mybatis-config.xml";
        // 读取配置文件
        InputStream inputStream = Resources.getResourceAsStream(resource);
        // 构建sqlSessionFactory
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        // 获取sqlSession
        SqlSession sqlSession = sqlSessionFactory.openSession(true);

        // 1. 映射文件的命名空间(namespace)必须是mapper接口的全路径
        // 2. 映射文件的statement的id必须和mapper接口的方法名保持一致
        // 3. Statement的resultType必须和mapper接口方法的返回类型一致
        // 4. statement的parameterType必须和mapper接口方法的参数类型一致(不一定)
        this.userMapper = sqlSession.getMapper(UserMapper.class);

    }

    @Test
    public void login() {
        System.out.println(this.userMapper.login("lk", "123456"));
    }

    @Test
    public void queryUserByTableName() {
        List<User> userList = this.userMapper.queryUserByTableName("tb_user");
        for (User user : userList) {
            System.out.println(user);
        }
    }

    @Test
    public void queryUserById() {
        System.out.println(this.userMapper.queryUserById(1));
    }

    @Test
    public void queryUserAll() {
        List<User> userList = this.userMapper.queryUserAll();
        for (User user : userList) {
            System.out.println(user);
        }
    }
    @Test
    public void insertUser() {
        User user = new User();
        user.setAge(20);
        user.setBirthday(new Date());
        user.setName("大神");
        user.setPassword("123456");
        user.setSex(2);
        user.setUserName("bigGod222");
        this.userMapper.insertUser(user);
        System.out.println(user.getId());
    }

    @Test
    public void updateUser() {
        User user = new User();
        user.setBirthday(new Date());
        user.setName("静静");
        user.setPassword("123456");
        user.setSex(0);
        user.setUserName("Jinjin");
        user.setId(1);
        this.userMapper.updateUser(user);
    }

    @Test
    public void deleteUserById() {
        this.userMapper.deleteUserById(1);
    }
}
Mapper XML文件详解

1.CRUD标签

  • select

id属性:当前名称空间下的statement的唯一标识。必须。要求id和mapper接口中的方法的名字一致。
resultType:将结果集映射为java的对象类型。必须(和 resultMap 二选一)
parameterType:传入参数类型。可以省略

  • insert

id:唯一标识,随便写,在同一个命名空间下保持唯一,使用动态代理之后要求和方法名保持一致
parameterType:参数的类型,使用动态代理之后和方法的参数类型一致
useGeneratedKeys:开启主键回写
keyColumn:指定数据库的主键
keyProperty:主键对应的pojo属性名
标签内部:具体的sql语句。

  • update

id属性:当前名称空间下的statement的唯一标识(必须属性);
parameterType:传入的参数类型,可以省略。
标签内部:具体的sql语句。

  • delete

id属性:当前名称空间下的statement的唯一标识(必须属性);
parameterType:传入的参数类型,可以省略。
标签内部:具体的sql语句。

2.#{}和${}
#{} 和 ${} 在预编译中的处理是不一样的。#{} 在预处理时,会把参数部分用一个占位符 ? 代替;而 ${} 则只是简单的字符串替换.优先使用 #{}, ${} 会导致 sql 注入的问题。

场景1:数据库有两个一模一样的表。历史表,当前表
查询表中的信息,有时候从历史表中去查询数据,有时候需要去新的表去查询数据。
希望使用1个方法来完成操作。

<select id="queryUserByTableName" resultType="com.zpc.mybatis.pojo.User">
    select * from #{tableName}
</select>
<-- 相当于select * from “tb_user”;  会报错 -->

<-- 正确做法 -->
<select id="queryUserByTableName" resultType="com.zpc.mybatis.pojo.User">
    select * from ${tableName}
</select>

注意:
使用 去 取 出 参 数 值 信 息 , 需 要 使 用 {} 去取出参数值信息,需要使用 使{value}
#{} 只是表示占位,与参数的名字无关,如果只有一个参数,会自动对应。多参数时,通常在方法的参数列表上加上一个注释@Param(“xxxx”) 显式指定参数的名字

3.sql片段

<--定义-->
<sql id=””></sql>
<--使用-->
<include refId=”” />
动态sql

动态sql有

  1. if
  2. choose,when,otherwise
  3. where,set
  4. foreach

1.if
场景:查询用户,如果输入了姓名,则按姓名查询

// 接口
List<User> queryUserListByName(@Param("userName") String userName);

<--mapper-->
<mapper namespace="cn.wishhust.mybatis.dao.mappers.DynamicSqlMapper">
    <!--if的简单使用-->
    <select id="queryUserListByName"
            resultType="cn.wishhust.mybatis.pojo.User">
      select * from tb_user
      <if test="userName != null and userName.trim() != ''">
          where user_name like '%${userName}%'
      </if>
    </select>
</mapper>

2.choose,when,otherwise
场景:查询用户,如果输入了姓名则按照姓名模糊查找,否则如果输入了年龄则按照年龄查找,否则查找姓名为“ls”的用户。

// 接口
List<User> queryUserListByNameOrAge(@Param("userName") String userName,
                                    @Param("age") Integer age);
                                        
<--mapper-->
<mapper namespace="cn.wishhust.mybatis.dao.mappers.DynamicSqlMapper">
	<!--choose when otherwise的简单使用-->
    <select id="queryUserListByNameOrAge"
            resultType="cn.wishhust.mybatis.pojo.User">
        select * from tb_user WHERE
        <!--
        1.一旦有条件成立的when,后续的when则不会执行
        2.当所有的when都不执行时,才会执行otherwise
        -->
        <choose>
            <when test="userName!=null and userName.trim()!=''">
                user_name like '%${userName}%'
            </when>
            <when test="age!=null">
                age = #{age}
            </when>
            <otherwise>
                user_name = 'ls'
            </otherwise>
        </choose>
    </select>
</mapper>

3.where 和set
场景一:查询所有用户,如果输入了姓名按照姓名进行模糊查询,如果输入年龄,按照年龄进行查询,如果两者都输入,两个条件都要成立。

// 接口
List<User> queryUserListByNameAndAge(@Param("userName") String userName,
                                     @Param("age") Integer age);

<--mapper-->
<mapper namespace="cn.wishhust.mybatis.dao.mappers.DynamicSqlMapper">
	<!--where 和set的简单使用-->
    <select id="queryUserListByNameAndAge" resultType="cn.wishhust.mybatis.pojo.User">
        select * from tb_user
        <!--如果多出一个and,会自动去除,如果缺少and或者多出多个and则会报错-->
        <where>
            <if test="userName!=null and userName.trim()!=''">
                and name like '%${userName}%'
            </if>
            <if test="age!=null">
                and age = #{age}
            </if>
        </where>
    </select>
</mapper>

场景二:修改用户信息,如果参数user中的某个属性为null,则不修改。

// 接口
void updateUser(User user);

<--mapper-->
<mapper namespace="cn.wishhust.mybatis.dao.mappers.DynamicSqlMapper">
	<update id="updateUser" parameterType="cn.wishhust.mybatis.pojo.User">
        UPDATE tb_user
        <trim prefix="set" suffixOverrides=",">
            <if test="userName!=null">user_name = #{userName},</if>
            <if test="password!=null">password = #{password},</if>
            <if test="name!=null">name = #{name},</if>
            <if test="age!=null">age = #{age},</if>
            <if test="sex!=null">sex = #{sex},</if>
            <if test="birthday!=null">birthday = #{birthday},</if>
            updated = now(),
        </trim>
        WHERE
        (id = #{id});
    </update>
</mapper>

4.foreach
场景:按照多个id查询用户信息。

// 接口
List<User> queryUserListByIds(@Param("ids") int[] ids);

<--mapper-->
<mapper namespace="cn.wishhust.mybatis.dao.mappers.DynamicSqlMapper">
	<!--foreach的简单使用-->
    <select id="queryUserListByIds" resultType="cn.wishhust.mybatis.pojo.User">
        select * from tb_user where id in
        <foreach collection="ids" item="id" open="(" close=")" separator=",">
            #{id}
        </foreach>
    </select>
</mapper>
高级查询

一对一查询
需求:查询订单,并查询出下单人的信息。
Order.java

public class Order {
    private Integer id;
    private Long userId;
    private String orderNumber;
    private Date createdTime;
    private Date updatedTime;
    private User user;
    // get,set,toString
}

OrderMapper.java

public interface OrderMapper {
	Order queryOrderWithUserByOrderNumber(@Param("number") String number);

}

OrderMapper.xml

<!-- mappers:根标签,namespace:命名空间,随便写,一般保证命名空间唯一 -->
<mapper namespace="cn.wishhust.mybatis.dao.mappers.OrderMapper">
    <resultMap id="OrderUserResultMap"
               type="cn.wishhust.mybatis.pojo.Order"
               autoMapping="true">
        <!--
            指定主键
            column:数据库的列名
            property:java实体类中的属性名
        -->
        <id column="id" property="id"/>
        <!--association:完成子对象的映射-->
        <!--property:子对象在父对象中的属性名-->
        <!--javaType:子对象的java类型-->
        <!--autoMapping:完成子对象的自动映射,若开启驼峰,则按驼峰匹配-->
        <association property="user"
                     javaType="cn.wishhust.mybatis.pojo.User"
                     autoMapping="true">
            <id column="user_id" property="id"/>
        </association>
    </resultMap>

    <select id="queryOrderWithUserByOrderNumber"
            resultMap="OrderUserResultMap">
      select * from tb_order o left join tb_user u
        on o.user_id=u.id
        where o.order_number = #{number}
    </select>
</mapper>
缓存

一级缓存
Mybatis的一级缓存的作用域是session,当openSession()后,如果执行相同的SQL(相同语句和参数),Mybatis不进行执行SQL,而是从缓存中命中返回。原理:
Mybatis执行查询时首先去缓存区命中,如果命中直接返回,没有命中则执行SQL,从数据库中查询。

在mybatis中,一级缓存默认是开启的,并且一直无法关闭

一级缓存满足条件:
1、同一个session中
2、相同的SQL和参数

二级缓存
mybatis 的二级缓存的作用域是一个mapper的namespace ,同一个namespace中查询sql可以从缓存中命中。

<mapper namespace="cn.wishhust.mybatis.dao.mappers.UserMapper">
    <cache/>
    ...
</mapper>

<settings>
    <!--开启驼峰匹配-->
    <setting name="mapUnderscoreToCamelCase" value="true"/>
    <!--开启二级缓存,全局总开关,这里关闭,mapper中开启了也没用-->
    <setting name="cacheEnabled" value="false"/>
</settings>
sql语句中出现’<’的解决方案

方法一:

转义字符字符说明
&lt;<小于
&gt;>小于
&amp;&
&apos;省略号
&quot;"引号

方法二:

<![CDATA[ 符号 ]]>

注:使用<![CDATA[ ]]>标记的sql语句中的 等标签不会被解析。

参考:https://blog.csdn.net/hellozpc/article/details/80878563#102choose_when_otherwise_1444

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值