Mybatis 对象关系映射 框架
(ORM Object(对象) relation(关系) Mapping(映射)) 框架
class Dept{
private String dName;//部门名称
private List<Emp> emps;// 关系 一对多
}
//查询 ID 为 2 的 部门
Dept dept = mybatis.getDeptByDid(deptId);
jdbc 用法:
//查询 ID 为2 的部门 的 所有员工股
List<emp> emps =mybatis.getEmpByDid(deptID);
dept.setEmps(emps);
// 获取所有的员工 ORM 关系
List<emp> emps = dept.emps;
导入 jar 包
核心配置文件 sqlMapConfig.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- 1.数据源 -->
<!-- 2.事务控制 -->
<!-- 配置一个开发环境,可以配置多个,在具体用时切换 -->
<environments default="test">
<environment id="test"><!-- 测试环境 -->
<transactionManager type="JDBC"></transactionManager><!-- 事务管理 JDBC/MANAGED -->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/mybatisdb?characterEncoding=utf-8" />
<property name="username" value="root" />
<property name="password" value="root" />
</dataSource><!-- 数据源 POOLED/UNPOOLED/JNDI -->
</environment>
</environments>
<!-- 加载映射文件 mapper -->
<mappers>
<mapper resource="cn/albin/mapper/PersonMapper.xml"/>
</mappers>
</configuration>
实体映射文件
<?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="cn.albin.mapper.UserMapper"> <!-- 命名空间,可以随意些,只要不冲突 -->
<insert id="insert" parameterType="cn.albin.Person">
INSERT INTO person (id,username,age) VALUES(#{id},#{userName},#{age})
</insert>
<!-- 修改 -->
<update id="update" parameterType="cn.albin.Person">
UPDATE person set user_name=#{userName},age=#{age}
WHERE id=#{id}
</update>
</mapper>
使用步骤
//操作步骤
//1.加载sqlMapConfig.xml文件
InputStream inputStream = App.class.getClassLoader().getResourceAsStream("sqlMapConfig.xml");
SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//2.获取 sqlSession对象
SqlSession session = sessionFactory.openSession();
//调用插入方法 mapper配置文件的 命名空间+动作标签 id 名称
session.insert("com.mapper.BankMapper.insert");
//提交事务
session.commit();
session.close();//关闭数据连接 conntion.close();
MyBaties核心配置文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- 加载类路径下的属性文件 -->
<properties resource="db.properties"/>
<!-- 设置类型别名 -->
<typeAliases>
<typeAlias type="cn.albin.javaee.mybatis.app04.Student" alias="student"/>
</typeAliases>
<!-- 设置一个默认的连接环境信息 -->
<environments default="mysql_developer">
<!-- 连接环境信息,取一个任意唯一的名字 -->
<environment id="mysql_developer">
<!-- mybatis使用jdbc事务管理方式 -->
<transactionManager type="jdbc"/>
<!-- mybatis使用连接池方式来获取连接 -->
<dataSource type="pooled">
<!-- 配置与数据库交互的4个必要属性 -->
<property name="driver" value="${mysql.driver}"/>
<property name="url" value="${mysql.url}"/>
<property name="username" value="${mysql.username}"/>
<property name="password" value="${mysql.password}"/>
</dataSource>
</environment>
<!-- 连接环境信息,取一个任意唯一的名字 -->
<environment id="oracle_developer">
<!-- mybatis使用jdbc事务管理方式 -->
<transactionManager type="jdbc"/>
<!-- mybatis使用连接池方式来获取连接 -->
<dataSource type="pooled">
<!-- 配置与数据库交互的4个必要属性 -->
<property name="driver" value="${oracle.driver}"/>
<property name="url" value="${oracle.url}"/>
<property name="username" value="${oracle.username}"/>
<property name="password" value="${oracle.password}"/>
</dataSource>
</environment>
</environments>
<!-- 加载映射文件-->
<mappers>
<mapper resource="cn/albin/javaee/mybatis/app04/StudentMapper.xml"/>
</mappers>
</configuration>
实体Mapper配置文件
Insert 标签详解
<?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">
<!-- namespace属性是名称空间,必须唯一 cn.albin.javaee.mybatis.app04.Student -->
<mapper namespace="cn.albin.javaee.mybatis.app04.Student">
<!--
insert标签:要书写insert这么一个sql语句
id属性:为insert这么一个sql语句取一个任意唯一的名字
parameterType:要执行的dao中的方法的参数,如果是类的话,必须使用全路径类
-->
<insert id="add" parameterType="student">
insert into students(id,name,sal) values(#{id},#{name},#{sal})
</insert>
</mapper>
-
API
sqlSession.insert(Student.class.getName()+".add",student);
Insert 标签详解
<?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">
<!-- namespace属性是名称空间,必须唯一 cn.albin.javaee.mybatis.app04.Student -->
<mapper namespace="cn.albin.javaee.mybatis.app04.Student">
<!-- resultMap标签:映射实体与表
type属性:表示实体全路径名
id属性:为实体与表的映射取一个任意的唯一的名字
-->
<resultMap type="student" id="studentMap">
<!-- id标签:映射主键属性
result标签:映射非主键属性
property属性:实体的属性名
column属性:表的字段名
-->
<id property="id" column="id"/>
<result property="name" column="name"/>
<result property="sal" column="sal"/>
</resultMap>
<!-- 根据ID查询学生
如果参数不是一个实体的话,只是一个普通变量,例如:int,double,String
这里的#{中间的变量名可以随便写},不过提倡就用方法的形参
-->
<select id="findById" parameterType="int" resultType="cn.albin.javaee.mybatis.app09.Student">
select id,name,sal from students where id = #{id}
</select>
<!-- 查询所有学生
理论上resultType要写List<Student>
但这里只需书写List中的类型即可,即只需书写Student的全路径名
-->
<select id="findAll" resultType="cn.albin.javaee.mybatis.app09.Student">
select id,name,sal from students
</select>
</mapper>
-
API
sqlSession.selectOne(Student.class.getName()+".findById",id); sqlSession.selectList(Student.class.getName()+".findAll");
Select 标签详解
- 查询所有记录 属性与字段匹配
-
<!-- 查询一条记录 数据库的字段名 与 实体属性名字 不一样情况 ? resultMap: 查询结果的返回 自定义 resultMap --> <select id="getBankResultTypeById" resultMap="BankResultMap"> select * from tb_bank where id=75 </select>
-
查询所有记录 属性与字段不匹配
<!-- resultMap标签:映射实体与表 type属性:表示实体全路径名 id属性:为实体与表的映射取一个任意的唯一的名字 --> <resultMap type="student" id="studentMap"> <!-- id标签:映射主键属性 result标签:映射非主键属性 property属性:实体的属性名 column属性:表的字段名 --> <id property="id" column="id"/> <result property="name" column="name"/> <result property="sal" column="sal"/> </resultMap> <!-- 查询所有记录 数据库的字段名 与 实体属性名字 不一样情况 ? resultMap: 查询结果的返回 自定义 resultMap --> <select id="getAllBankResult" resultMap="BankResultMap"> select * from tb_bank </select>
-
分页
<select id="findAllWithFy" parameterType="map" resultMap="studentMap"> select students_id,students_name,students_sal from students limit #{pstart},#{psize} </select>
-
API
Map<String,Object> map = new LinkedHashMap<String,Object>(); map.put("pstart",start); map.put("psize",size); sqlSession.selectList(Student.class.getName()+".findAllWithFy",map);
-
优化: 工具类
private static SqlSessionFactory sqlSessionFactory;
/**
* 加载位于src/mybatis.xml配置文件
*/
static{
try {
sqlSessionFactory = new SqlSessionFactoryBuilder().build(MybatisUtil1.class.getResourceAsStream("/mybatis.xml"));
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
/**
* 禁止外界通过new方法创建
*/
private MybatisUtil1(){}
/**
* 获取SqlSession
*/
public static SqlSession getSqlSession(){
//返回SqlSession对象
return sqlSessionFactory.openSession();
}
动态SQL操作之查
<resultMap type="cn.albin.javaee.mybatis.app11.Student" id="studentMap">
<id property="id" column="students_id"/>
<result property="name" column="students_name"/>
<result property="sal" column="students_sal"/>
</resultMap>
<select id="findAll" parameterType="map" resultMap="studentMap">
select * from students
<where>
<if test="pid!=null">
and students_id = #{pid}
</if>
<if test="pname!=null">
and students_name = #{pname}
</if>
<if test="psal!=null">
and students_sal = #{psal}
</if>
</where>
</select>
动态SQL操作之更新
<resultMap type="cn.albin.javaee.mybatis.app12.Student" id="studentMap">
<id property="id" column="students_id"/>
<result property="name" column="students_name"/>
<result property="sal" column="students_sal"/>
</resultMap>
<!-- set标签自动判断哪个是最后一个字段,会自动去掉最后一个,号 -->
<update id="dynaUpdate" parameterType="map">
update students
<set>
<if test="pname!=null">
students_name = #{pname},
</if>
<if test="psal!=null">
students_sal = #{psal},
</if>
</set>
where students_id = #{pid}
</update>
动态SQL操作之删除
<resultMap type="cn.albin.javaee.mybatis.app13.Student" id="studentMap">
<id property="id" column="students_id"/>
<result property="name" column="students_name"/>
<result property="sal" column="students_sal"/>
</resultMap>
<delete id="dynaDeleteArray">
delete from students where students_id in
<!-- foreach用于迭代数组元素
open表示开始符号
close表示结束符合
separator表示元素间的分隔符
item表示迭代的数组,属性值可以任意,但提倡与方法的数组名相同
#{ids}表示数组中的每个元素值
-->
<foreach collection="array" open="(" close=")" separator="," item="ids">
#{ids}
</foreach>
</delete>
<delete id="dynaDeleteList">
delete from students where students_id in
<foreach collection="list" open="(" close=")" separator="," item="ids">
#{ids}
</foreach>
</delete>
动态SQL操作之插入
<resultMap type="cn.albin.javaee.mybatis.app14.Student" id="studentMap">
<id property="id" column="students_id"/>
<result property="name" column="students_name"/>
<result property="sal" column="students_sal"/>
</resultMap>
<!-- sql片段对应字段名,id属性值任意
Students stu = new Students();
stu.setId(1);
stu.setName("张三")
insert students ( udents_id,students_name)
-->
<sql id="key">
<!-- 去掉最后一个, -->
<trim suffixOverrides=",">
<if test="id!=null">
students_id,
</if>
<if test="name!=null">
students_name,
</if>
<if test="sal!=null">
students_sal,
</if>
</trim>
</sql>
<!-- sql片段对应?,id属性值任意
Students stu = new Students();
stu.setId(1);
stu.setName("张三")
values (#{id},#{name})
-->
<sql id="value">
<!-- 去掉最后一个, -->
<trim suffixOverrides=",">
<if test="id!=null">
#{id},
</if>
<if test="name!=null">
#{name},
</if>
<if test="sal!=null">
#{sal},
</if>
</trim>
</sql>
<!-- <include refid="key"/>和<include refid="value"/>表示引用上面定义的sql片段 -->
<insert id="dynaInsert" parameterType="cn.albin.javaee.mybatis.app14.Student">
insert into students(<include refid="key"/>) values(<include refid="value"/>)
</insert>
一对多关系映射 班级和学生
-
班级类
public class Grade { private Integer id; private String name; //一对多的多(学生)的一方 private List<Student> studentList = new ArrayList<Student>();//关联属性 }
-
学生类
public class Student { private Integer id; private String name; //多对一(班级) private Grade grade;//关联属性 }
-
班级映射
<?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="gradeNamespace"> <resultMap type="cn.albin.javaee.mybatis.one2many.Grade" id="gradeMap"> <id property="id" column="gid"/> <result property="name" column="gname"/> <!-- 多的一方配置 --> <collection property="studentList" resultMap="studentNamespace.studentMap"/> </resultMap> <!-- 查询哈哈是哪个学科的 --> <select id="findByName" parameterType="string" resultMap="gradeMap"> select g.gid,g.gname,s.sid,s.sname from grades g,students s where g.gid = s.sgid and s.sname = #{name} </select> </mapper>
-
学生映射
<?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="studentNamespace"> <resultMap type="cn.albin.javaee.mybatis.one2many.Student" id="studentMap"> <id property="id" column="sid"/> <result property="name" column="sname"/> <association property="grade" resultMap="gradeNamespace.gradeMap"/> </resultMap> <!-- 查询java学科有哪些学生信息 --> <select id="findAllByName" parameterType="string" resultMap="studentMap"> select s.sid,s.sname,g.gid,g.gname from grades g,students s where g.gid = s.sgid and g.gname = #{name} </select> </mapper>
多对多关联 学生和课程
-
课程类
public class Course { private Integer id; private String name; //多对多 private List<Student> studentList = new ArrayList<Student>();//关联属性 }
-
学生类
public class Student { private Integer id; private String name; //多对多 private List<Course> courseList = new ArrayList<Course>();//关联属性 }
-
课程映射
<?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="courseNamespace"> <resultMap type="cn.albin.javaee.mybatis.many2many.Course" id="courseMap"> <id property="id" column="cid"/> <result property="name" column="cname"/> <collection property="studentList" resultMap="studentNamespace.studentMap"/> </resultMap> <!-- 查询哈哈选学了哪些课程 --> <select id="findAllByName" resultMap="courseMap"> select c.cid,c.cname, s.sid,s.sname from students s inner join middles m on s.sid = m.msid inner join courses c on m.mcid = c.cid </select> </mapper>
-
学生映射
<?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="studentNamespace"> <resultMap type="cn.albin.javaee.mybatis.many2many.Student" id="studentMap"> <id property="id" column="sid"/> <result property="name" column="sname"/> <collection property="courseList" resultMap="courseNamespace.courseMap"/> </resultMap> <select id="findAllByCourseName" resultMap="studentMap"> select c.cid,c.cname,s.sid,s.sname from students s inner join middles m on s.sid = m.msid inner join courses c on m.mcid = c.cid </select> </mapper>
一对一关联 学生和身份证
-
学生类
public class Student { private Integer id; private String name; private Card card;//关联属性 一对一的 }
-
身份证类
public class Card { private Integer id; private String num; }
-
学生映射
<?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="studentNamespace"> <resultMap type="cn.albin.javaee.mybatis.one2one.Student" id="studentMap"> <!-- 主键id --> <id property="id" column="sid"/> <!-- 普通属性 --> <result property="name" column="sname"/> <!-- 引入CardMapper.xml文件中的映射信息 property表示Student类的关联属性 resultMap表示引入CardMapper.xml文件的映射类型 一的一方的关系 --> <association property="card" resultMap="cardNamespace.cardMap"/> </resultMap> <!-- 查询1号学生的信息 --> <select id="findById" parameterType="int" resultMap="studentMap"> select s.sid,s.sname,c.cid,c.cnum from students s inner join cards c on s.scid = c.cid and s.sid = #{id} </select> <!-- 查询哈哈学生的信息 --> <select id="findByName" parameterType="string" resultMap="studentMap"> select s.sname,c.cnum from students s inner join cards c on s.scid = c.cid and s.sname = #{name} </select> </mapper>
-
身份证映射
<?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="cardNamespace"> <resultMap type="cn.albin.javaee.mybatis.one2one.Card" id="cardMap"> <id property="id" column="cid"/> <result property="num" column="cnum"/> </resultMap> </mapper>