mybatis02
1.mybatis配置文件
mybatis文件配置属性
配置属性的顺序不能颠倒,必须从上到下
2.mybatis事务
mybatis在创建sqlSession对象,调用openSession()方法时,会自动开启事务,关闭自动提交。
如果sqlSession执行增、删、改的操作时,需要手动提交事务。
在我们执行openSession方法时传入true,可以自动提交。
sqlSessionFactory接口提供的方法:
调用第二个方法
sqlSession = sqlSessionFactory.openSession(true);
3.mybatis的动态sql语句
3.1 <if 标签
if 标签中可以进行判断,为true自动添加标签内的代码,因此我们可以进行模糊查询的sql拼接,方法中传入的参数为一个对象,通过判断对象的属性是否为空,进行相应的模糊查询或者精准查询
<!--如果 <if test="name !=null and name!=''"> name 不是null 或者 空串 进行sql 连接
where 1=1 作用就是 当条件成立时 where 后面不能直接跟 and 需要在and前 加 true 或者 1=1-->
<select id="findStudentByNameAndSex" resultType="Student">
select id,name,age,sex,height,s_address from student_tb where 1=1
<if test="name !=null and name!=''">
and name like #{name}
</if>
<if test="sex !=null and sex!=''">
and sex = #{sex}
</if>
</select>
3.2 <where 标签
where 标签的作用就是讲内部的if进行拼接,并在sql增加where的字段,如果其中第一个 if 成立,会删除and,并进行拼接
<!-- where 标签作用就是 将 内部的 if进行拼接 并且 在sql增加 where 字段 ,删除 where 后的and ,where标签所有的if 都不成立则 不添加where -->
<select id="findStudentByNameAndSex" resultType="Student">
select id,name,age,sex,height,s_address from student_tb
<where>
<if test="name !=null and name!=''">
and name like #{name}
</if>
<if test="sex !=null and sex!=''">
and sex = #{sex}
</if>
</where>
</select>
3.3 <foreach 标签
foreach标签可以进行循环遍历,可以遍历数组,集合
- collection:为接受ids的变量名
- open:表示以什么字段开始
- close:表示以什么字段结束
- item:为遍历集合中的元素
- separator:为切分集合到的标记
3.3.1 遍历数组
<!-- collection:传入的是数组就填array 如果是集合就是list ;open:拼接sql的起始语句 ;separator:分隔符为逗号, ; close:结束的语句; if中的test为判断条件数组的长度大于零
-->
<select id="getStudentByIds" resultType="Student">
select * from student
<where>
<if test="array.length>0">
<foreach collection="array" open="id in (" separator="," close=")" item="id">
#{id}
</foreach>
</if>
</where>
</select>
/** dao层的方法
* 遍历数组查询学生表,传入学生ID的数组
*/
List<Student> getStudentByIds(int[] ids);
//测试:
List<Student> studentList = studentDao.getStudentByIds(new int[]{
1, 2});
for (Student stu:studentList) {
System.out.println(stu);
}
3.3.2遍历集合
<select id="getStudentByIds" resultType="Student">
select * from student
<where>
<if test="list.size()>0">
<foreach collection="list" open="id in (" separator="," close=")" item="id">
#{id}
</foreach>
</if>
</where>
</select>
/** dao层方法
* 遍历集合查询学生表,传入学生ID的集合
*/
List<Student> getStudentByIds(List<Integer> ids);
//测试:
List<Integer> ids = new ArrayList<Integer>();
ids.add(1);
ids.add(2);
List<Student> studentList = studentDao.getStudentByIds(ids);
for (Student stu:studentList) {
System.out.println(stu);
}
3.4 <sql 标签
在xml配置我们可以通过完成语句的声明,通过 标签进行应用拼接
<sql id="findAllStudentsql">
select * from student
</sql>
<select id="findAllStudent" resultType="com.yth.entity.Student">
<include refid="findAllStudentsql"></include> where id >1
</select>
4.mybatis的多表查询
4.1一对一查询
通过两张表关联查出所需要的信息,学生表与分数表之间使用学生的id进行关联
一个成绩对应的一个学生为一对一
一个学生对应的多门课程成绩为一对多
4.1.1查询关联的sql语句
查询成绩表对应的相关学生
select * from score a , student b where a.s_id = b.id;
4.1.2添加实体类Score,并添加Student属性
package com.yth.entity;
import java.io.Serializable;
public class Score implements Serializable {
private int scoreid;
private String coursename;
private int score;
private int sid;
private Student student;
public int getScoreid() {
return scoreid;
}
public void setScoreid(int scoreid) {
this.scoreid = scoreid;
}
public String getCoursename() {
return coursename;
}
public void setCoursename(String coursename) {
this.coursename = coursename;
}
public int getScore() {
return score;
}
public void setScore(int score) {
this.score = score;
}
public int getSid() {
return sid;
}
public void setSid(int sid) {
this.sid = sid;
}
public Student getStudent() {
return student;
}
public void setStudent(Student student) {
this.student = student;
}
@Override
public String toString() {
return "Score{" +
"scoreid=" + scoreid +
", coursename='" + coursename + '\'' +
", score=" + score +
", sid=" + sid +
", student=" + student +
'}';
}
}
4.1.3编写业务实现
dao层
/**
* 一对一联表查询,查询所有成绩并包含学生信息
*/
List<Score> getAllScore();
xml文件
定义 resultType 来接受getAllScore 查询结果
一对一查询
association 解决一对一问题
property=“student” 对应Score 中 student属性,也就是实体类的属性名
column=“studentid” 对应Score_tb 与 student关联的外键 列名,也就是数据库表中的字段名
javaType=“Student” 将其他非Score 中的字段写入Student 类
写入student对应的属性
<resultMap id="ScoreWithStudentMap" type="Score">
<id property="scoreid" column="scoreid"></id>
<result property="coursename" column="coursename"></result>
<result property="score" column="score"></result>
<association property="student" column="s_id" javaType="Student">
<id property="id" column="id"></id>
<result property="name" column="name"></result>
<result property="sex" column="sex"></result>
<result property="age" column="age"></result>
<result property="height" column="height"></result>
</association>
</resultMap>
<select id="getAllScore" resultMap="ScoreWithStudentMap">
select *
from score a , student b
where a.s_id = b.id;
</select>
测试:
//一对一联表查询
@org.junit.Test
public void Test8(){
List<Score> ScoreList = studentDao.getAllScore();
for (Score score:ScoreList) {
System.out.println(score);
}
}
4.2一对多查询
查询所有学生,并关联学生的每门科目的成绩
4.2.1 sql语句
4.2.2修改Student实体类
在Student实体类中添加List scoreList属性;并添加相应的set,get方法,修改toString方法
4.2.3 编写业务实现
dao层
/** dao层方法
* 一对多联表查询
*/
List<Student> getAllStudent2();
xml文件
<resultMap id="StudentWithScoreMap" type="Student">
<id property="id" column="id"></id>
<result property="name" column="name"></result>
<result property="sex" column="sex"></result>
<result property="age" column="age"></result>
<result property="height" column="height"></result>
<collection property="scoreList" ofType="Score">
<id property="scoreid" column="scoreid"></id>
<result property="coursename" column="coursename"></result>
<result property="score" column="score"></result>
</collection>
</resultMap>
<select id="getAllStudent2" resultMap="StudentWithScoreMap">
select *
from student a left join score b
on a.id = b.s_id;
</select>
测试
//一对多联表查询
@org.junit.Test
public void Test9(){
List<Student> studentList = studentDao.getAllStudent2();
for (Student stu:studentList) {
System.out.println(stu);
}
}
4.3多对多查询
业务需求:查找查询所有角色,并包含学生信息
4.3.1role实体类创建
package com.yth.entity;
import java.util.List;
public class Role {
private String rolename;
private int roleid;
private List<Student> studentsList;
public String getRolename() {
return rolename;
}
public void setRolename(String rolename) {
this.rolename = rolename;
}
public int getRoleid() {
return roleid;
}
public void setRoleid(int roleid) {
this.roleid = roleid;
}
public List<Student> getStudentsList() {
return studentsList;
}
public void setStudentsList(List<Student> studentsList) {
this.studentsList = studentsList;
}
@Override
public String toString() {
return "Role{" +
"rolename='" + rolename + '\'' +
", roleid=" + roleid +
", studentsList=" + studentsList +
'}';
}
}
4.3.2sql语句
4.3.3编写业务实现
dao层
/**
* 查询所有角色 并包含学生列表
* @return
*/
List<Role> getAllRoleWithStudent();
xml文件
<resultMap id="roleWithStudent" type="Role">
<id property="roleid" column="roleid"></id>
<result property="rolename" column="rolename"></result>
<collection property="studentsList" column="studentid" ofType="Student">
<id column="id" property="id"></id>
<result property="name" column="name"></result>
<result property="age" column="age"></result>
<result property="sex" column="sex"></result>
<result property="height" column="height"></result>
</collection>
</resultMap>
<select id="getAllRoleWithStudent" resultMap="roleWithStudent">
SELECT r.*,sr.s_id,s.* FROM role r LEFT JOIN student_role sr
ON r.roleid = sr.roleid LEFT JOIN student s ON sr.s_id = s.id;
</select>
测试
//多对多
List<Role> roleList = roleDao.getAllRoleWithStudent();
for (Role role:roleList) {
System.out.println(role);
}
4.4测试
实现多对多的查询
查询一个学生下的所有角色???
问题:
- 目前都是在java的基础工程写的项目,在web工程中每次都会创建sqlSession对象来获取dao层的实现对象来调用方法,如何解决代码冗余问题
- mybaties为我们提供了事务的功能,在本文中我们在创建sqlSession直接设置了自动提交事务,如果不设置自动提交,我们应该如何做
在下一篇文章中我们将书写sqlSession的工具类以及利用动态代理实现事务处理器