首发于我的博客 和尚的博客
本文讲解,用接口代理模式实现mybatis的模糊查询,讲解#{}和${}两个的区别,XML文件中五个特殊字符串不允许使用,小于号的解决问题。
源码获取github
传统模式:在笔记(二)就是采用的这个模式:
接口代理模式:本笔记之后所有采用这个模式:
只需要写接口,在测试类中调用,接口编程: 什么是接口? 简单理解:接口就是定义规范
接口返回类型跟你设置的resultMap或者resultType对应上即可,但是会根据你返回的类型完成selectone或者selectList操作
接口里方法如何写:sql语句返回的结果集类型 sql语句的id(要传的值);
List为SQL语句返回的结果集类型,getSkillLike02为映射文件中SQL语句的id,String name是传给映射文件的值
映射文件命名空间为接口的全路径
可以根据接口的返回类型自动判断使用selectOne还是selectList
方法一:用了转义字符把>和<替换掉,然后就没有问题了。
附:XML转义字符
方法二:
因为这个是xml格式的,所以不允许出现类似“>”这样的字符,但是都可以使用
jdbc.properties
jdbc.mysql.driver=com.mysql.jdbc.Driver
jdbc.mysql.url=jdbc:mysql://localhost:3306/cy42_mss
jdbc.mysql.username=root
jdbc.mysql.password=root
mybatis-config.xml
<configuration>
<properties resource="jdbc.properties"/>
<typeAliases>
<package name="com.hs.model"/>
typeAliases>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="${jdbc.mysql.driver}" />
<property name="url" value="${jdbc.mysql.url}" />
<property name="username" value="${jdbc.mysql.username}" />
<property name="password" value="${jdbc.mysql.password}" />
dataSource>
environment>
environments>
<mappers>
<mapper resource="com/hs/model/SkillMapper.xml"/>
mappers>
configuration>
SkillDao.java
package com.hs.dao;
/**
* 接口代理模式实现操作,在xxDao接口中,定义方法: sql语句返回的结果类型 sql语句的id(要传的值);
* 不用写实现类,直接写测试类,具体实现见测试类
* sql的映射文件的命名空间跟接口的全路径一致
* 可以根据接口的返回类型自动判断使用selectOne还是selectList eg:返回的是一个对象的为one,返回的是list的就是list,如果是List,也是list
*/
import com.hs.model.Skill;
import java.util.List;
import java.util.Map;
public interface SkillDao {
List getSkillLike01();
List getSkillLike02(String name);
List getSkillLike03(String name);
List getSkillLike04(Map map);
List getSkillLike05(Map map);
}
Skill.java
package com.hs.model;
public class Skill {
private Integer skillid;
private String skillname;
private Integer num;
public Integer getSkillid() {
return skillid;
}
public void setSkillid(Integer skillid) {
this.skillid = skillid;
}
public String getSkillname() {
return skillname;
}
public void setSkillname(String skillname) {
this.skillname = skillname;
}
public Integer getNum() {
return num;
}
public void setNum(Integer num) {
this.num = num;
}
@Override
public String toString() {
return "Skill{" +
"skillid=" + skillid +
", skillname='" + skillname + '\'' +
", num=" + num +
'}';
}
}
SkillMapper.xml
<mapper namespace="com.hs.dao.SkillDao">
<resultMap id="BaseResultMap" type="com.hs.model.Skill">
<id column="skill_id" property="skillid"/>
<result column="skill_name" property="skillname"/>
<result column="num" property="num"/>
resultMap>
<select id="getSkillLike01" resultMap="BaseResultMap">
select skill_id,skill_name,num from skill where skill_name like '%s%'
select>
<select id="getSkillLike02" parameterType="string" resultMap="BaseResultMap">
select skill_id,skill_name,num from skill where skill_name like #{name}
select>
<select id="getSkillLike03" parameterType="string" resultMap="BaseResultMap">
select skill_id,skill_name,num from skill where skill_name like concat('%',#{name},'%')
select>
<select id="getSkillLike04" parameterType="map" resultMap="BaseResultMap">
select skill_id,skill_name,num from skill where skill_name like concat('%','${name}','%')
select>
<select id="getSkillLike05" parameterType="map" resultMap="BaseResultMap">
select * from skill order by skill_id ${fs}
select>
mapper>
MyBatis.java
package com.hs.util;
/**
* 知识点:
* final修饰类:不能被继承
* 修饰方法:不能被重写
* 修饰变量:常量不可用变,但如果是对象,对象里的值可以变
*
*/
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 java.io.IOException;
import java.io.InputStream;
public class MyBatisUtils {
private MyBatisUtils() { } //不允许实例化
private static final String PATH = "mybatis-config.xml";
private static InputStream inputStream;
private static SqlSessionFactory sqlSessionFactory;
static { //1.静态代码块,只是加载一次
try {
inputStream = Resources.getResourceAsStream(PATH);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException("加载核心配置文件失败");
}
}
public static SqlSession getSqlsession() {
return sqlSessionFactory.openSession();
}
public static void closeSqlSession(SqlSession sqlSession) {
if (sqlSession != null) {
sqlSession.close();
}
}
}
log4j.properties
# 日志配置文件Global logging configuration
log4j.rootLogger=ERROR, stdout
# MyBatis logging configuration...
# 如果要显示SQL语句,那么这个位置需要配置为命名空间log4j.logger.命名空间
log4j.logger.com.hs.dao.SkillDao=TRACE
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
MyBatis.java
package com.hs.test;
import com.hs.dao.SkillDao;
import com.hs.util.MyBatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import java.util.HashMap;
import java.util.Map;
/**
* 接口代理模式实现操作,在xxDao接口中,定义方法: sql语句返回的结果类型 sql语句的id(要传的值);
* 不用写实现类,直接写测试类,具体实现见测试类
* sql的映射文件的命名空间跟接口的全路径一致
* 可以根据接口的返回类型自动判断使用selectOne还是selectList eg:返回的是一个对象的为one,返回的是list的就是list,如果是List,也是list
*/
public class MyBatisTest {
/**
* 1.模糊条件查询是固定的,写死在sql语句里了
*/
@Test
public void getSkillLike01() {
SqlSession sqlSession = null;
try {
sqlSession = MyBatisUtils.getSqlsession();
// 根据xml映射文件,接口创建实现类代理 有点类似传统模式的new UserMapperImpl()
SkillDao skillDao = sqlSession.getMapper(SkillDao.class);
System.out.println(skillDao.getSkillLike01());
} finally {
MyBatisUtils.closeSqlSession(sqlSession);
}
}
/**
* 2.通过java代码拼接字符串进行模糊查询
*/
@Test
public void getSkillLike02() {
SqlSession sqlSession = null;
try {
sqlSession = MyBatisUtils.getSqlsession();
String name = "%a%";
SkillDao skillDao = sqlSession.getMapper(SkillDao.class);
System.out.println(skillDao.getSkillLike02(name));
} finally {
MyBatisUtils.closeSqlSession(sqlSession);
}
}
/**
* 3.通过sql语句函数拼接字符串进行模糊查询
*/
@Test
public void getSkillLike03() {
SqlSession sqlSession = null;
try {
sqlSession = MyBatisUtils.getSqlsession();
String name = "s";
SkillDao skillDao = sqlSession.getMapper(SkillDao.class);
System.out.println(skillDao.getSkillLike03(name));
} finally {
MyBatisUtils.closeSqlSession(sqlSession);
}
}
/**
* 4.通过${}拼接字符串进行模糊查询
*/
@Test
public void getSkillLike04() {
SqlSession sqlSession = null;
try {
sqlSession = MyBatisUtils.getSqlsession();
Map map = new HashMap();
map.put("name", "s");
SkillDao skillDao = sqlSession.getMapper(SkillDao.class);
System.out.println(skillDao.getSkillLike04(map));
} finally {
MyBatisUtils.closeSqlSession(sqlSession);
}
}
/**
* 4.通过${}进行排序操作
*/
@Test
public void getSkillLike05() {
SqlSession sqlSession = null;
try {
sqlSession = MyBatisUtils.getSqlsession();
Map map = new HashMap();
map.put("fs", "DESC");
SkillDao skillDao = sqlSession.getMapper(SkillDao.class);
System.out.println(skillDao.getSkillLike05(map));
} finally {
MyBatisUtils.closeSqlSession(sqlSession);
}
}
}