云计算百科
云计算领域专业知识百科平台

SSM框架-MyBatis3

目录

一、动态sql(接SSM框架-MyBatis2中的动态sql)

二、MyBatis的缓存机制

三、数据库中列名和pojo中的实体类不一致问题

四、多表关联查询


一、动态sql(接SSM框架-MyBatis2中的动态sql)

1.<choose><when><otherwise>标签:

(1)单条件查询(只取其一),这是一套标签,功能类似于if…else if…else if…else。

(2)这个标签需要写在<where></where>标签里面。

(3)格式:<choose><when test="条件">sql语句</when> <when test="条件">sql语句</when> <when test="条件">sql语句</when> <otherwise>sql语句</otherwise></choose>。

(4)when中取其中的一个,不会追加多个条件,如果有多个条件,只取最前面的那个,如果都不满足就不查数据了。

2.<set>标签:

(1)用于维护update语句中的set子句,功能如下:

  • 满足条件时,会自动添加set关键字;
  • 会去除set子句中多余的逗号;
  • 不满足条件时,不会生成set关键字;

(2)格式:<set> <if test="username != null and username != ''"> 要修改的列1, </if> <if test="password != null and password != ''"> 要修改的列2, </if> <if test="city != null and city != ''"> 要修改的列3 </if></set>。

(3)set标签里面可以使用if标签完成语句的添加,可以根据不同的条件添加不同的语句。

(4)如果要修改多个数据,要使用逗号隔开。

3.<bind>标签:

(1)用于对数据进行再加工,用于模糊查询,这个加工是在数据使用之前做加工的,加工完之后再去使用。

(2)格式:<bind name="要动态接收的数据名" value="对数据进行加工进行加工" />。

(3)bind标签要写在select标签里面。

4.concat函数:

(1)这个函数在mysql中是用于拼接字符串串的,要拼接多个字符串需要使用逗号分隔。

(2)格式:concat("字符串1","字符串2","字符串3")。

(3)这个函数有点像java中StringBuffer里面的append方法。

5.<foreach>标签:

(1)在一个范围中查询。

(2)用于在SQL语句中遍历集合参数,在in查询中使用。

(3)属性:

  • collection:待遍历的集合名称。
  • open:设置开始符号。
  • separator:项目分隔符。
  • close:设置结束符号。
  • item:获取到的集合中的单个数据,迭代变量。
  • 格式:select * from users where uid in<foreach collection="list" open="(" separator="," close=")" item="i"> #{i}</foreach>。

6.<sql>\\<include>标签:

(1)动态选择要查询的列。

(2)sql标签用于提取SQL语句,include标签用于引用SQL语句。

(3)格式:<sql id="s1"> uid,username</sql> <select id="selChose" resultType="Users"> select <include refid="s1"></include> from users</select>。

(4)注意:include标签是通过id去绑定sql标签的,sql标签可以有多个。

7.案例 (1)映射文件中的内容:

<?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="com.mybatis.mapper.UserMapper">
<!–通过if标签实现动态sql语句–>
<!–where 1=1 是因为我们想要使用and拼接条件,但是where语句必须出现在and前面,所以要把where消耗掉–>
<select id="selAll" resultType="Users">
select * from users where 1 = 1
<if test="uid != 0">
and uid = #{uid}
</if>
<if test="username != null and username != ''">
and username = #{username}
</if>
<if test="password != null and password != ''">
and password = #{password}
</if>
<if test="city != null and city != ''">
and city = #{city}
</if>
</select>

<!–解决where问题–>
<select id="selAll2" resultType="Users">
select * from users
<where>
<if test="uid != 0">
and uid = #{uid}
</if>
<if test="username != null and username != ''">
and username = #{username}
</if>
<if test="password != null and password != ''">
and password = #{password}
</if>
<if test="city != null and city != ''">
and city = #{city}
</if>
</where>
</select>

<select id="selBy3" resultType="Users">
select * from users
<where>
<choose>
<when test="uid != 0">
uid = #{uid}
</when>
<when test="username != null and username != ''">
username = #{username}
</when>
<otherwise>
city = #{city}
</otherwise>
</choose>
</where>
</select>

<update id="updateBy">
update users
<set>
<if test="username != null and username != ''">
username = #{username},
</if>
<if test="password != null and password != ''">
password = #{password},
</if>
<if test="city != null and city != ''">
city = #{city}
</if>
</set>
where uid = #{uid}
</update>

<!–方式一–>
<!–bind在数据使用之前做加工处理–>
<select id="selLike" resultType="Users">
<bind name="param1" value="'%' + param1 + '%'"/>
select * from users where city like #{param1}
</select>
<!–方式二 使用函数concat:有点像StringBuffer里面的append方法–>
<select id="selLike2" resultType="Users">
<bind name="param1" value="'%' + param1 + '%'"/>
select * from users where city like concat ('%',#{param1},'%')
</select>

<!–foreach标签中,拼接数据为(4,5,9)
for(Integer i : list){
i代表list集合中的每一个元素
}
–>
<select id="selIn" resultType="Users">
select * from users where uid in
<foreach collection="list" open="(" separator="," close=")" item="i">
#{i}
</foreach>
</select>

<!–根据组合来指定查询列–>
<sql id="s1">
uid,username
</sql>
<sql id="s2">
username,city
</sql>
<select id="selChose" resultType="Users">
select
<include refid="s2"></include>
from users
</select>
</mapper>

(2)接口中的内容:

package com.mybatis.mapper;

import com.mybatis.pojo.Users;

import java.util.List;

public interface UserMapper {
List<Users> selAll(Users user);

List<Users> selAll2(Users user);

List<Users> selBy3(Users user);

int updateBy(Users user);

List<Users> selLike(String city);

List<Users> selLike2(String city);

List<Users> selIn(List<Integer> list);

List<Users> selChose();
}

(3)使用:

package com.mybatis.test;

import com.mybatis.mapper.UserMapper;
import com.mybatis.pojo.Users;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;

import javax.xml.bind.annotation.XmlAnyAttribute;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

public class Demo {
SqlSession session;
UserMapper mapper;
public Demo(){
//加载application-dao.xml
String resource = "application-dao.xml";
try {
//将文件转换为流对象
InputStream resourceAsStream = Resources.getResourceAsStream(resource);
//获取SqlSessionFactory对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
//获取发送sql语句的对象
session = sqlSessionFactory.openSession();
//获取接口对象
mapper = session.getMapper(UserMapper.class);
} catch (IOException e) {
e.printStackTrace();
}
}

/**
* 查询
*/
@Test
public void selAll(){
Users u = new Users();
// u.setUid(22);
// u.setUsername("小乔");
// u.setPassword("123321");
u.setCity("江南");
List<Users> users = mapper.selAll(u);
for (Users user : users) {
System.out.println(user);
}
}

@Test
public void selAll2(){
Users u = new Users();
// u.setUid(22);
u.setUsername("小乔");
u.setPassword("123321");
// u.setCity("江南");
List<Users> users = mapper.selAll2(u);
for (Users user : users) {
System.out.println(user);
}
}

@Test
public void selBy3(){
Users u = new Users();
// u.setUid(22);
// u.setUsername("小乔");
// u.setCity("江南");
List<Users> users = mapper.selBy3(u);
for (Users user : users) {
System.out.println(user);
}
}

@Test
public void update(){
Users u = new Users();
u.setUid(26);
// u.setPassword("123");
// u.setCity("重庆");
u.setUsername("夏蝉");
int n = mapper.updateBy(u);
System.out.println(n == 1 ? "修改成功" : "修改失败");
session.commit();
}

@Test
public void like(){
// List<Users> users = mapper.selLike("江");
List<Users> users = mapper.selLike2("江");
for (Users user : users) {
System.out.println(user);
}
}

@Test
public void selIn(){
List<Integer> list = new ArrayList<>();
list.add(4);
list.add(5);
list.add(9);
List<Users> users = mapper.selIn(list);
for (Users user : users) {
System.out.println(user);
}
}

@Test
public void selChose(){
List<Users> users = mapper.selChose();
for (Users user : users) {
System.out.println(user);
}
}
}

二、MyBatis的缓存机制

1.缓存就是用户在第一次访问某些数据的时候,会将这些数据缓存到redis中,如果要再次访问这些内容,可以直接从redis中读取,而不需要在去访问数据库了。

2.redis可以看作是一个基于内存的数据库,而mysql可以看作是基于硬盘的数据库。

3.缓存的作用:

(1)缓存用于提高查询的效率。

(2)MyBatis的缓存是使用SQL标签的ID作为缓存的唯一标识的,执行相同的标签可以使用缓存,不同的标签不能使用缓存。

(3)MyBatis中有两种缓存机制,一个是一级缓存,一个是二级缓存。

4.一级缓存:

(1)默认开启线程级别的缓存,SqlSession的缓存。

(2)在一个SqlSession生命周期中有效,SqlSession关闭,缓存清空。

5.二级缓存:

(1)进程级别的缓存,SqlSessionFactory的缓存。

(2)在一个SqlSessionFactory生命周期中有效,可以在多个SqlSession生命周期中共享。

(3)默认关闭,需要使用的时候,要为某个命名空间开启二级缓存(在mapper.xml中配置<cache>):

  • 在application-dao.xml配置文件中加<setting name="cacheEnabled" value="true"/>,这个也可以不加。
  • 在mapper.xml中第一行加<cache></cache>。
  • 注意:在application-dao.xml配置文件中加的配置,现在可以不加,但是在老版本之中是需要添加的,在新版本中可以直接在mapper.xml中添加标签就可以了。

三、数据库中列名和pojo中的实体类不一致问题

1.如果查询时使用resultType属性,表示采用MyBatis的Auto-Mapping(自动映射)机制,即相同的列名和属性名会自动匹配。因此,当数据库表的列名和类的属性名不一致时,会导致查不到数据。解决该问题有两种方式:一种是列别名,一种是使用resultMap手动映射。

2.列别名:

(1)查询时,可以通过列别名的方式将列名和属性名保持一致,继续使用自动映射,从而解决该问题,但是较为麻烦。

3.resultMap手动映射:

(1)将resultType换成resultMap

  • resultMap用于自定义映射关系,可以由程序员自主制定列名和属性名的映射关系。一但使用resultMap,表示不在采用自动映射机制。

(2)在sql语句对应的标签外面加一个resultMap标签。

(3)格式:

  • resultMap标签:
  • <resultMap id="mm" type="com.mybatis.pojo.Users2">
    <id property="id" column="uid"></id>
    <result property="uname" column="username"></result>
    <result property="pwd" column="password"></result>
    <result property="cite" column="city"></result>
    </resultMap>
  • sql语句标签:
  • <select id="selAllUsers" resultMap="mm">
    select * from users
    </select>
  • 注意:
    • 这两个通过id和resultMap关联起来,其中id标签和result标签效果是一样的,id标签只是为了区分是否是主键。
    • resultMap标签中的子标签内的属性property代表的是实体的中的属性,而column属性代表的是数据库中的列名。

四、多表关联查询

1.多表关联查询在MyBatis中可以有两种方式实现:一种是关联的方式,一种是装配的方式。

2.关联实现多表查询:

(1)关联的方式就是将sql语句完整的放入映射文件中,然后动态取值查询就可以了。

3.手动装配实现多表查询(多对一):

(1)mapper层只做单表查询操作,在service层进行手动装配,实现关联查询的结果。

(2)在application中关联映射文件的时候,如果有多个映射文件,一个一个关联太麻烦了,可以使用<package>标签:

  • 格式:<package name="映射文件所在的包名.*"/>。
  • 这种方式可以关联一个包下面的所有映射文件。
  • 案例:
  • <mappers>
    <!–关联外部写有sql语句的映射文件
    <mapper resource="com/mybatis/mapper/StudentMapper.xml"/>
    <mapper resource="com/mybatis/mapper/ClazzMapper.xml"/>
    –>
    <package name="com.mybatis.mapper.*"/>
    </mappers>

(3)手动装配就是先将一个表中的数据查处理,在根据这个表中关联的外键去查询另一张表中的内容,这样两张表中的内容就都查到了。

(4)手动装配其实就是把多表查询拆分成单表查询。如果是多对一查询,就先把多的一方查出来,在用多把一查出来。如果是一对多,就先把一查出来,再去查询多。

(5)简单来说,手动装配可以理解为手动组装,把你要的多个关联起来的数据先拆分成单个数据进行查询,最后将查询的结果在手动组装起来,这个称之为业务装配。

(6)注意:这种关联查询需要我们在实体类中将数据关联起来,比如多对一,那么我们就要使用多去持有一,就像多个学生对应一个班级,那么我们就要将班级的实体类当作学生的实体类是属性。

(7)案例:

  • ClazzMapper.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="com.mybatis.mapper.ClazzMapper">
    <select id="selByCid" resultType="Clazz">
    select * from clazz where cid = #{param1}
    </select>
    </mapper>
  • ClazzMapper接口中的内容:
  • package com.mybatis.mapper;

    import com.mybatis.pojo.Clazz;

    public interface ClazzMapper {
    Clazz selByCid(int cid);
    }

  • StudentMapper.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="com.mybatis.mapper.StudentMapper">
    <select id="selAll" resultType="Student">
    select * from student
    </select>
    </mapper>
  • StudentMapper接口中的内容:
  • package com.mybatis.mapper;

    import com.mybatis.pojo.Student;

    import java.util.List;

    public interface StudentMapper {
    List<Student> selAll();
    }

  • 具体使用:
  • package com.mybatis.test;

    import com.mybatis.mapper.ClazzMapper;
    import com.mybatis.mapper.StudentMapper;
    import com.mybatis.pojo.Clazz;
    import com.mybatis.pojo.Student;
    import org.apache.ibatis.io.Resources;
    import org.apache.ibatis.session.SqlSession;
    import org.apache.ibatis.session.SqlSessionFactory;
    import org.apache.ibatis.session.SqlSessionFactoryBuilder;
    import org.junit.Test;

    import java.io.IOException;
    import java.io.InputStream;
    import java.util.List;

    public class Demo {
    SqlSession session;
    ClazzMapper clazzMapper;
    StudentMapper studentMapper;
    public Demo(){
    //加载application-dao.xml
    String resource = "application-dao.xml";
    try {
    //将文件转换为流对象
    InputStream resourceAsStream = Resources.getResourceAsStream(resource);
    //获取SqlSessionFactory对象
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
    //获取发送sql语句的对象
    session = sqlSessionFactory.openSession();
    //获取接口对象
    clazzMapper = this.session.getMapper(ClazzMapper.class);
    studentMapper = this.session.getMapper(StudentMapper.class);
    } catch (IOException e) {
    e.printStackTrace();
    }
    }

    /**
    * 查询学生及其所在的班级信息(多对一 查询)
    * 手动装配
    */
    @Test
    public void selAll(){
    List<Student> students = studentMapper.selAll();
    for (Student stu : students) {
    //学生对应的班级cid
    int cid = stu.getCid();
    //根据cid查询它所在的班级
    Clazz clazz = clazzMapper.selByCid(cid);
    stu.setClazz(clazz);
    }
    for (Student stu : students) {
    System.out.println(stu.getSid() + "-" + stu.getSname() + "-" + stu.getAge() + "-" + stu.getCid() + "-" + stu.getClazz());
    }
    }
    }

赞(0)
未经允许不得转载:网硕互联帮助中心 » SSM框架-MyBatis3
分享到: 更多 (0)

评论 抢沙发

评论前必须登录!