框架:别人写好的类和规则
MVC
ssm:spring + springMVC + mybatis
-
spring
项目中装配bean的工厂,不需要程序猿显示创建对象,核心思想是IoC,工厂帮我们new对象
-
springMVC
在项目中拦截用户的请求,分析请求去匹配对应的控制器
- mybatis
用久层框架(数据访问层),jdbc的封装,只需要配置相关的sql语句
mybatis动态sql
动态sql :if 、 choose when otherwise 、set 、foreach
mybatis多表查询
sql语句:
创建外键:alter table my_tab1 add [constraint 外键名] foreign key(外键字段名) references mytab2(主键字段名);
删除外键:alter table my_tab drop foreign key 外键名字;
多表查询:select * from student left join score on student.Num=score.Stu_id;
student: 左表 score:右表
left join :右连接(把右表放在左表的右边,其他连接类似)
student.Num=score.Stu_id : 关联字段
-
一对一
-
方式一: 连接查询
创建实体类 Student,Glass
@Setter @Getter public class Student { private Integer sid; private String sname; private Integer sage; private Glass glass; @Override public String toString() { return "Student{" + "sid=" + sid + ", sname='" + sname + '\'' + ", sage=" + sage + ", glassid=" + glass.getGlassid() + ",glassname=" + glass.getGlassname()+ '}'; } } @Setter @Getter public class Glass { private Integer glassid; private String glassname; }
创建mapper(dao 和 mapper文件)
public interface StudentDao { List<Student> selectStudents(); }
<?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.zhj.dao.StudentDao"> <select id="selectStudents" resultMap="studentsMap"> select * from student left join glass on student.glassid=glass.glassid; </select> <!--核心部分--> <resultMap id="studentsMap" type="Student"> <!--id: 唯一标识 type:类权限名称--> <id property="sid" column="sid" /> <result property="sname" column="sname"/> <result property="sage" column="sage"/> <!-- association 使用在 一对一 或 多对一的关系 代表一个学生代表一个班级 --> <association property="glass" javaType="Glass"> <id property="glassid" column="glassid" /> <result property="glassname" column="glassname" /> </association> </resultMap> </mapper>
测试
public class MyTest { public static void main(String[] args) { SqlSession sqlSession = MyBatisUtil.getSqlSession(); StudentDao dao = sqlSession.getMapper(StudentDao.class); List<Student> students = dao.selectStudents(); System.out.println(students); // 注意 如果有的字段为空会报 空指针异常 } }
-
方式二:子查询
实体类不变
创建mapper(dao 和 mapper文件)
public interface StudentDao { // List<Student> selectStudents(); List<Student> selectStudents1(); }
// 思路: 先通过 学生查询出 glassid ,再通过 glassid 查询出 glass信息,然后 通过 resultMap统一返回 <select id="selectStudents1" resultMap="studentsMap1"> select * from student </select> <select id="selectGlass" parameterType="int" resultType="com.zhj.pojo.Glass"> select * from glass where glassid = #{glassid} </select> <resultMap id="studentsMap1" type="Student"> <id property="sid" column="sid" /> <result property="sname" column="sname"/> <result property="sage" column="sage"/> <!-- property:Student中glass属性 column: 通过第一张表中查询出来的关联字段 --> <association property="glass" column="glassid" select="selectGlass"> <id property="glassid" column="glassid" /> <result property="glassname" column="glassname" /> </association> </resultMap>
如果,表中的字段名和对象名是一致的,id 、result标签是可以省略的,只有子查询可以省略
<!-- 子查询 --> <select id="selectStudents1" resultMap="studentsMap1"> select * from student </select> <select id="selectGlass" parameterType="int" resultType="com.zhj.pojo.Glass"> select * from glass where glassid = #{glassid} </select> <resultMap id="studentsMap1" type="Student"> <!-- property:Student中glass属性 column: 通过第一张表中查询出来的关联字段 --> <association property="glass" column="glassid" select="selectGlass"> </association> </resultMap>
-
-
一对多
-
方式一:连接查询
实体类
Student 实体类不变
Glass
@Setter @Getter public class Glass { private Integer glassid; private String glassname; private List<Student> studentList; @Override public String toString() { return "Glass{" + "glassid=" + glassid + ", glassname='" + glassname + '\'' + ", studentList=" + studentList + '}'; } }
创建mapper(dao 和 mapper文件)
public interface GlassDao { List<Glass> selectGlassById(Integer glassid); }
<?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.zhj.dao.GlassDao"> <select id="selectGlassById" resultMap="glassMap" parameterType="int"> select * from glass left join student on glass.glassid = student.glassid and glass.glassid = #{glassid} </select> <resultMap id="glassMap" type="com.zhj.pojo.Glass"> <id property="glassid" column="glassid"/> <result property="glassname" column="glassname"/> <collection property="studentList" ofType="Student"> <id property="sid" column="sid"/> <result property="sname" column="sname"/> <result property="sage" column="sage"/> </collection> </resultMap> </mapper>
测试
public class MyTest { public static void main(String[] args) { SqlSession sqlSession = MyBatisUtil.getSqlSession(); GlassDao sql = sqlSession.getMapper(GlassDao.class); List<Glass> glass = sql.selectGlassById(1); System.out.println(glass); } } // 注意: 如果有 字段值 为 null ,会报空指针异常
-
方式二:子查询
实体类不变(同方式一)
创建mapper(dao 和 mapper文件)
public interface GlassDao { // List<Glass> selectGlassById(Integer glassid); List<Glass> selectGlassById1(Integer glassid); }
<!-- 子查询 --> <select id="selectGlassById1" parameterType="int" resultMap="glassMap"> select * from glass where glassid = #{glassid} </select> <select id="selectStudentById" resultType="Student" parameterType="int"> select * from student where glassid = #{glassid} </select> <resultMap id="glassMap" type="com.zhj.pojo.Glass"> <id property="glassid" column="glassid" /> <result property="glassname" column="glassname" /> <collection property="studentList" column="glassid" select="selectStudentById"> <id property="sid" column="sid"/> <result property="sname" column="sname"/> <result property="sage" column="sage"/> </collection> </resultMap> </mapper>
测试
public class MyTest { public static void main(String[] args) { SqlSession sqlSession = MyBatisUtil.getSqlSession(); GlassDao sql = sqlSession.getMapper(GlassDao.class); List<Glass> glass = sql.selectGlassById1(1); System.out.println(glass); } }
-
MyBatis懒加载
所谓 懒加载 就是 按需加载
例如 : 对象模型就是一个订单中持有一个对象的引用
当查询订单信息时,在是不加载用户信息。就是延迟加载(懒加载)
什么情况下才能使用懒加载呢?
使用连接查询多表数据时,使用懒加载
mybatis默认 不是懒加载模式
- 如何配置
lazyLoadingEnable:
加载。当禁用时所有关联的对象都会即使加载
aggressiveLazyLoading:
当启用时,有延迟加载属性的对象在被调用时会完全加载任意属性。否则,每种属性会按需加载
配置 这两个属性
<!--如果要使用延迟加载,就必须配置这两个属性--> <setting name="lazyLoadingEnabled" value="true" /> <setting name="aggressiveLazyLoading" value="false" />