MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Ordinary Java Object,普通的 Java对象)映射成数据库中的记录。
一、构建mybatis框架需要准备内容:
1.下载jar包 ,mybatis.jar
2.全局的xml配置文件,mybatis配置文件,配置在类路径下
属性(properties),类的别名,环境(事务管理器,datasource数据源),mapper映射文件
(外部属性文件:如jdbc.properties)
<?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>
<!-- 加载属性文件,把属性文件的值映射成属性key-value -->
<properties resource="jdbc.props"/>
<settings>
<!-- 指定mybatis使用log4j作为日志管理的方式 -->
<setting name="logImpl" value="LOG4J"/>
<!-- 延迟加载或者懒加载 -->
<setting name="lazyLoadingEnabled" value="true"/>
<!-- 积极的懒加载 -->
<!-- <setting name="aggressiveLazyLoading" value="true"/> -->
</settings>
<typeAliases>
<!-- 给全限定名org.lanqiao.entity.Student起一个别名Student,在xml映射文件中就可以使用Student代表全限定名 -->
<!-- <typeAlias type="org.lanqiao.entity.Student" alias="Student"/> -->
<!-- 让entity.lanqiao.entity包下所有实体类都默认起了别名(类名) -->
<package name="org.lanqiao.entity"/>
</typeAliases>
<!--设置数据库连接的环境,选中dev环境-->
<environments default="dev">
<!-- dev环境 -->
<environment id="dev">
<!-- mybais采用jdbc处理事务的方式commit,roolback -->
<transactionManager type="JDBC"></transactionManager>
<!-- 数据源,连接池 -->
<dataSource type="POOLED">
<!-- 数据库连接的信息 -->
<property name="driver" value="${jdbc_driverClass}"/>
<property name="url" value="${jdbc_url}"/>
<property name="username" value="${jdbc_username}"/>
<property name="password" value="${jdbc_password}"/>
</dataSource>
</environment>
<environment id="test">
<transactionManager type="JDBC"></transactionManager>
<dataSource type="POOL">
<property name="" value=""/>
<property name="" value=""/>
<property name="" value=""/>
<property name="" value=""/>
</dataSource>
</environment>
<environment id="pro">
<transactionManager type="JDBC"></transactionManager>
<dataSource type="POOL">
<property name="" value=""/>
<property name="" value=""/>
<property name="" value=""/>
<property name="" value=""/>
</dataSource>
</environment>
</environments>
<mappers>
<!-- 映射的资源文件的位置 -->
<mapper resource="org/lanqiao/mapper/StudentMapper.xml"/>
<mapper resource="org/lanqiao/mapper/SgroupMapper.xml"/>
<mapper resource="org/lanqiao/mapper/CourseMapper.xml"/>
</mappers>
</configuration>
在src文件夹下
log4j.properties
log4j.rootLogger=DEBUG,std,file
log4j.appender.std=org.apache.log4j.ConsoleAppender
log4j.appender.std.layout=org.apache.log4j.SimpleLayout
log4j.appender.file=org.apache.log4j.FileAppender
log4j.appender.file.File=d:/mybatis.log
#log4j.appender.file.layout=org.apache.log4j.SimpleLayout
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=[%d{HH:mm:ss:SSS}][%C-%M] -%m%n
3.接口 增删改查方法
package org.lanqiao.dao;
import java.util.List;
import org.lanqiao.entity.Student;
public interface StudentDao {
public int insertStudent(Student student);
public int updateStudent(Student student);
public int deleteStudent(int i);
public Student selectStudentById(Integer i);
public List<Student> selectAllStudentsWithGroup();
public List<Student> selectAllStudents();
/**
* 根据条件查询满足条件的学生
* @param student
* @return
*/
public List<Student> selectStudentByCondition(Student student);
/**
* 根据field进行排序
* @param field
* @return
*/
public List<Student> selectStudentOrderBy(String field);
/**
* 通过多选的id进行查询
* @param stus
* @return
*/
public List<Student> selectStudentByIds(List<Student> stus);
/**
* 一次插入多个学生
* @param stus
* @return
*/
public int insertStduents(List<Student> students);
}
4.映射文件 (对应接口 namespace)
<?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="org.lanqiao.dao.StudentDao">
<!-- 开启namespace的二级缓存 -->
<cache/>
<resultMap type="Student" id="studentResultMap">
<!-- property属性指的是java实体类的属性名,column指的是数据库的字段名,id标签指的是主键字段 -->
<id property="id" column="id"/>
<result property="name" column="name"/>
<result property="age" column="age"/>
<!-- assocaition,一对一的关系,student和sgroup -->
<association property="sgroup" column="gid" select="org.lanqiao.dao.SgroupDao.selectSgroupByGid"/>
<!-- collection,一对多的关系,一个学生对应多个课程 -->
<collection property="courses" column="id" select="org.lanqiao.dao.CourseDao.selectCourseBySid"/>
</resultMap>
<!--
<resultMap type="Student" id="studentResultMap2">
<id property="id" column="id"/>
<result property="name" column="name"/>
<result property="age" column="age"/>
通过对象属性进行关联
<result property="sgroup.gid" column="gid"/>
<result property="sgroup.gname" column="gname"/>
</resultMap>
-->
<!--
<resultMap type="Student" id="studentResultMap2">
<id property="id" column="id"/>
<result property="name" column="name"/>
<result property="age" column="age"/>
将属性和
<association property="sgroup" javaType="Sgroup">
<id property="gid" column="gid"/>
<result property="gname" column="gname"/>
</association>
</resultMap>
-->
<!--
<resultMap type="Student" id="studentResultMap2">
<id property="id" column="id"/>
<result property="name" column="name"/>
<result property="age" column="age"/>
将
<association property="sgroup" resultMap="sgroupResultMap"/>
</resultMap>
<resultMap type="Sgroup" id="sgroupResultMap">
<id property="gid" column="gid"/>
<result property="gname" column="gname"/>
</resultMap>
-->
<sql id="studentColumns">id,name,age</sql>
<sql id="studentColumns1">id,name,age,gid</sql>
<insert id="insertStudent" keyProperty="id" useGeneratedKeys="true">
insert into student values(null,#{name},#{age},null)
</insert>
<insert id="insertStduents">
insert into student value
<foreach collection="list" item="student" separator=",">
(null,#{student.name},#{student.age},null)
</foreach>
</insert>
<delete id="deleteStudent">
delete from student where id = #{id}
</delete>
<select id="selectAllStudents" resultMap="studentResultMap">
select <include refid="studentColumns1"/> from student
</select>
<select id="selectStudentById" resultMap="studentResultMap">
select * from student where id = #{id}
</select>
<select id="selectStudentOrderBy" resultType="Student">
select * from student order by ${value} desc
</select>
<select id="selectStudentByIds" resultType="Student">
select * from student where id in
<!-- 用foreach批量查询id -->
<foreach collection="list" item="student" open="(" close=")" separator=",">
#{student.id}
</foreach>
</select>
<update id="updateStudent">
update student set name=#{name},age=#{age} where id =#{id}
</update>
<!-- 为了体现java的复用性,将是查询分开写,student完成,student的,group完成group的
<select id="selectAllStudentsWithGroup" resultMap="studentResultMap2">
select s.id,s.name,s.age,g.gid,g.gname from student s,sgroup g where s.gid = g.gid
</select>
-->
<select id="selectStudentByCondition" resultType="Student">
select * from student
<where><!-- 1.动态产生where,内部的所有条件都不成立的话,不生成where
2.动态去掉第一个条件的and -->
<if test="id!=null">
and id=#{id}
</if>
<if test="name!='' and name!=null">
and name like concat('%',concat(#{name},'%'))
</if>
<if test="age!=null">
and age=#{age}
</if>
<!--
<choose>当有一个条件满足时,后面的就不会再判断了
<when test="id!=null">
and id=#{id}
</when>
<when test="name!='' and name!=null">
and name=#{name}
</when>
<when test="age!=null">
and age=#{age}
</when>
</choose>
-->
</where>
</select>
</mapper>
Mybatis核心组件:
- SqlSessionFactoryBuilder:会根据配置信息或代码来生成SqlSessionFactory;
- SqlSessionFactory:依靠工厂来生成SqlSession;
- SqlSession:是一个既可以发送SQL去执行并返回结果,也可以获取Mapper的接口;
- SQL Mapper:是MyBatis新设计的组件,由一个Java接口和XML文件构成,需要给出对应的SQL和映射规则。它负责发送SQL去执行,并返回结果。
private static InputStream is = null;
private static SqlSession sqlSession = null;
private static SqlSession sqlSession2 = null;
private static StudentDao studentDao = null;
private static StudentDao studentDao2 = null;
@BeforeClass
public static void init() throws IOException {
//第一步,把全局配置文件mubatis-config.xml读入流中
is = Resources.getResourceAsStream("mybatis-config.xml");
//第二步,通过流(全局配置文件)创建一个sqlsession的工厂构建器
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
//第三步,通过sqlSession工厂创建sqlSession对象
sqlSession = sqlSessionFactory.openSession();
sqlSession2 = sqlSessionFactory.openSession();
//第四步,通过sqlsession获取StudentDao对象
studentDao = sqlSession.getMapper(StudentDao.class);
studentDao2 = sqlSession2.getMapper(StudentDao.class);
}
7.单元测试JUnit
(1)从库中导入junit
(2)创建一个专门来单元测试的文件夹
(3)单元测试Junit使用的注解
junit4中常用注解 @BeforeClass @Before @AfterClass @After @Test @Ignore
junit5中常用注解 @BeforeAll @BeforeEach @AfterAll @ AfterEach @Test
package org.lanqiao.test;
import static org.junit.Assert.*;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
public class testCycle {
@Before
public void before() {
System.out.println("@Before.....");
}
@BeforeClass
public static void init() {
System.out.println("@BeforeClass.....");
}
@Test
public void test() {
System.out.println("test....");
}
@Test
public void test1() {
System.out.println("test1....");
}
@After
public void after() {
System.out.println("@after.....");
}
@AfterClass
public static void destory() {
System.out.println("@afterClass.....");
}
}
二、Mybatis增删改查
修改接口和映射文件
<sql id="studentColumns">id,name,age</sql>
<sql id="studentColumns1">id,name,age,gid</sql>
<insert id="insertStudent" keyProperty="id" useGeneratedKeys="true">
insert into student values(null,#{name},#{age},null)
</insert>
<insert id="insertStduents">
insert into student value
<foreach collection="list" item="student" separator=",">
(null,#{student.name},#{student.age},null)
</foreach>
</insert>
<delete id="deleteStudent">
delete from student where id = #{id}
</delete>
<select id="selectAllStudents" resultMap="studentResultMap">
select <include refid="studentColumns1"/> from student
</select>
<select id="selectStudentById" resultMap="studentResultMap">
select * from student where id = #{id}
</select>
<select id="selectStudentOrderBy" resultType="Student">
select * from student order by ${value} desc
</select>
<select id="selectStudentByIds" resultType="Student">
select * from student where id in
<!-- 用foreach批量查询id -->
<foreach collection="list" item="student" open="(" close=")" separator=",">
#{student.id}
</foreach>
</select>
<update id="updateStudent">
update student set name=#{name},age=#{age} where id =#{id}
</update>