我们可以用mybatis执行sql的形式来对数据的表进行增删改查操作,不过遇到比较复杂的业务需要写复杂的sql时(比如说sql的条件不确定,可能有一个条件或者多个),
我们就需要动态sql来提高sql的灵活性。
示例代码 : Demo.
Java接口 UserMapper.java
//动态Sql
// 1. if where trim
// 查询用户表, 跟名称 密码 地址做多条件查询
//如果参数过多可以使用 Map;
public List<User> cha(@Param("name")String name,@Param("pwd")String pwd,@Param("address")String address);
映射文件:UserMapper.XML
if 完成多条件查询
<select id="cha" resultType="User" >
SELECT * FROM `smbms_user` WHERE 1=1
<if test="name!=null and name!='' " >
AND userName LIKE CONCAT('%',#{name},'%')
if>
<if test="pwd!=null and pwd!='' " >
AND userPassword LIKE CONCAT('%',#{pwd},'%')
if>
<if test="address!=null and address!='' " >
AND address LIKE CONCAT('%',#{address},'%')
if>
select>
where 完成多条件查询
<select id="cha" resultType="User" >
SELECT * FROM `smbms_user`
<where>
<if test="name!=null and name!='' " >
AND userName LIKE CONCAT('%',#{name},'%')
if>
<if test="pwd!=null and pwd!='' " >
AND userPassword LIKE CONCAT('%',#{pwd},'%')
if>
<if test="address!=null and address!='' " >
AND address LIKE CONCAT('%',#{address},'%')
if>
where>
select>
trim 完成多条件查询
<select id="cha" resultType="User" >
SELECT * FROM `smbms_user`
<trim prefix="where" prefixOverrides="and|or" >
<if test="name!=null and name!='' " >
AND userName LIKE CONCAT('%',#{name},'%')
if>
<if test="pwd!=null and pwd!='' " >
AND userPassword LIKE CONCAT('%',#{pwd},'%')
if>
<if test="address!=null and address!='' " >
AND address LIKE CONCAT('%',#{address},'%')
if>
trim>
select>
Java接口 UserMapper.java
//2.修改用户表 使用if set frim
public int upd(User u);
映射文件:UserMapper.XML
set 完成修改
<update id="upd" parameterType="User" >
UPDATE `smbms_user`
<set>
<if test="userName!=null and userName!='' " > `userName` =#{userName}, if>
<if test="userPassword!=null and userPassword!='' " > `userPassword`=#{userPassword}, if>
set>
where id= #{id}
update> -->
trim 完成修改
<update id="upd" parameterType="User">
UPDATE `smbms_user`
<trim prefix="set" suffix="where id = #{id}" suffixOverrides=",">
<if test="userName!=null and userName!='' " > `userName` =#{userName}, if>
<if test="userPassword!=null and userPassword!='' " > `userPassword`=#{userPassword}, if>
trim>
update>
Java接口 UserMapper.java
// 3.in查询用户表, 使用foreach 完成部门查询;
public List<User> chain(List<Integer> userRoles);
映射文件:UserMapper.XML
<select id="chain" parameterType="java.util.List" resultType="User" >
SELECT * FROM `smbms_user` WHERE `userRole` IN
<foreach collection="list" item="W" open="(" close=")" separator="," >
#{W}
foreach>
select>
Java接口 UserMapper.java
//5.对于某些查询需求,虽然有多个查询条件,但我们不想应用所有的条件,只选择其中一种查询结果时候可以使用:Choose;
//用户名模糊查询 | 密码模糊查询 都不符合则查全部;
public List<User> choose(@Param("name")String name,@Param("pwd")String pwd);
映射文件:UserMapper.XML
<select id="choose" resultType="User" >
SELECT * FROM `smbms_user`
<where>
<choose>
<when test="name!=null and name!='' ">
AND userName LIKE CONCAT('%',#{name},'%')
when>
<when test="pwd!=null and pwd!='' ">
AND userPassword LIKE CONCAT('%',#{pwd},'%')
when>
<otherwise>
and 1=1
otherwise>
choose>
where>
select>
运行类 DTSqlRun .Java
package com.wsm.run;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import org.apache.ibatis.session.SqlSession;
import com.wsm.mapper.UserMapper;
import com.wsm.pojo.User;
import com.wsm.utis.MyBatisUtil;
public class DTSqlRun {
static Scanner input = new Scanner(System.in);
public static void main(String[] args) {
DTSqlRun r = new DTSqlRun();
//r.cha();
//r.upd();
//r.chain();
r.choose();
}
public void cha(){
SqlSession session = MyBatisUtil.create();
UserMapper um = session.getMapper(UserMapper.class);
List<User> users = um.cha("w",null,"");
if(users.size()==0){
System.out.println("没有数据!");
}
for (User user : users) {
System.out.println(user.getId() + "\t" + user.getUserCode() + "\t" + user.getUserName() + "\t" + user.getPhone()
+ "\t" + user.getAddress());
}
MyBatisUtil.close(session);
}
public void upd(){
User u = new User();
//u.setUserName("asdsasad");
u.setUserPassword("xxasssssda");
u.setId(1);
SqlSession session = MyBatisUtil.create();
UserMapper um = session.getMapper(UserMapper.class);
if(um.upd(u)==1){
session.commit(); //手动提交;
System.out.println("修改成功");
}else{
System.out.println("修改失败");
}
MyBatisUtil.close(session);
}
public void chain(){
List<Integer> in = new ArrayList<Integer>();
in.add(1);
in.add(2);
//in.add(3);
SqlSession session = MyBatisUtil.create();
UserMapper um = session.getMapper(UserMapper.class);
List<User> users = um.chain(in);
if(users.size()==0){
System.out.println("没有数据!");
}
for (User user : users) {
System.out.println(user.getId() + "\t" + user.getUserCode() + "\t" + user.getUserName() + "\t" + user.getPhone()
+ "\t" + user.getAddress()+"\t"+user.getUserRole());
}
MyBatisUtil.close(session);
}
public void choose(){
SqlSession session = MyBatisUtil.create();
UserMapper um = session.getMapper(UserMapper.class);
List<User> users = um.choose("s","ss"); //两个参数都传了,但pwd的属性无效,因为name 成立了 就结束了;
if(users.size()==0){
System.out.println("没有数据!");
}
for (User user : users) {
System.out.println(user.getId() + "\t" + user.getUserCode() + "\t" + user.getUserName() + "\t" + user.getPhone()
+ "\t" + user.getAddress());
}
MyBatisUtil.close(session);
}
}
正如大多数框架一样,MyBatis提供了一级缓存
和 二级缓存
一级缓存
一级缓存是基于,PerpetyalCache(MyBatis 自带的), HashMap本地缓存,作用范围在 SqlSession域内. 当SqlSession关闭时,则其所有的缓存就会被清空…
二级缓存
二级缓存就是 global caching 它超出 sqlsession 范围之外, 结果可以被所有的sqlSession 共享;
开启它只需要在MyBatis 的核心配置文件( MyBatis-config.xml ) setting 中设置…
二级缓存的配置:
1.需要在MyBatis-config.xml中配置
<settings>
<setting name="logImpl" value="LOG4J" />
<setting name="autoMappingBehavior" value="FULL" />
<setting name="cacheEnabled" value="true"/>
settings>
2.在对应的Mapper.xml 文件中设置缓存,默认是没有开启缓存的;
需要注意的是:global caching 作用域针对的是 mapper 的 namespace 而言的,即只有在此 namepace 内的查询才可以共享这个 cache…
<cache eviction="FIFO" flushInterval="60000" size="512" readOnly="true"/>
3.在 mapper 文件配置支持 cache 后, 如果需要对个别查询进行调整,可以单独设置 cache 代码
这样就不需要在配置 Cache了… 方法2 和 方法3可以选一种...
<select id="cha" resultMap="RoleMap" useCache="true" >
...
select>
示例demo
//根据编号查部门及 部门员工;
public void cha(){
SqlSession session = MyBatisUtil.create();
RoleMapper rm = session.getMapper(RoleMapper.class);
//一级缓存:缓存数据存储在 sqlSession中;
Role r = rm.cha(2);
System.out.println(r.getRoleName()+"\t"+r.getId());
List<User> u = r.getUsers();
for (User user : u) {
System.out.println(user.getUserName());
}
//因此不关闭 sqlSession 在此查相同的数据不会在需要sql语句; 访问数据库;
System.out.println("------------------------------------------");
Role r1 = rm.cha(2);
System.out.println(r1.getRoleName()+"\t"+r1.getId());
//而查询没有查过的数据还是需要sql 访问数据库
System.out.println("------------------------------------------");
Role r2 = rm.cha(3);
System.out.println(r2.getRoleName()+"\t"+r2.getId());
MyBatisUtil.close(session); //关闭SqlSession
System.out.println("二级缓存");
//二级缓存: 数据存储在 sqlSessionFactory工厂中;
//需要在配置信息中设置
//MyBatis:
//xxxMapper.xml中:
//而查询时:
//即使是SqlSession 关闭对于查过的数据也会保存起来
SqlSession sessionr = MyBatisUtil.create();
RoleMapper rmr = sessionr.getMapper(RoleMapper.class);
Role rr = rmr.cha(1);
System.out.println(rr.getRoleName()+"\t"+rr.getId());
MyBatisUtil.close(sessionr); //关闭SqlSession
//上面关闭了,才用二级缓存;所以不在需要Sql 数据库操作;
SqlSession sessionr1 = MyBatisUtil.create();
RoleMapper rmr1 = sessionr1.getMapper(RoleMapper.class);
Role rr1 = rmr1.cha(1);
System.out.println(rr1.getRoleName()+"\t"+rr1.getId());
MyBatisUtil.close(sessionr1); //关闭SqlSession
}