版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/linzhaoliangyan/article/details/88658573
* 传统的使用JDBC的方法,相信大家在组合复杂的的SQL语句的时候,需要去拼接,稍不注意哪怕少了个空格,都会导致错误。Mybatis的动态SQL功能正是为了解决这种问题, 其通过 if, choose, when, otherwise, trim, where, set, foreach标签,可组合成非常灵活的SQL语句,从而提高开发人员的效率。
* 传统JDBC组合复杂的sql语句
* 动态查询
* 从多个查询条件中随机选择若干个组合成一个DQL语句进行查询,这一过程叫做动态查询。
public List<Student> getStudentsByParams(HashMap<String,Object> map){
Connection connection = null;
PreparedStatement pst = null;
ResultSet rs = null;
// 用jdbc连接数据库获取数据
try {
// 1 加载数据库驱动
Class.forName("com.mysql.jdbc.Driver");
// 2 通过驱动类获取的数据库的链接
connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/hx01?characterEncoding=utf-8",
"root", "root");
// 3 定义SQL语句
// // 关键是"where 1=1",不需要再判断追加的查询条件前是否需要添加and,统一在前面添加and
String sql = "SELECT * FROM student WHERE 1=1";
StringBuilder sb=new StringBuilder();
sb.append(sql);
if(map==null || map.size()==0){
// 没有传递参数查询所有
pst = connection.prepareStatement(sql);
}else{
for(Map.Entry<String,Object> entry:map.entrySet()){
sb.append(" and "+entry.getKey()+"=? ");
}
String sqlBuilder=sb.toString();
System.out.println(sqlBuilder);
pst = connection.prepareStatement(sqlBuilder);
int index=1;
for(Map.Entry<String,Object> entry:map.entrySet()){
pst.setObject(index,entry.getValue());
index++;
}
}
rs = pst.executeQuery();
List<Student> students=new ArrayList<Student>();
while (rs.next()) {
Student student=new Student();
student.setSid(rs.getInt(1));
student.setCno(rs.getInt(2));
student.setSname(rs.getString(3));
student.setSsex(rs.getString(4).charAt(0));
student.setSage(rs.getInt(5));
student.setColleage(rs.getString(6));
students.add(student);
}
return students;
} catch (Exception e) {
e.printStackTrace();
} finally {
// 8 释放资源
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (pst != null) {
try {
pst.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (connection != null) {
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
return null;
}
* 测试
@Test
public void test1(){
StudentDao studentDao=new StudentDao();
HashMap<String,Object> map=new HashMap<String,Object>();
// 模拟输入的条件
map.put("ssex","男");
map.put("sage","22");
map.put("colleage","物理系");
List<Student> students = studentDao.getStudentsByParams(map);
System.out.println(students);
}
* mybatis动态sql
* 使用Mybatis的动态SQL
public interface StudentMapper {
/**
* 通过动态参数查询:动态sql
* @param map
* @return
*/
public List<Student> getStudentsByParams(HashMap<String,Object> map);
}
<?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.hx.hx02.mapper.StudentMapper">
<select id="getStudentsByParams" parameterType="hashMap" resultType="com.hx.hx02.bean.Student">
SELECT * FROM student where
<if test="ssex !=null">
ssex=#{ssex}
</if> and
<if test="sage !=null">
sage=#{sage}
</if> and
<if test="colleage !=null">
colleage=#{colleage}
</if>
</select>
</mapper>
@Test
public void test7(){
SqlSession session = MyBatisUtils.getSqlSession();
StudentMapper mapper = session.getMapper(StudentMapper.class);
HashMap<String,Object> map=new HashMap<String,Object>();
// 模拟输入的条件
map.put("ssex","男");
map.put("sage","22");
map.put("colleage","物理系");
List<Student> students = mapper.getStudentsByParams(map);
System.out.println(students);
session.close();
}
假如没有ssex参数:SQL语句会变成如下
SELECT * FROM student where and sage=? and colleage=?
扫描二维码关注公众号,回复:
5596200 查看本文章
* 解决方法:使用where标签(自动处理多余的and|or)
<?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.hx.framework.dao.StudentMapper">
<select id="getStudentsByParams" parameterType="hashMap" resultType="com.hx.framework.bean.Student">
SELECT * FROM student
<where>
<if test="ssex !=null">
and ssex=#{ssex}
</if>
<if test="sage !=null">
and sage=#{sage}
</if>
<if test="colleage !=null">
and colleage=#{colleage}
</if>
</where>
</select>
</mapper>
* set 标签
/**
* 根据学生学号动态更新学生姓名,性别,年龄,学院
* @param student
*/
public void updateStudent(Student student);
UPDATE student SET sname='小小',ssex='女',sage=22,colleage='物理系' WHERE sid=100002;
<update id="updateStudent" parameterType="com.hx.hx02.bean.Student">
UPDATE student SET
<if test="sname!=null">
sname=#{sname},
</if>
<if test="ssex!=''">
ssex=#{ssex},
</if>
<if test="sage!=0">
sage=#{sage},
</if>
<if test="colleage!=null">
colleage=#{colleage}
</if>
<where>
<if test="sid !=null">
sid=#{sid}
</if>
</where>
</update>
@Test
public void test8(){
SqlSession session = MyBatisUtils.getSqlSession();
StudentMapper mapper = session.getMapper(StudentMapper.class);
Student student=new Student();
student.setSid(100002);
student.setSname("大明");
student.setSsex('男');
student.setColleage("计算机系");
student.setSage(23);
mapper.updateStudent(student);
session.commit();
session.close();
}
* 问题分析
* 当不设置colleage的时候,sage后面多个逗号
sql:
UPDATE student SET sname=?, ssex=?, sage=?, WHERE sid=?
* 解决方案使用set标签
<update id="updateStudent" parameterType="com.hx.hx02.bean.Student">
UPDATE student
<set>
<if test="sname!=null">
sname=#{sname},
</if>
<if test="ssex!=''">
ssex=#{ssex},
</if>
<if test="sage!=0">
sage=#{sage},
</if>
<if test="colleage!=null">
colleage=#{colleage}
</if>
</set>
<where>
<if test="sid !=null">
sid=#{sid}
</if>
</where>
</update>
* 易错点提醒
<if test="ssex!=null">
ssex=#{ssex},
</if>
<if test="sage!=null">
sage=#{sage},
</if>
int:0
char:''
没有设置值,不是为null
* foreach
-- 通过动态学号数组数组查询学生信息
SELECT * FROM student WHERE sid IN(100001,100002,100003);
/**
* 通过动态学号数组数组查询学生信息
* @param ids
* @return
*/
public List<Student> getStudentsByIds(int[] ids);
/**
* 通过动态学号数组数组查询学生信息
* @param ids
* @return
*/
public List<Student> getStudentsByListIds(List<Integer> ids);
<select id="getStudentsByIds" parameterType="int" resultType="com.hx.hx02.bean.Student">
SELECT * FROM student WHERE sid IN
<foreach collection="array" item="id" index="index" separator="," open="(" close=")">
${id}
</foreach>
SELECT * FROM student WHERE sid IN(100001,100002,100003);
</select>
<select id="getStudentsByListIds" parameterType="list" resultType="com.hx.hx02.bean.Student">
SELECT * FROM student WHERE sid IN
<foreach collection="list" item="id" index="index" separator="," open="(" close=")">
${id}
</foreach>
</select>
@Test
public void test9(){
SqlSession session = MyBatisUtils.getSqlSession();
StudentMapper mapper = session.getMapper(StudentMapper.class);
int[] ids={100001,100002,100003};
List<Student> students = mapper.getStudentsByIds(ids);
System.out.println(students);
session.close();
}
@Test
public void test10(){
SqlSession session = MyBatisUtils.getSqlSession();
StudentMapper mapper = session.getMapper(StudentMapper.class);
List<Integer> ids=new ArrayList<Integer>();
ids.add(100001);
ids.add(100002);
ids.add(100003);
List<Student> students = mapper.getStudentsByListIds(ids);
System.out.println(students);
session.close();
}
* choose/when
* 参考
<select id="findActiveBlogLike"
resultType="Blog">
SELECT * FROM BLOG WHERE state = ‘ACTIVE’
<choose>
<when test="title != null">
AND title like #{title}
</when>
<when test="author != null and author.name != null">
AND author_name like #{author.name}
</when>
<otherwise>
AND featured = 1
</otherwise>
</choose>
</select>