14、动态SQL语句
15、mybatis缓存
16、缓存的使用顺序说明
17、mybatis 逆向工程
14、动态SQL语句
实体类:
public class User { private int id; private String lastName; private int sex;
14.1、if 语句
说明: if语句,可以动态的根据你的值来决定,是否需要动态的添加查询条件。
代码:
public List<User> queryUsersByNameAndSex(String name, int sex);
配置:
<!-- public List<User> queryUsersByNameAndSex(String name, int sex); --> <select id="queryUsersByNameAndSex" resultType="com.tcent.pojo.User"> select id,last_name lastName,sex from t_user where <if test="param1 != null"> last_name like concat('%',#{param1},'%') </if> <if test="param2 == 1 || param2 == 0"> and sex = #{param2} </if> </select>
测试:
@Test public void testQueryUsersByNameAndSex() throws Exception { SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder() .build(Resources.getResourceAsStream("mybatis-config.xml")); SqlSession session = sqlSessionFactory.openSession(); try { UserMapper userMapper = session.getMapper(UserMapper.class); // name的值,如果等于null ,这个时候会出现问题。 // sex 性别 。1是男,0是女 如果出现0或1之外的值。也是非法值。 System.out.println( userMapper.queryUsersByNameAndSex("bbb", 10) ); } catch (Exception e) { e.printStackTrace(); } finally { session.close(); } }
14.2、where 语句
说明: where语句,可以帮我们在多个动态语句中,有效的去掉前面的多余的and 或 or 之类的多余关键字
where标签,还只可以动态的判断中间是否包含查询条件。如果没有连where关键字也不会出现。
<select id="queryUsersByNameAndSex" resultType="com.tcent.pojo.User"> select id,last_name lastName,sex from t_user <where> <if test="param1 != null"> last_name like concat('%',#{param1},'%') </if> <if test="param2 == 1 || param2 == 0"> and sex = #{param2} </if> </where> </select>
14.3、trim语句
说明:trim 可以动态在包含的语句前面和后面添加内容。也可以去掉前面或者后面给定的内容
- prefix 前面添加内容
- suffix 后面添加内容
- suffixOverrides 去掉的后面内容
- prefixOverrides 去掉的前面内容
<select id="queryUsersByNameAndSexTrim" resultType="com.tcent.pojo.User"> select id,last_name lastName,sex from t_user <where> <!-- prefix 前面添加内容 suffix 后面添加内容 suffixOverrides 去掉的后面内容 prefixOverrides 去掉的前面内容 --> <trim prefixOverrides="and" suffixOverrides="and"> <if test="param1 != null"> last_name like concat('%',#{param1},'%') and </if> <if test="param2 == 1 || param2 == 0"> sex = #{param2} </if> </trim> </where> </select>
14.4、choose( when , otherwise )语句
说明:choose when otherwise 可以执行多路选择判断,但是只会有一个分支会被执行。
类似switch case 语句
方法代码:
public List<User> queryUsersByNameAndSexChoose(String name, int sex);
xml中的配置:
<select id="queryUsersByNameAndSexChoose" resultType="com.tcent.pojo.User"> select id,last_name lastName,sex from t_user <where> <!-- 我们希望,如果name的值非空,只查询name 如果name的值非法,而sex的值合法。只查询sex 如果两个都不合法,都不要(或者你可以自己加一些查询条件) --> <choose> <when test="param1 != null"> last_name like concat('%',#{param1},'%') </when> <when test="param2 == 1 || param2 == 0"> sex = #{param2} </when> <otherwise> sex = 0 </otherwise> </choose> </where> </select>
测试代码:
@Test public void testQueryUsersByNameAndSexChoose() throws Exception { SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder() .build(Resources.getResourceAsStream("mybatis-config.xml")); SqlSession session = sqlSessionFactory.openSession(); try { UserMapper userMapper = session.getMapper(UserMapper.class); // name的值,如果等于null ,这个时候会出现问题。 // sex 性别 。1是男,0是女 如果出现0或1之外的值。也是非法值。 System.out.println( userMapper.queryUsersByNameAndSexChoose(null, 1) ); } catch (Exception e) { e.printStackTrace(); } finally { session.close(); } }
14.4、set语句
删除条件后的逗号
代码:
public int updateUser(User user);
xml中的配置:
<update id="updateUser" parameterType="com.tcent.pojo.User"> update t_user <set> last_name = #{lastName} , <!-- 我们希望可以动态的判断,如果sex非法,不更新sex的值。 --> <if test="sex == 1 || sex == 0"> sex = #{sex} </if> </set> where id = #{id} </update>
测试的代码:
@Test public void testUpdateUser() throws Exception { SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder() .build(Resources.getResourceAsStream("mybatis-config.xml")); SqlSession session = sqlSessionFactory.openSession(); try { UserMapper userMapper = session.getMapper(UserMapper.class); // name的值,如果等于null ,这个时候会出现问题。 // sex 性别 。1是男,0是女 如果出现0或1之外的值。也是非法值。 userMapper.updateUser(new User(5, "bbb", 10)); session.commit(); } catch (Exception e) { e.printStackTrace(); } finally { session.close(); } }
14.5、foreach语句
代码:
/** * select * from t_user where id in(1,2,3,4,5) */ public List<User> queryUsersByIds(List<Integer> ids);
xml中的配置:
<!-- public List<User> queryUsersByIds(List<Integer> ids); --> <select id="queryUsersByIds" resultType="com.tcent.pojo.User"> select id,last_name lastName,sex from t_user <where> id in <!-- foreach标签用来遍历集合 collection遍历的数据源 open属性设置遍历的开始内容 close属性设置遍历的结束内容 item属性是当前遍历到的数据 separator属性设置遍历的每个元素之间的间隔符 --> <foreach collection="list" open="(" close=")" item="i" separator=","> #{i} </foreach> </where> </select>
测试代码:
@Test public void testQueryUsersByIds() throws Exception { SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder() .build(Resources.getResourceAsStream("mybatis-config.xml")); SqlSession session = sqlSessionFactory.openSession(); try { UserMapper userMapper = session.getMapper(UserMapper.class); List<Integer> ids = new ArrayList<Integer>(); ids.add(1); ids.add(2); ids.add(5); ids.add(6); System.out.println( userMapper.queryUsersByIds( ids ) ); } catch (Exception e) { e.printStackTrace(); } finally { session.close(); } }
15、mybatis缓存
缓存:缓存指的是将经常访问的数据保存到一个高速的数据存储区。缓存的目的就是为了快速访问
一级缓存: 指的是将数据保存一SqlSession中(同一个SqlSession)
二级缓存: 指的是将数据保存一mapper中(同一个sqlSessionFactory)
准备一个UserMapper
public interface UserMapper { public User queryUserById(int id); public int updateUser(User user); }
UserMapper.xml中的配置:
<mapper namespace="com.atguigu.dao.UserMapper"> <!-- public User queryUserById(int id); --> <select id="queryUserById" resultType="com.tcent.pojo.User"> select id,last_name lastName,sex from t_user where id = #{id} </select> <!-- public User updateUser(User user); --> <update id="updateUser" parameterType="com.tcent.pojo.User" > update t_user set last_name = #{lastName},sex = #{sex} where id = #{id} </update> </mapper>
15.1、mybatis的一级缓存的示例
@Test public void testQueryUserById() throws Exception { SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder() .build(Resources.getResourceAsStream("mybatis-config.xml")); SqlSession session = sqlSessionFactory.openSession(); UserMapper mapper = session.getMapper(UserMapper.class); User user = mapper.queryUserById(1); System.out.println(user); user = mapper.queryUserById(1); System.out.println(user); session.close(); }
15.1.2、一级缓存的管理
缓存失效的四种情况:
1.不在同一个SqlSession对象中
// 1.不在同一个SqlSession对象中 @Test public void testQueryUserByIdFail1() throws Exception { SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder() .build(Resources.getResourceAsStream("mybatis-config.xml")); SqlSession session = sqlSessionFactory.openSession(); UserMapper mapper = session.getMapper(UserMapper.class); User user = mapper.queryUserById(1); System.out.println(user); session.close(); SqlSession session2 = sqlSessionFactory.openSession(); UserMapper userMapper2 = session2.getMapper(UserMapper.class); User user2 = userMapper2.queryUserById(1); System.out.println(user2); session2.close(); }
2.执行语句的参数不同。缓存中也不存在数据。
// 2.执行语句的参数不同。缓存中也不存在数据。 public void testQueryUserByIdFail2() throws Exception { SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder() .build(Resources.getResourceAsStream("mybatis-config.xml")); SqlSession session = sqlSessionFactory.openSession(); UserMapper mapper = session.getMapper(UserMapper.class); User user = mapper.queryUserById(1); System.out.println(user); user = mapper.queryUserById(2); System.out.println(user); session.close(); }
3.执行增,删,改,语句,会清空掉缓存
@Test // 3.执行增,删,改,语句,会清空掉缓存 public void testQueryUserByIdFail3() throws Exception { SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder() .build(Resources.getResourceAsStream("mybatis-config.xml")); SqlSession session = sqlSessionFactory.openSession(); UserMapper mapper = session.getMapper(UserMapper.class); User user = mapper.queryUserById(1); System.out.println(user); //////////////////////////////////////////// mapper.updateUser(new User(5, "cccc", 1)); session.commit(); /////////////////////////////////////////// user = mapper.queryUserById(1); System.out.println(user); session.close(); }
4.手动清空缓存数据
@Test // 4.手动清空缓存数据 public void testQueryUserByIdFail4() throws Exception { SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder() .build(Resources.getResourceAsStream("mybatis-config.xml")); SqlSession session = sqlSessionFactory.openSession(); UserMapper mapper = session.getMapper(UserMapper.class); User user = mapper.queryUserById(1); System.out.println(user); session.clearCache(); user = mapper.queryUserById(1); System.out.println(user); session.close(); }
四种效果图都一样
15.2、mybatis的二级缓存
二级缓存的图解示
二级缓存的使用:
myBatis的二级缓存默认是不开启的。我们需要在mybatis的核心配置文件中配置setting选项 和 在Mapper的配置文件中加入cache标签。并且需要被二级缓存的对象必须要实现java的序列化接口。
二级缓存的使用步骤:
1、在mybatis-config.xml中配置选项
<settings>
<!-- 开启二级缓存 -->
<setting name="cacheEnabled" value="true"/>
</settings>
2、在Mapper.xml中去添加一个cache<>cache</>空标签即可
3、对象必须要实现java的序列化接口。implements Serializable
15.2.1、二级缓存的演示
@Test public void testCacheLevel2() throws IOException { SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder() .build(Resources.getResourceAsStream("mybatis-config.xml")); SqlSession session = sqlSessionFactory.openSession(); UserMapper mapper = session.getMapper(UserMapper.class); User user = mapper.queryUserById(1); System.out.println(user); session.close(); SqlSession session2 = sqlSessionFactory.openSession(); UserMapper userMapper2 = session2.getMapper(UserMapper.class); User user2 = userMapper2.queryUserById(1); System.out.println(user2); session2.close(); }
16、缓存的使用顺序说明:
1、当我们执行一个查询语句的时候。mybatis会先去二级缓存中查询数据。如果二级缓存中没有。就到一级缓存中查找。
2、如果二级缓存和一级缓存都没有。就发sql语句到数据库中去查询。
3、查询出来之后马上把数据保存到一级缓存中。
4、当SqlSession关闭的时候,会把一级缓存中的数据保存到二级缓存中。
17、mybatis 逆向工程
MyBatis逆向工程,简称MBG。是一个专门为MyBatis框架使用者定制的代码生成器。可以快速的根据表生成对应的映射文件,接口,以及Bean类对象。
在Mybatis中,有一个可以自动对单表生成的增,删,改,查代码的插件。
叫 mybatis-generator-core-1.3.2。
它可以帮我们对比数据库表之后,生成大量的这个基础代码。
这些基础代码有:
1、数据库表对应的javaBean对象
2、这些javaBean对象对应的Mapper接口
3、这些Mapper接口对应的配置文件
<!-- 去掉全部的注释 --> <commentGenerator> <property name="suppressAllComments" value="true" /> </commentGenerator>
创建一个Java工程
log4j-1.2.17.jar
mybatis-3.4.1.jar
mybatis-generator-core-1.3.2.jar
mysql-connector-java-5.1.7-bin.jar
生成代码:
public class Runner { public static void main(String[] args) throws Exception { List<String> warnings = new ArrayList<String>(); boolean overwrite = true; File configFile = new File("mbg.xml"); ConfigurationParser cp = new ConfigurationParser(warnings); Configuration config = cp.parseConfiguration(configFile); DefaultShellCallback callback = new DefaultShellCallback(overwrite); MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings); myBatisGenerator.generate(null); } }
附一张mybatis的组成图