就是多张表进行关联,如果查询等操作不只是与一张表有关系,同时其他表也要进行操作。
表结构:
顾客表:customers 订单表:orders 员工表emps
sql语句:
SELECT c.name,o.isbn,o.price FROM customers c INNER JOIN orders o on c.id=o.customers_id;
sql语句:
select c.name,count(o.isbn) from customers c LEFT OUTER JOIN orders o on c.id=o.customers_id GROUP BY c.name;
结果:
sql语句:
SELECT c.name,count(o.isbn) from orders o RIGHT OUTER JOIN customers c on o.customers_id=c.id GROUP BY c.name;
结果:
解释:和左外连接的结果是一样的,所以说左外连接和右外连接是差不多的,只是二者以哪个表为基准不同而已。
sql语句:
SELECT user.ename AS '员工',boss.ename AS '员工对应的上级' from emps user INNER JOIN emps boss on user.mgr=boss.empno;
结果:
sql语句:
SELECT user.ename AS '员工',boss.ename AS '员工对应的上级' FROM emps user left OUTER JOIN emps boss on user.mgr=boss.empno;
结果:
sql语句:
SELECT user.ename AS '员工',boss.ename AS '员工对应的上级' FROM emps boss RIGHT OUTER JOIN emps user on user.mgr=boss.empno;
结果:
导入jar包:
asm-3.3.1.jar 、cglib-2.2.2.jar 、commons-logging-1.1.1.jar 、log4j-1.2.16.jar 、mybatis-3.1.1.jar 、mysql-connector-java-5.1.26-bin.jar
日志文件:log4j.properties
log4j.rootLogger=debug,stdout,logfile
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.SimpleLayout
log4j.appender.logfile=org.apache.log4j.FileAppender
log4j.appender.logfile.layout=org.apache.log4j.PatternLayout
log4j.appender.logfile.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %F %p %m%n
log4j.logger.com.ibatis=DEBUG
log4j.logger.com.ibatis.common.jdbc.SimpleDataSource=DEBUG
log4j.logger.com.ibatis.common.jdbc.ScriptRunner=DEBUG
log4j.logger.com.ibatis.sqlmap.engine.impl.SqlMapClientDelegate=DEBUG
log4j.logger.java.sql.Connection=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG
数据库配置文件:db.properties
mysql.driver=com.mysql.jdbc.Driver
mysql.url=jdbc:mysql://localhost:3306/relation?characterEncoding=utf-8
mysql.username=root
mysql.password=
工具类:
public class MybatisUtil {
private static ThreadLocal threadLocal =new ThreadLocal();
private static SqlSessionFactory sqlSessionFactory;
static{
try {
Reader reader =Resources.getResourceAsReader("mybatis.xml");
sqlSessionFactory =new SqlSessionFactoryBuilder().build(reader);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
throw new RuntimeException(e);
}
}
private MybatisUtil(){}
public static SqlSession getSqlSession(){
SqlSession sqlSession =threadLocal.get();
if(sqlSession ==null){
sqlSession =sqlSessionFactory.openSession();
threadLocal.set(sqlSession);
}
return sqlSession;
}
public static void closeSqlSession(){
SqlSession sqlSession =threadLocal.get();
if(sqlSession !=null){
sqlSession.close();
threadLocal.remove();
}
}
public static void main(String[] args) {
Connection conn =MybatisUtil.getSqlSession().getConnection();
System.out.println(conn !=null ?"连接成功":"连接失败");
MybatisUtil.closeSqlSession();
}
}
需求就是:查询一个学生的学号、查询一个id号对应的学生
Mybatis总配置文件:
model模型及对应的mapper:
Student:
public class Student {
private Integer id;
private String name;
private Card card;
public Student(){}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Card getCard() {
return card;
}
public void setCard(Card card) {
this.card = card;
}
@Override
public String toString() {
return "Student [id=" + id + ", name=" + name + ", card=" + card + "]";
}
}
StudentMapper.xml:
Card:
public class Card {
private Integer id;
private String num;
public Card(){}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getNum() {
return num;
}
public void setNum(String num) {
this.num = num;
}
@Override
public String toString() {
return "Card [id=" + id + ", num=" + num + "]";
}
}
CardMapper.xml:
dao实现类:
public class StudentCardDaoImpl implements IStudentCardDao{
@Override
public Student findById(Integer id) throws Exception {
SqlSession sqlSession =null;
try{
sqlSession =MybatisUtil.getSqlSession();
return sqlSession.selectOne("studentNamespace.findById", id);
}catch(Exception e){
e.printStackTrace();
throw e;
}finally{
MybatisUtil.closeSqlSession();
}
}
@Override
public Student findByName(String name) throws Exception {
SqlSession sqlSession =null;
try{
sqlSession =MybatisUtil.getSqlSession();
return sqlSession.selectOne("studentNamespace.findByName", name);
}catch(Exception e){
e.printStackTrace();
throw e;
}finally{
MybatisUtil.closeSqlSession();
}
}
public static void main(String[] args) throws Exception {
IStudentCardDao scd =new StudentCardDaoImpl();
Student stu =scd.findByName("哈哈");
System.out.println(stu);
}
}
结果:
需求:就是一个学生在哪个班级,哪个方向班级里又有哪些学生
Mybatis总配置文件:
model模型及对应的mapper
Student2类:
public class Student2 {
private Integer id;
private String name;
private Grade grade;
public Student2(){}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Grade getGrade() {
return grade;
}
public void setGrade(Grade grade) {
this.grade = grade;
}
@Override
public String toString() {
return "Student2 [id=" + id + ", name=" + name + ", grade=" + grade
+ "]";
}
}
Student2Mapper.xml:
Grade类:
public class Grade {
private Integer id;
private String name;
private List list =new ArrayList();
public Grade(){}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List getList() {
return list;
}
public void setList(List list) {
this.list = list;
}
@Override
public String toString() {
return "Grade [id=" + id + ", name=" + name + ", list=" + list + "]";
}
}
GradeMapper.xml:
dao实现类:
public class StudentGradeDaoImpl implements IStudentGradeDao{
/*功能:查询学软件工程的人有哪些
* name表示学科名*/
@Override
public List findAllByName(String name) throws Exception {
SqlSession sqlSession =null;
try{
sqlSession =MybatisUtil.getSqlSession();
return sqlSession.selectList("studentNamespace.findAllByName", name);
}catch(Exception e){
e.printStackTrace();
throw e;
}finally{
MybatisUtil.closeSqlSession();
}
}
/*
* 查询张三是属于哪个方向的
*
* */
public Grade findGradeByName(String name) throws Exception{
SqlSession sqlSession =null;
try{
sqlSession =MybatisUtil.getSqlSession();
return sqlSession.selectOne("gradeNamespace.findGradeByName", name);
}catch(Exception e){
e.printStackTrace();
throw e;
}finally{
MybatisUtil.closeSqlSession();
}
}
public static void main(String[] args) throws Exception {
IStudentGradeDao sgd =new StudentGradeDaoImpl();
// List list =sgd.findAllByName("软件工程");
// for(Student2 student2 :list){
// System.out.println(student2);
// }
Grade grade =sgd.findGradeByName("张三");
System.out.println(grade);
}
}
需求:一个学生选修了多个课程、一个课程被多个学生选修了。
Mybatis总配置文件:
Student3类:
public class Student3 {
private Integer id;
private String name;
private List courseList =new ArrayList();
public Student3(){}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List getCourseList() {
return courseList;
}
public void setCourseList(List courseList) {
this.courseList = courseList;
}
@Override
public String toString() {
return "Student3 [id=" + id + ", name=" + name + ", courseList="
+ courseList + "]";
}
}
Student3Mapper.xml:
Course类:
public class Course {
private Integer id;
private String name;
private List student3List =new ArrayList();
public Course(){}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List getStudent3List() {
return student3List;
}
public void setStudent3List(List student3List) {
this.student3List = student3List;
}
@Override
public String toString() {
return "Course [id=" + id + ", name=" + name + ", student3List="
+ student3List + "]";
}
}
CourseMapper.xml:
dao实现类:
public class StudentCourseDaoImpl implements IStudentCourseDao{
public static void main(String[] args) throws Exception {
IStudentCourseDao scd =new StudentCourseDaoImpl();
// List list =scd.findCourseByName("张三");
// for(Course course :list){
// System.out.println(course);
// }
List list =scd.findStudent3ByName("软件工程");
for(Student3 student3 :list){
System.out.println(student3);
}
}
//通过学生名,查看其选学了哪些课程
@Override
public List findCourseByName(String name) throws Exception {
SqlSession sqlSession =null;
try{
sqlSession =MybatisUtil.getSqlSession();
return sqlSession.selectList("courseNamespace.findCourseByName",name);
}catch(Exception e){
e.printStackTrace();
throw e;
}finally{
MybatisUtil.closeSqlSession();
}
}
//通过课程名,查看有哪些学生选择学习该课程
@Override
public List findStudent3ByName(String name) throws Exception {
SqlSession sqlSession =null;
try{
sqlSession =MybatisUtil.getSqlSession();
return sqlSession.selectList("studentNamespace.findStudent3ByName", name);
}catch(Exception e){
e.printStackTrace();
throw e;
}finally{
MybatisUtil.closeSqlSession();
}
}
}
结果:
解释:
多对多其实就是将两个表之间再创建一个中间转换表,现在就三个表,让两个表与中间表形成一对多的关系,多对多就可以转化为两个一对多的关系了。