MyBatis 项目配置
目录结构
?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="jdbc.properties"/> <!-- 类型别名 --> <typeAliases> <typeAlias alias="Student" type="com.java1234.model.Student"/> </typeAliases> <!-- 环境配置 --> <environments default="development"> <environment id="development"> <transactionManager type="JDBC" /> <!-- 数据源 --> <dataSource type="POOLED"> <property name="driver" value="${jdbc.driverClassName}" /> <property name="url" value="${jdbc.url}" /> <property name="username" value="${jdbc.username}" /> <property name="password" value="${jdbc.password}" /> </dataSource> </environment> </environments> <!-- 映射器 --> <mappers> <mapper resource="com/java1234/mappers/StudentMapper.xml" /> </mappers> </configuration> |
environments
<environments default="development"> |
可以修改default的值,配置多个开发环境
transactionManager
<transactionManager type="JDBC" /> |
dataSource
<dataSource type="POOLED"> |
一般使用POOLED
properties
<!-- 引入资源文件 --> <properties resource="jdbc.properties"/> |
访问配置文件的内容(一般使用该方式)
另一种方式
<properties> <property name="jdbc.driverClassName" value="com.mysql.jdbc.Driver"/> <property name="jdbc.url" value="jdbc:mysql://localhost:3306/db_mybatis"/> <property name="jdbc.username" value="root"/> <property name="jdbc.password" value="123456"/> </properties> |
typeAliases
<!-- 类型别名 --> <typeAliases> <typeAlias alias="Student" type="com.java1234.model.Student"/> </typeAliases> |
给完整的配置名取别名
使用mybatis的规范自动扫描取别名(一般使用该方式)
<typeAliases> <package name="com.java1234.model"/> </typeAliases> |
mappers
<mappers> <package name="com.java1234.mappers"/> </mappers> |
将配置的包路径下的所有映射文件进行扫描,不用单个配置(一般使用该方式)
配置 Log4j 日志
<<log4j.properties>>
信息,目标,目标(可以设置多个目标) log4j.rootLogger=info,appender1,appender2 输出目标为控制台 log4j.appender.appender1=org.apache.log4j.ConsoleAppender 输出目标为文件 log4j.appender.appender2=org.apache.log4j.FileAppender 指定输出文件的路径 log4j.appender.appender2.File=C:/logFile.txt 指定输出信息的类型 log4j.appender.appender1.layout=org.apache.log4j.TTCCLayout log4j.appender.appender2.layout=org.apache.log4j.TTCCLayout |
使用 XML 配置 SQL 映射器
INSERT 映射语句
<insert id="add" parameterType="Student" > insert into t_student values(null,#{name},#{age}) </insert> |
UPDATE 映射语句
<update id="update" parameterType="Student"> update t_student set name=#{name},age=#{age} where id=#{id} </update> |
DELETE 映射语句
<delete id="delete" parameterType="Integer"> delete from t_student where id=#{id} </delete> |
SELECT 映射语句
条件查询
<select id="findById" parameterType="Integer" resultType="Student"> select * from t_student where id=#{id} </select> |
全查
<select id="find" resultMap="StudentResult"> select * from t_student </select> |
定义返回的map
<resultMap type="Student" id="StudentResult"> <id property="id" column="id"/> <result property="name" column="name"/> <result property="age" column="age"/> </resultMap> |
Service层
@Test public void testAdd() { logger.info("添加成功"); Student student=new Student("李四2",12); studentMapper.add(student); sqlSession.commit(); }
@Test public void testUpdate(){ logger.info("修改成功"); Student student=new Student(8,"张三2",13); studentMapper.update(student); sqlSession.commit(); }
@Test public void testDelete(){ logger.info("删除成功"); studentMapper.delete(8); sqlSession.commit(); }
@Test public void testFindById(){ logger.info("ͨ通过Id查询"); Student student=studentMapper.findById(1); System.out.println(student); }
@Test public void testFind(){ logger.info("全查"); List<Student> studentList=studentMapper.find(); //遍历list for(Student s:studentList){ System.out.println(s); } |
MyBatis 关系映射
一对一关系实现
第一种方法(使用对象级联)(对象级联,可重用性不大)
配置映射的xml文件
查询后返回的map
配置映射的查询接口(配置通过主键查询从表字段的方法)
配置mybati查询(两张表的关联查询)
配置service层
第二种方式
<resultMap type="Address" id="AddressResult"> <result property="id" column="id"/> <result property="sheng" column="sheng"/> <result property="shi" column="shi"/> <result property="qu" column="qu"/> </resultMap>
<resultMap type="Student" id="StudentResult"> <id property="id" column="id"/> <result property="name" column="name"/> <result property="age" column="age"/> <association property="address" resultMap="AddressResult"/> </resultMap> |
将Result独立出来定义一个AddressResult,再关联到StudentResult中
第三种方式
<resultMap type="Student" id="StudentResult"> <id property="id" column="id"/> <result property="name" column="name"/> <result property="age" column="age"/> <association property="address" javaType="Address"> <result property="id" column="id"/> <result property="sheng" column="sheng"/> <result property="shi" column="shi"/> <result property="qu" column="qu"/> </association> </resultMap> |
直接嵌套到StudentResult中
第四种方式(一般使用该方式)
配置从表查询
定义AddressMapper.java(将通过外键查询到的数据也映射出来)
配置AddressMapper.xml
配置主表查询
配置StudentMapper.xml(使用Mybatis的xml配置指定调用的映射方法)
通过主表的外键查询从表的数据,id为外键
查询方法
查询时,mybatis会根据配置的外键查询从表中的数据
一对多关系实现(多对多使用多个一对多实现)
通过GradeIdi查询所有班级内的学生(学生包含所有信息(地址从表))
配置Grade表查询
配置GradeMapper.java
配置GradeMapper.xml(通过gradeid查询时,mybatis会通过配置查询所有学生)
配置StudentMapper.java
配置StudentMapper.xml
配置Service的Grade,Address也级联打印
双向查询
如果要在查询Student时同时查询Class信息,类似于Address,通过外键查询
动态 SQL
if 条件(动态拼接查询)
<select id="searchStudents" parameterType="Map" resultMap="StudentResult"> select * from t_student where gradeId=#{gradeId} <if test="name!=null"> and name like #{name} </if> <if test="age!=nulll"> and age=#{age} </if> </select> |
查询(条件是动态的)
choose,when 和 otherwise 条件
<select id="searchStudents2" parameterType="Map" resultMap="StudentResult"> select * from t_student <choose> //单个查询,多条件判断 <when test="searchBy=='gradeId'"> where gradeId=#{gradeId} </when> <when test="searchBy=='name'"> where name like #{name} </when> <otherwise> where age=#{age} </otherwise> </choose> </select> |
where 条件(经常使用的)
<select id="searchStudents3" parameterType="Map" resultMap="StudentResult"> select * from t_student <where> //可以不加 <if test="gradeId!=null"> gradeId=#{gradeId} </if> <if test="name!=null"> and name like #{name} </if> <if test="age!=nulll"> and age=#{age} </if> </where> </select> |
查询
trim 条件
<select id="searchStudents4" parameterType="Map" resultMap="StudentResult"> select * from t_student <trim prefix="where" prefixOverrides="and|or"> <if test="gradeId!=null"> gradeId=#{gradeId} </if> <if test="name!=null"> and name like #{name} </if> <if test="age!=nulll"> and age=#{age} </if> </trim> </select> |
可以加前后缀
foreach 循环
<select id="searchStudents5" parameterType="Map" resultMap="StudentResult"> select * from t_student <if test="gradeIds!=null"> <where> gradeId in <foreach item="gradeId" collection="gradeIds" open="(" separator="," close=")"> #{gradeId} </foreach> </where> </if> </select> |
使用foreach遍历集合
遍历查询的集合
set 条件(经常使用的)
<update id="updateStudent" parameterType="Student"> update t_student //自动添加set,自动删除结尾的,逗号 <set> <if test="name!=null"> name=#{name}, </if> <if test="age!=null"> age=#{age}, </if> </set> where id=#{id} </update> |
更新
Mybatis 杂项
处理 CLOB、BLOB 类型数据
CLOB(大文本)
映射成字符串
BLOB(二进制的,图片,视频)(使用流处理)
映射成字节数组
写入表
配置mybatis映射
<insert id="insertStudent" parameterType="Student"> insert into t_student values(null,#{name},#{age},#{pic},#{remark}); </insert> |
插入方法(使用输入流输入文件)
读取表
配置Mybatis映射
<select id="getStudentById" parameterType="Integer" resultType="Student"> select * from t_student where id=#{id} </select> |
读取方法(使用输出流输出文件)
传入多个输入参数(一般不适用该方式查询,多使用Map条件查询)
配置Mybatis(传入param1,param2,两个条件查询)
<select id="searchStudents6" resultMap="StudentResult"> select * from t_student where name like #{param1} and age=#{param2} </select> |
查询方法
Mybatis 分页(内置分页为逻辑分页)
逻辑分页(数据量很大时,性能不高)
配置映射接口方法
配置Mybatis
<select id="findStudents" resultMap="StudentResult" flushCache="false" useCache="true"> select * from t_student </select> |
分页查询方法
物理分页(一般使用该方式分页查询,性能很好)
配置映射接口方法
配置Mybatis
<select id="findStudents2" parameterType="Map" resultMap="StudentResult"> select * from t_student <if test="start!=null and size!=null"> //传入start,size参数 limit #{start},#{size} </if> </select> |
分页查询方法
Mybatis 缓存
在并发量很大的查询时,使用缓存
设置Mybatis缓存
<!-- 1,size:表示缓存cache中能容纳的最大元素数。默认是1024; 2,flushInterval:定义缓存刷新周期,以毫秒计; 3,eviction:定义缓存的移除机制;默认是LRU(least recently userd,最近最少使用(一般使用)),还有FIFO(first in first out,先进先出) 4,readOnly:默认值是false,假如是true的话,缓存只能读。 --> <cache size="1024" flushInterval="60000" eviction="LRU" readOnly="false"/> |
使用注解配置 SQL 映射器(一般使用xml,注解不够灵活)
基本映射语句(不需要配置文件)
//在接口上方使用注解
@Insert("insert into t_student values(null,#{name},#{age})") public int insertStudent(Student student);
@Update("update t_student set name=#{name},age=#{age} where id=#{id}") public int updateStudent(Student student);
@Delete("delete from t_student where id=#{id}") public int deleteStudent(int id);
@Select("select * from t_student where id=#{id}") public Student getStudentById(Integer id); |
事务操作方法(查询不需要提交事务)
@Test public void testInsert() { logger.info("添加学生"); Student student=new Student("李四",11); studentMapper.insertStudent(student); //需要提交 sqlSession.commit(); }
@Test public void testUpdate() { logger.info("修改学生"); Student student=new Student(6,"李四2",12); studentMapper.updateStudent(student); sqlSession.commit(); }
@Test public void testDelete() { logger.info("删除学生"); studentMapper.deleteStudent(6); sqlSession.commit(); }
@Test public void testGetById() { logger.info("ͨ通过Id查询学生"); Student student=studentMapper.getStudentById(1); System.out.println(student); //不需要提交 } |
结果集映射语句
@Select("select * from t_student") //定义结果集 @Results( { //定义结果集的映射字段 @Result(id=true,column="id",property="id"), @Result(column="name",property="name"), @Result(column="age",property="age") } ) //返回集合 public List<Student> findStudents(); |
@Test public void testFindStudents() { logger.info("全查"); List<Student> studentList=studentMapper.findStudents(); //遍历集合 for(Student student:studentList){ System.out.println(student); } } |
关系映射
一对一
配置Student对象
配置Student映射(通过外键查询)
配置Address映射(通过id查询)
配置查询方法
一对多
配置Student对象
配置Student映射(通过外键查询,一对一)
配置Grade映射(通过id查询,一对多)
配置查询方法
双向查询
配置Student映射(通过外键查询,一对多)
配置查询方法
动态 SQL(把sql语句动态拼接出来)(一般使用XML查询)
配置映射类的实现类
动态插入
if 动态判断
修改
WHERE 判断
删除
单条件查询
多条件查询
//设置具体调用的哪个方法 //插入 @InsertProvider(type=StudentDynaSqlProvider.class,method="insertStudent") public int insertStudent(Student student); //修改 @UpdateProvider(type=StudentDynaSqlProvider.class,method="updateStudent") public int updateStudent(Student student); //删除 @DeleteProvider(type=StudentDynaSqlProvider.class,method="deleteStudent") public int deleteStudent(int id); //单条件查询 @SelectProvider(type=StudentDynaSqlProvider.class,method="getStudentById") public Student getStudentById(Integer id); //多条件查询 @SelectProvider(type=StudentDynaSqlProvider.class,method="findStudents") public List<Student> findStudents(Map<String,Object> map); |
具体查询
@Test public void testInsert() { logger.info("查询学生"); Student student=new Student("李四",11); studentMapper.insertStudent(student); sqlSession.commit(); }
@Test public void testUpdate() { logger.info("修改"); Student student=new Student(6,"李四2",12); studentMapper.updateStudent(student); sqlSession.commit(); }
@Test public void testDelete() { logger.info("删除"); studentMapper.deleteStudent(6); sqlSession.commit(); }
@Test public void testGetById() { logger.info("ͨ通过Id查询"); Student student=studentMapper.getStudentById(1); System.out.println(student); }
@Test public void testFindStudents() { logger.info("多条件查询"); Map<String,Object> map=new HashMap<String,Object>(); // map.put("name", "%李%"); // map.put("age", 12); List<Student> studentList=studentMapper.findStudents(map); for(Student student:studentList){ System.out.println(student); } } |
Mybatis 与 Spring,SpringMvc 整合
<<SSM jar包.rar>><<配置文件.rar>>
Spring 与 SpringMvc 整合
目录结构
Spring 与 Mybatis 整合
登录案例
<<Mybatis13.rar>>