MyBatis笔记1:快速入门使用

注:本文内容都来自互联网,通过自己整理用于学习,不作任何其他作用!

使用流程:

1.在maven中导入依赖
Mysql包,mybatis包,junit包
在pom.xml中>配置maven资源过滤文件

<build>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>true</filtering>
            </resource>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>true</filtering>
            </resource>
        </resources>
    </build>

2.配置mybatis-config.xml(resources目录下)

<?xml version="1.0" encoding="GBK" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">

<configuration>

    <environments default="default">
        <environment id="default">
            <transactionManager type="JDBC"></transactionManager>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=true&amp;useUnicode=true&amp;characterEncoding=UTF-8&amp;serverTimezone=UTC"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
    </environments>

    <!--    每一个mapper.xml都需要先在mybatis-config中注册-->
    <mappers>
        <mapper resource="com/aruiea/dao/UserMapper.xml" />
    </mappers>

</configuration>

3.配置数据库,设计数据库表,创建对应Pojo实体类

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student {
    private int id;
    private String name;
    private String age;
    private String group;
}

4.编写MyBatisUtils类获得SqlSession对象。新建utils包,MyBatisUtils类

public class MyBatisUtils {
    
    private static SqlSessionFactory sqlSessionFactory;
    
    static {
        try {
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml"));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    public static SqlSession getSqlSession(){
        return sqlSessionFactory.openSession();
    }
    
}

5.编写数据库dao层公用接口Dao以及DaoMapper.xml映射
注意:DaoMapper.xml要在mybatis-config.xml中进行配置!!!

public interface Dao {
//    增

//    删

//    改

//    查全部

//    查一个
    List<Student> getAll();
}
特别注意:中文注释不能出现在mapper.xml映射器中,会报错!!!!

<?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.aruiea.dao.Dao">
//namespace要和dao/mapper接口的包名一致,绑定一个对应dao/mapper接口
    <select id="getAll" resultType="com.aruiea.pojo.Student">
    //id是接口的方法名,resultType:返回结果。
       select * from mybatis.student;
    </select>
</mapper>

6.测试。在test下,创建DaoMapper.xml相同目录,创建DaoMapperTest

public class DaoMapperTest {

    @Test
    public void Test(){
        SqlSession sqlSession = MyBatisUtils.getSqlSession();
        Dao dao = sqlSession.getMapper(Dao.class);
        List<Student> studentList = dao.getAll();

        for (Student stu:studentList){
            System.out.println(stu);
        }
        
        sqlSession.close();
    }

}

其他功能:
1.通过id查询

    <select id="getById" parameterType="int" resultType="com.aruiea.pojo.Student" >
        select * from mybatis.student where id = #{id};
    </select>
    @Test
    public void getById(){
        SqlSession sqlSession = MyBatisUtils.getSqlSession();
        Dao dao = sqlSession.getMapper(Dao.class);
        Student student = dao.getById(1);

        System.out.println(student);

        sqlSession.close();
    }

2.插入数据

    <insert id="insertStudent" parameterType="com.aruiea.pojo.Student">
        insert into mybatis.student values(#{id},#{name},#{age},#{group});
    </insert>
注意:增删改一定要提交事务才生效!!!!
    @Test
    public void insertStudent(){
        SqlSession sqlSession = MyBatisUtils.getSqlSession();
        Dao dao = sqlSession.getMapper(Dao.class);
        int result = dao.insertStudent(new Student(4,"Flower",200,"魔法学院"));
//        提交事务
        sqlSession.commit();
        if(result > 0 ){
            System.out.println("插入成功");
        }
        sqlSession.close();
    }

3.更新数据

    <update id="updateStudent" parameterType="com.aruiea.pojo.Student" >
        UPDATE student SET name=#{name},age=#{age},`group`=#{group} WHERE id=#{id};
    </update>
    @Test
    public void updateStudent(){
        SqlSession sqlSession = MyBatisUtils.getSqlSession();
        Dao dao = sqlSession.getMapper(Dao.class);
        int result = dao.updateStudent(new Student(4,"Flow",100,"wtf"));
//        提交事务
        sqlSession.commit();
        if(result > 0 ){
            System.out.println("成功!!!");
        }
        sqlSession.close();
    }

4.删除数据

    <delete id="deleteStudent" parameterType="int">
        delete from mybatis.student where id=#{id};
    </delete>
    @Test
    public void updateStudent(){
        SqlSession sqlSession = MyBatisUtils.getSqlSession();
        Dao dao = sqlSession.getMapper(Dao.class);
        int result = dao.deleteStudent(2);
//        提交事务
        sqlSession.commit();
        if(result > 0 ){
            System.out.println("成功!!!");
        }
        sqlSession.close();
    }

使用Map传参:(一般用于表字段多的时候,或者名字不确定的时候)

    <select id="getStudent" parameterType="map" resultType="com.aruiea.pojo.Student">
        select * from mybatis.student where id=#{id} and name=#{name}
    </select>
//    通过多个参数调用方法
    List<Student> getStudent(Map<String,Object> map);
    @Test
    public void getStudent(){
        SqlSession sqlSession = MyBatisUtils.getSqlSession();
        Dao dao = sqlSession.getMapper(Dao.class);
        Map<String,Object> map = new HashMap<String,Object>();
        map.put("id",1);
        map.put("name","Aruiea");
        List<Student> list = dao.getStudent(map);

        for (Student stu:list){
            System.out.println(stu);
        }

        sqlSession.close();
    }

模糊查询:

直接在java传参时加入通配符%value%

//    模糊查询
    List<Student> getStudentLike(String name);
    <select id="getStudentLike" parameterType="String" resultType="com.aruiea.pojo.Student">
        select * from mybatis.student where name like #{name}
    </select>
    @Test
    public void getStudentLike(){
        SqlSession sqlSession = MyBatisUtils.getSqlSession();
        Dao dao = sqlSession.getMapper(Dao.class);

        List<Student> list = dao.getStudentLike("%o%");

        for (Student stu:list){
            System.out.println(stu);
        }

        sqlSession.close();
    }

MyBatis配置
使用properties配置数据库连接

//在resources中新建db.properties。  String=value
driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/mybatis?useSSL=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
username=root
password=123456
<!--    引入外部文件,用${String}引入值-->
    <properties resource="db.properties"/>

    <environments default="default">
        <environment id="default">
            <transactionManager type="JDBC"></transactionManager>
            <dataSource type="POOLED">
                <property name="driver" value="${driver}"/>
                <property name="url" value="${url}"/>
                <property name="username" value="${username}"/>
                <property name="password" value="${password}"/>
            </dataSource>
        </environment>
    </environments>

给一个类设置别名:

<!--    xml配置中,每个标签都有顺序-->
    <typeAliases>
        <typeAlias type="com.aruiea.pojo.Student" alias="stu"></typeAlias>
    </typeAliases>
    <select id="getAll" resultType="stu">
       select * from mybatis.student;
    </select>

指定一个包,扫描下面所有类名小写的名字,如果有注解,为注解名

<!--    xml配置中,每个标签都有顺序-->
    <typeAliases>
        <typeAlias type="com.aruiea.pojo.Student" alias="stu"></typeAlias>
        //配置包名,扫描包下所有的bean,默认小写名称对应
        <package name="com.aruiea.pojo"/>
    </typeAliases>
    <select id="getById" parameterType="int" resultType="student" >
        select * from mybatis.student where id = #{id};
    </select>

注解:

@Alias("al")
public class Student {
    <select id="getAll" resultType="al">
       select * from mybatis.student;
    </select>

拷贝过来的项目,实体类和数据库字段不一致,取不出数据的问题

//数据库中的字段
public class Student {
    private int id;
    private String name;
    private int age;
    private String group;
}
//拷贝过来的pojo
public class Student {
    private int id;
    private String name;
    private int age;
    private String banji;
}
//查询到的代码
Student(id=1, name=Aruiea, age=27, banji=null)
Student(id=3, name=Loader, age=40, banji=null)
Student(id=4, name=Flow, age=100, banji=null)
类型处理器把pojo实体类映射处理成这样:
select id,name,age,banji from student;
所以出错,查不到banji,所以都为Null
解决办法:起别名
    <select id="getAll" resultType="al">
       select id,name,age,`group` as banji from mybatis.student;
    </select>
解决方法:resultMap结果集映射
<!--    结果集映射 id:标识名  type:映射到的类类型-->
    <resultMap id="resMap" type="com.aruiea.pojo.Student">
<!--        column:数据库列名  property:实体类属性名-->
        <result column="id" property="id"></result>
        <result column="name" property="name"></result>
        <result column="age" property="age"></result>
        <result column="group" property="banji"></result>
    </resultMap>
<!--    返回结果resultMap="标识名"-->
    <select id="getAll" resultMap="resMap">
       select * from mybatis.student;
    </select>

Mybatis中数据库操作出现异常:日志!

//在pom.xml导入依赖
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
//在resource目录下新建log4j.properties.并写上一下内容
#将等级为DEBUG的日志信息输出到console和file这两个目的地,console 和file的定义在下面的代码
log4j.rootLogger=DEBUG, console, file

log4j.rootLogger=INFO,CONSOLE
log4j.addivity.org.apache=true

# console
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.Threshold=INFO
log4j.appender.CONSOLE.Target=System.out
log4j.appender.CONSOLE.Encoding=UTF-8
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=[demo] %-5p %d{yyyy-MM-dd HH\:mm\:ss} - %C.%M(%L)[%t] - %m%n

# all
log4j.logger.com.demo=INFO, DEMO
log4j.appender.DEMO=org.apache.log4j.RollingFileAppender
log4j.appender.DEMO.File=${catalina.base}/logs/demo.log
log4j.appender.DEMO.MaxFileSize=50MB
log4j.appender.DEMO.MaxBackupIndex=3
log4j.appender.DEMO.Encoding=UTF-8
log4j.appender.DEMO.layout=org.apache.log4j.PatternLayout

//在mybatis-config.xml中配置日志实现
    <settings>
<!--        <setting name="logImpl" value="STDOUT_LOGGING"/>-->
        <setting name="logImpl" value="LOG4J"/>
    </settings>
//简单使用:
    @Test
    public void Test(){
//        使用
        logger.info("info:进入了Test方法");
        logger.debug("debug:进入了Test方法");
        logger.error("error:进入了Test方法");
        SqlSession sqlSession = MyBatisUtils.getSqlSession();
        Dao dao = sqlSession.getMapper(Dao.class);
        List<Student> studentList = dao.getAll();

        for (Student stu:studentList){
            System.out.println(stu);
        }

        sqlSession.close();
    }

输出结果:
"D:\Program Files\Java\jdk1.8\bin\java.exe" -ea -Didea.test.cyclic.buffer.size=1048576 "-javaagent:D:\Program Files\JetBrains\IntelliJ IDEA 2019.3.5\lib\idea_rt.jar=64486:D:\Program Files\JetBrains\IntelliJ IDEA 2019.3.5\bin" -Dfile.encoding=UTF-8 -classpath "D:\Program Files\JetBrains\IntelliJ IDEA 2019.3.5\lib\idea_rt.jar;D:\Program Files\JetBrains\IntelliJ IDEA 2019.3.5\plugins\junit\lib\junit5-rt.jar;D:\Program Files\JetBrains\IntelliJ IDEA 2019.3.5\plugins\junit\lib\junit-rt.jar;D:\Program Files\Java\jdk1.8\jre\lib\charsets.jar;D:\Program Files\Java\jdk1.8\jre\lib\deploy.jar;D:\Program Files\Java\jdk1.8\jre\lib\ext\access-bridge-64.jar;D:\Program Files\Java\jdk1.8\jre\lib\ext\cldrdata.jar;D:\Program Files\Java\jdk1.8\jre\lib\ext\dnsns.jar;D:\Program Files\Java\jdk1.8\jre\lib\ext\jaccess.jar;D:\Program Files\Java\jdk1.8\jre\lib\ext\jfxrt.jar;D:\Program Files\Java\jdk1.8\jre\lib\ext\localedata.jar;D:\Program Files\Java\jdk1.8\jre\lib\ext\nashorn.jar;D:\Program Files\Java\jdk1.8\jre\lib\ext\sunec.jar;D:\Program Files\Java\jdk1.8\jre\lib\ext\sunjce_provider.jar;D:\Program Files\Java\jdk1.8\jre\lib\ext\sunmscapi.jar;D:\Program Files\Java\jdk1.8\jre\lib\ext\sunpkcs11.jar;D:\Program Files\Java\jdk1.8\jre\lib\ext\zipfs.jar;D:\Program Files\Java\jdk1.8\jre\lib\javaws.jar;D:\Program Files\Java\jdk1.8\jre\lib\jce.jar;D:\Program Files\Java\jdk1.8\jre\lib\jfr.jar;D:\Program Files\Java\jdk1.8\jre\lib\jfxswt.jar;D:\Program Files\Java\jdk1.8\jre\lib\jsse.jar;D:\Program Files\Java\jdk1.8\jre\lib\management-agent.jar;D:\Program Files\Java\jdk1.8\jre\lib\plugin.jar;D:\Program Files\Java\jdk1.8\jre\lib\resources.jar;D:\Program Files\Java\jdk1.8\jre\lib\rt.jar;D:\Program Files\JetBrains\MyBatisProject\MyBatisPractice2\target\test-classes;D:\Program Files\JetBrains\MyBatisProject\MyBatisPractice2\target\classes;D:\Programe\apache-maven-3.6.0\maven-repo\mysql\mysql-connector-java\8.0.19\mysql-connector-java-8.0.19.jar;D:\Programe\apache-maven-3.6.0\maven-repo\com\google\protobuf\protobuf-java\3.6.1\protobuf-java-3.6.1.jar;D:\Programe\apache-maven-3.6.0\maven-repo\org\mybatis\mybatis\3.5.4\mybatis-3.5.4.jar;D:\Programe\apache-maven-3.6.0\maven-repo\log4j\log4j\1.2.17\log4j-1.2.17.jar;D:\Programe\apache-maven-3.6.0\maven-repo\org\projectlombok\lombok\1.18.12\lombok-1.18.12.jar;D:\Programe\apache-maven-3.6.0\maven-repo\junit\junit\4.13\junit-4.13.jar;D:\Programe\apache-maven-3.6.0\maven-repo\org\hamcrest\hamcrest-core\1.3\hamcrest-core-1.3.jar" com.intellij.rt.junit.JUnitStarter -ideVersion5 -junit4 com.aruiea.dao.DaoMapperTest,Test
[demo] INFO  2020-06-06 22:11:24 - com.aruiea.dao.DaoMapperTest.Test(30)[main] - info:进入了Test方法
[demo] ERROR 2020-06-06 22:11:24 - com.aruiea.dao.DaoMapperTest.Test(32)[main] - error:进入了Test方法
Student(id=1, name=Aruiea, age=27, banji=三年二班)
Student(id=3, name=Loader, age=40, banji=教导处)
Student(id=4, name=Flow, age=100, banji=wtf)

分页查询实现
1.Dao.class中增加方法getStudentLimit();

//    分页查询
    List<Student> getStudentLimit(Map map);

2.DaoMapper.xml中配置文件

<!--    分页查询-->
    <select id="getStudentLimit" parameterType="Map" resultType="com.aruiea.pojo.Student">
        select * from mybatis.student limit #{startIndex},#{pageSize};
    </select>

3.使用sqlSession测试。

    @Test
    public void getStduentLimit(){
        SqlSession sqlSession =MyBatisUtils.getSqlSession();
        Dao dao = sqlSession.getMapper(Dao.class);
        HashMap<String,Object> map = new HashMap<String,Object>();
        map.put("startIndex",0);
        map.put("pageSize",5);

        List<Student> studentLimit = dao.getStudentLimit(map);
        for (Student student : studentLimit) {
            System.out.println(student);
        }

        sqlSession.close();
    }

使用注解开发
1.在接口上加注解

//    查全部
    @Select("select * from mybatis.student;")
    List<Student> getAll();
    //    通过id查询,有参数要加上@Param
    @Select("select * from mybatis.student where id=#{id}")
    Student getById(@Param("id") int id);

2.在mybatis中注册类

    <!--    注解开发接口需要先在mybatis-config中注册-->
    <mappers>
        <mapper class="com.aruiea.dao.Dao" />
    </mappers>

3.测试

    @Test
    public void Test(){
        SqlSession sqlSession = MyBatisUtils.getSqlSession();
        Dao dao = sqlSession.getMapper(Dao.class);
        List<Student> studentList = dao.getAll();

        for (Student stu:studentList){
            System.out.println(stu);
        }

        sqlSession.close();
    }

增删改/注解
1.创建sqlSession的时候设置自动提交。

    public static SqlSession getSqlSession(){
        return sqlSessionFactory.openSession(true);
    }

2.在接口上添加注解

//    增
    @Insert("insert into student values(#{id},#{name},#{age},#{banji})")
    int insertStudent(Student student);
//    删
    @Delete("delete from student where id=#{id}")
    int deleteStudent(int id);
//    改
    @Update("update student set name=#{name},age=#{age},`group`=#{banji} where id=#{id}")
    int updateStudent(Student student);

3.测试。

    @Test
    public void delTest(){
        SqlSession sqlSession= MyBatisUtils.getSqlSession();
        Dao mapper = sqlSession.getMapper(Dao.class);
        mapper.getAll();
        mapper.getById(2);
        mapper.deleteStudent(19);
        sqlSession.close();
    }

MyBatis执行流程
1.Resources:获取加载全局配置
2.创建SqlSessionFactoryBuilder().build(Resources.getResourceAsStream(MyBatis.xml));
3.解析文件流XMLconfigBuilder,Configuration所有的配置信息。
4.实例化SqlSessionFactory
5.executor执行器执行
6.创建SqlSession
7.实现CRUD,transcation事务管理

多对一处理
使用子查询
1.搭建数据库表

USE mybatis
;
CREATE TABLE `teacher`(
`id` INT(10) NOT NULL,
`name` VARCHAR(30) DEFAULT NULL,
PRIMARY KEY(`id`)
)ENGINE=INNODB DEFAULT CHARSET=utf8
INSERT INTO teacher(`id`,`name`) VALUES(1,'Aruiea');
INSERT INTO teacher(`id`,`name`) VALUES(2,'Gaoslin');

DROP TABLE student

CREATE TABLE `student2`(
`id` INT(10) NOT NULL,
`name` VARCHAR(30) DEFAULT NULL,
`tid` INT(10) DEFAULT NULL,
PRIMARY KEY(`id`),
KEY `fktid` (`tid`),
CONSTRAINT `fktid` FOREIGN KEY (`tid`) REFERENCES `teacher`(`id`)
)ENGINE=INNODB DEFAULT CHARSET=utf8

INSERT INTO `student2` VALUES(1,'小红',1),(2,'小明',1);
INSERT INTO `student2` VALUES(3,'小黑',1),(4,'小刚',1),(5,'小紫',1),(6,'小绿',1);
INSERT INTO `student2` VALUES(7,'小黑',2),(8,'小刚',2),(9,'小紫',2),(10,'小绿',2);

2.编写代码
准备工作:
1.pojo学生Student2和Teacher类
2.dao层Student2Mapper和TeacherMapper接口
3.resources目录下Student2Mapper.xml和TeacherMapper.xml
4.在mybatis-config中配置
注:纯注解开发不需要xml,配置时直接指定class

public class Student2 {
    private int id;
    private String name;
    private Teacher teacher;
}
public class Teacher {
    private int id;
    private String name;
}
<?xml version="1.0" encoding="GBK" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.aruiea.dao.TeacherMapper">

</mapper>
    <!--    每一个mapper.xml都需要先在mybatis-config中注册-->
    <mappers>
        <mapper class="com.aruiea.dao.TeacherMapper"/>
        <mapper class="com.aruiea.dao.Student2Mapper"/>
    </mappers>

查询Student2的所有数据(外键tid=teacher.id)多对一
1.写接口

//    查询所有学生以及对应老师的信息
    List<Student2> getList();

//    得到老师的信息
    Teacher getTeacher(int id);

2.配置Mapper.xml

<mapper namespace="com.aruiea.dao.Student2Mapper">
    <select id="getList" resultMap="Student2Teacher">
        select * from student2;
    </select>
<!--用结果集映射,对student2的结果进行映射-->
    <resultMap id="Student2Teacher" type="com.aruiea.pojo.Student2">
        <result property="id" column="id"  />
        <result property="name" column="name" />
<!--        单独处理复杂属性,把student属性teacher对应到数据库tid列。-->
<!--        声明java类型Teacher,结果为getTeacher方法返回的类型Teacher-->
        <association property="teacher" column="tid" javaType="Teacher" select="getTeacher" />
    </resultMap>

    <select id="getTeacher" resultType="com.aruiea.pojo.Teacher">
        select * from teacher where id=#{id};
    </select>
</mapper>

4.测试,输出结果正确!

联表查询

<!--    联表查询-->
    <select id="getList" resultMap="Student2Teacher">
        select s2.id s2id,s2.name s2name,t.name tname,s2.tid s2tid
        from student2 s2,teacher t
        where s2.tid=t.id;
    </select>
    <resultMap id="Student2Teacher" type="com.aruiea.pojo.Student2">
        <result property="id" column="s2id" />
        <result property="name" column="s2name" />
<!--        以下映射的column都是Student2中查询出来的数据,没查出来则没有-->
        <association property="teacher" javaType="com.aruiea.pojo.Teacher">
            <result property="id" column="s2tid" />
            <result property="name" column="tname" />
        </association>
    </resultMap>

一对多
子查询方式代码
1.写Mapper接口

//    获得所有老师对象
    List<Teacher> getTeacher(int id);
    //    获得指定学生对象
    Student2 getStudentById(int id);

2.编写Mapper.xml
注:没有解决子查询时,传参的问题。

<!--    直接查询处所有的Teacher-->
    <select id="getTeacher" resultMap="TeacherStudent2">
        select * from teacher where id = #{tid};
    </select>
<!--    在结果集映射中进行子查询-->
    <resultMap id="TeacherStudent2" type="Teacher">
<!--        把teacher中的属性students映射到student2类上(ofType)-->
<!--        调用select方法,用column传参-->
        <collection property="students" javaType="ArrayList" ofType="student2" select="getStudentById" column="id"/>
    </resultMap>
<!--    要查询的student2方法-->
    <select id="getStudentById" resultType="student2">
        select * from student2 where tid=#{tid};
    </select>

3.测试。id传参有误,其他正常!

联表查询代码示范
1.写Mapper接口

//    获得所有老师对象
    List<Teacher> getTeacher(int id);

2.编写Mapper.xml

<mapper namespace="com.aruiea.dao.TeacherMapper">
<!--    所有要显示的数据都要先查询-->
    <select id="getTeacher" resultMap="TeacherStudent2">
        select s.id sid,s.name sname,t.name tname,t.id tid
        from student2 s,teacher t
        where s.tid=t.id and t.id=#{tid}
    </select>
    <resultMap id="TeacherStudent2" type="com.aruiea.pojo.Teacher">
        <result property="id" column="tid"/>
        <result property="name" column="tname"/>
<!--        association是对应一个对象(多对一),collection对应一个集合(一对多)-->
<!--        ofType表明students属性归属的类,属于java代码-->
        <collection property="students" ofType="Student2">
<!--            这底下都是Student2类属性对应的数据库列,可以随便写-->
            <result property="id" column="sid"/>
            <result property="name" column="sname"/>
            <result property="tid" column="tid"/>
        </collection>
    </resultMap>

</mapper>

3.测试,成功。

    @Test
    public void getTeacher(){
        SqlSession sqlSession = MyBatisUtils.getSqlSession();
        TeacherMapper mapper = sqlSession.getMapper(TeacherMapper.class);
        List<Teacher> teacher = mapper.getTeacher(1);
        for (Teacher teacher1 : teacher) {
            System.out.println(teacher1);
        }
        sqlSession.close();
    }

动态SQL
1.准备工作:创建MyBatis类,创建pojo类,dao层接口和xml,工具类MyBatis和UUID(返回随机网络标识符)配置mybatis,把xml配置到mybatis中。

<?xml version="1.0" encoding="GBK" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">

<configuration>

<!--    引入外部文件-->
    <properties resource="db.properties"/>

    <settings>
<!--&lt;!&ndash;        <setting name="logImpl" value="STDOUT_LOGGING"/>&ndash;&gt;-->
<!--        <setting name="logImpl" value="LOG4J"/>-->
<!--        开启驼峰命名自动转换,把类似createtime映射到数据库create_time-->
        <setting name="mapUnderscoreToCamelCase" value="true"/>
    </settings>
    
    
    <typeAliases>
    <package name="com.aruiea.pojo"/>
    </typeAliases>
    
    <environments default="default">
        <environment id="default">
            <transactionManager type="JDBC"></transactionManager>
            <dataSource type="POOLED">
                <property name="driver" value="${driver}"/>
                <property name="url" value="${url}"/>
                <property name="username" value="${username}"/>
                <property name="password" value="${password}"/>
            </dataSource>
        </environment>
    </environments>

    <!--    每一个mapper.xml都需要先在mybatis-config中注册-->
    <mappers>
        <mapper class="com.aruiea.dao.BlogMapper"/>
    </mappers>

</configuration>

在这里插入图片描述

public class MyBatisUtils {

    private static SqlSessionFactory sqlSessionFactory;

    static {
        try {
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml"));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static SqlSession getSqlSession(){
        return sqlSessionFactory.openSession(true);
    }

}

public class Blog {
    private String id;
    private String title;
    private String author;
    private Date create_time;
    private int views;
}
public interface BlogMapper {
//    插入数据
    int addBlog(Blog blog);
}
<?xml version="1.0" encoding="GBK" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.aruiea.dao.BlogMapper">
    <insert id="addBlog" parameterType="blog">
        insert into mybatis.blog values(#{id},#{title},#{author},#{create_time},#{views});
    </insert>
</mapper>
public class IDUtils {
    public static String getId(){
//        利用UUID工具类创建随机UID,把里面所有的-删除掉
        return UUID.randomUUID().toString().replaceAll("-","");
    }
    
}

2.测试insert方法,成功。

    @Test
    public void aTest(){
        SqlSession sqlSession = MyBatisUtils.getSqlSession();
        BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
        Blog blog = new Blog();
        blog.setId(IDUtils.getId());
        blog.setTitle("极寒之地");
        blog.setAuthor("Aruiea");
        blog.setCreate_time(new Date());
        blog.setViews(999);

        sqlSession.commit();
        mapper.addBlog(blog);

        sqlSession.close();
    }
}

动态SQL:IF,trim(where,set) choose(when,otherwise) foreach
动态sql之IF
接口中增加方法。

//    查询博客
    List<Blog> queryBlogIF(Map map);

Mapper.xml中配置IF

<!--    动态sql的if语句-->
    <select id="queryBlogIF" parameterType="Map" resultType="blog">
        select * from blog where 1=1
--         test中写表达式:如果title属性不为空,把语句拼接到select后面
        <if test="title!=null">
            and title=#{title}
        </if>
        <if test="author">
            and author=#{author}
        </if>
    </select>

或者这么写:

<!--    动态sql的if语句-->
    <select id="queryBlogIF" parameterType="Map" resultType="blog">
        select * from blog
--         test中写表达式:如果title属性不为空,把语句拼接到select后面
        <!--    where元素只有在有SQL子句的情况下才生效,并且只能去掉前面的and或者or-->
        <where>
            <if test="title!=null">
                and title=#{title}
            </if>
            <if test="author">
                and author=#{author}
            </if>
        </where>

    </select>

测试。

    @Test
    public void a2Test(){
        SqlSession sqlSession = MyBatisUtils.getSqlSession();
        BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
        HashMap<String,Object> map = new HashMap<String,Object>();
//        map.put("title","极寒之地");
//        map.put("author","Aruiea");
        List<Blog> blogs = mapper.queryBlogIF(map);
        System.out.println(blogs);
        sqlSession.commit();
        sqlSession.close();
    }

动态SQL之Choose

//    查询博客,通过选择choose(类似java的switch)
    List<Blog> queryBlogChoose(Map map);
<!--    where元素只有在有SQL子句的情况下才生效,并且只能去掉前面的and或者or-->
    <select id="queryBlogChoose" parameterType="Map" resultType="blog">
        select * from blog
        <where>
            --    此处运行时需要删除!!!类似于java的switch,从下面选一个,otherwise是默认的
            <choose>
                <when test="title!=null">title=#{title}</when>
                <when test="author!=null">and author=#{author}</when>
                <otherwise>
                    and views=#{views}
                </otherwise>
            </choose>
        </where>
    </select>

测试。

    @Test
    public void a3Test(){
        SqlSession sqlSession = MyBatisUtils.getSqlSession();
        BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
        HashMap<String,Object> map = new HashMap<String,Object>();
//        map.put("title","极寒之地");
//        map.put("author","Aruiea");
          map.put("views",999);
        List<Blog> blogs = mapper.queryBlogChoose(map);
        System.out.println(blogs);

        sqlSession.commit();

        sqlSession.close();
    }

动态SQL之set
接口方法

//    更新博客
    int updateBlog(Map map);

xml配置文件

<!--    使用update/set更新-->
    <update id="updateBlog" parameterType="Map">
        update mybatis.blog
        <set>
            <if test="title != null">
               title=#{title},
            </if>
            <if test="author != null">
                author=#{author}
            </if>
        </set>
        where id=#{id}
    </update>

动态SQL之SQL片段
xml中定义公用SQL,INCLUDE引用,所有地方都能用

    <sql id="commonSql">
        <if test="title!=null">
            and title=#{title}
        </if>
        <if test="author">
            and author=#{author}
        </if>
    </sql>

<!--    动态sql的if语句-->
    <select id="queryBlogIF" parameterType="Map" resultType="blog">
        select * from blog
        <!--运行时需要删除此行!!!  test中写表达式:如果title属性不为空,把语句拼接到select后面-->
        <!--    where元素只有在有SQL子句的情况下才生效,并且只能去掉前面的and或者or-->
        <where>
            <!--运行时需要删除此行!!!    用include引入公用的sql语句-->
            <include refid="commonSql"></include>
        </where>
    </select>

动态SQL之FOREACH
对一个集合进行操作,通常在用IN的时候
xml代码

<!--    用Foreach实现select * from blog where 1=1 and (id=1 or id=2 or id=3);-->
    <select id="queryBlogForeach" parameterType="Map" resultType="blog">
        select * from blog
        <where>
--         注意拼接时的空格,否则会语法错误
            <foreach collection="ids" item="id" open=" and (" close=" )" separator=" or ">
                id=#{id}
            </foreach>
        </where>
    </select>

测试

    @Test
    public void a5Test(){
        SqlSession sqlSession = MyBatisUtils.getSqlSession();
        BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
        HashMap<String,Object> map = new HashMap<String,Object>();

        ArrayList<Integer> ids = new ArrayList<Integer>();
        ids.add(1);
        ids.add(2);
        map.put("ids",ids);
        List<Blog> blogs = mapper.queryBlogForeach(map);
        for (Blog blog : blogs) {
            System.out.println(blog);
        }
        sqlSession.close();
    }

MyBatis缓存
二级缓存:也叫全局缓存,一级缓存作用域太低,所以诞生了二级缓存。
基于一个namespace的缓存,一个命名空间,对应一个二级缓存。
*一个会话查询一条数据,这个数据会被放在当前对象的一级缓存中。
*会话关闭sqlsession关闭,对应的一级缓存就没有了。这时候需要二级缓存。
二级缓存的使用:
1.mybtis-config.xml中开启

   <settings>
<!--  显示开启全局缓存-->
        <setting name="cacheEnabled" value="true"/>
    </settings>

2.在当前xml使用二级缓存

<!--在当前mapper中开启二级缓存 eviction:收回  最多512个缓存 刷新时间60s-->
    <cache eviction="FIFO"
        flushInterval="60000"
        size="512"
        readOnly="true"
    />
    <select id="getAll" resultType="blog" useCache="true">
        select * from blog;
    </select>

*只要开启了二级缓存,在同一个Mapper下就有效
*所有数据都会先放在一级缓存中
*只有当会话提交/关闭的时候,才会提交到二级缓存中。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值