bingmous

欢迎交流,不吝赐教~

导航

Mybatis学习笔记(详细)

 介绍

  • 三层架构:视图层、业务逻辑层、持久层
  • mybatis框架:
    • 执行数据库操作,完成对数据库的增删改查,封装了jdbc
    • mapper映射,将表中数据转为一个Java对象,一个表对应一个接口

Mybatis实战

  • 使用方式:
    • 直接获取SqlSession,根据sql id执行sql
    • 自定义dao接口实现类,使用接口实现类对象操作(会有大量重复代码)
    • 使用mybatis的代理对象:使用getMapper()获取dao对象,直接执行方法访问数据库。
  • mybatis框架使用步骤:
    • 定义实体类
    • 定义接口
    • 定义mapper文件
    • 定义主配置文件:1.数据源,2.mapper文件位置
    • 使用SqlSessionFactoryBuild创建SqlSessionFactory并传入xml配置文件,通过Factory创建SqlSession,通过SqlSession执行一系列数据库操作
  • mybatis传递参数
    • dao方法有一个简单类型,直接使用#{任意字符}
    • 多个参数:使用@Param("xx")指明xml解析的名字
    • 使用Java对象,mapper中使用对象的属性
  • #和$的区别
    • #是占位符,使用PreparedStatement执行sql,效率高
    • 表示列的值,一般放在等号右侧使用
    • $是字符串连接,使用Statement,效率低,有sql注入的风险
    • $一般是替换表名、列名
  • mybatis封装sql的执行结果
    • 标签中的resultType,指明封装结果的对象,可以使用别名(需要定义,可以复用)
    • 标签中的resultMap,指明数据库列名与Java对象属性的对应关系(需要定义,可以复用),或者使用sql语句的as给列取别名
  • like:直接使用#{xxx},传递参数给mapper
  • 动态sql
    • <where>:里面是if,条件满足加入where,并去除多余的and,or等关键字
    • <if>:如果条件满足,加入后面的sql语句
    • <foreach>:list或array
  • mybatis主配置文件:配置项有顺序
    • <properties resource=xxx>配置.properties:,使用${}引用
    • <settings>中可以配置日志
    • <typeAliases>配置别名:<typeAlias>给某个类型,<package>把一个包中的类作为别名(如果有名称相同的类会有冲突)
    • <plugins>配置插件
    • <environments>配置<dataSource>
    • mapper文件的位置:<mapper resource>单个指定,<package name>指定某个包(要求名称与接口名相同,并在同一个包下)
  • PageHelper分页插件
    • 加入依赖
    • 在执行查询前调用PageHelper的静态方法即可

代码

  • pom
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.bingmous</groupId>
    <artifactId>mybatis</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
    </properties>
    <dependencies>
        <!--mybatis依赖-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.1</version>
        </dependency>
        <!--postgresql驱动-->
        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <version>42.2.19</version>
        </dependency>

        <!--mybatis分页插件-->
        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper</artifactId>
            <version>5.2.1</version>
        </dependency>

        <!--其他开发插件-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.20</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <!--把src目录下的文件复制到target目录-->
        <resources>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>false</filtering>
            </resource>
        </resources>
    </build>

</project>
  • 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"></properties>

    <!--全局配置-->
    <settings>
        <setting name="logImpl" value="STDOUT_LOGGING"/><!--加入日志配置,可以在控制台输出执行的sql-->
    </settings>
    
    <!--定义别名
        1 指定某个类型
        2 指定某个包,该包下的类都是别名,不区分大小写(如果有名字相同的类则报错)
        建议不使用别名,使用全限定名
    -->
    <typeAliases>
<!--        <typeAlias type="com.bingmous.beans.Student" alias="stu"></typeAlias>-->
<!--        <package name="com.bingmous.beans"/>-->
    </typeAliases>
    <!--使用page插件,在environments之前插入-->
    <plugins>
        <plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin>
    </plugins>

    <environments default="development"><!--默认的数据库连接信息-->
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.drive}"/>
                <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/bingmous/dao/StudentDao.xml"/>
<!--        <mapper resource="mapper/StudentDao.xml"/>-->
        <!--指定包下的所有接口
            注意:必须mapper名与dao名相同,且在同一个包下
        -->
<!--        <package name="com.bingmous.dao"/>-->
    </mappers>
</configuration>
  • jdbc配置文件
jdbc.drive=org.postgresql.Driver
jdbc.url=jdbc:postgresql://10.194.227.212:5432/zztest
jdbc.username=postgres
jdbc.password=hik12345+
  • 操作student表的接口
/**
 * 操作student表的接口
 * created by Bingmous on 2021/7/6 9:59
 */
public interface StudentDao {

    List<Student> selectStudents();

    //单个简单参数
    Student selectStudentById(Integer id);
    //多个简单参数
    List<Student> selectStudentByNameAndAge(@Param("name") String name,
                                            @Param("age") Integer age);
    //使用对象传递参数
    List<Student> selectStudentByNameAndAge2(Student student);
    //like
    List<Student> selectStudentLike(String name);

    int insertStudent(Student student); //插入数据

//    List<Student> selectDynamicSQL(Student student);
//    List<Student> selectDynamicSQL(@Param("name") String name,
//                                   @Param("age") Integer age);
    List<Student> selectDynamicSQL(@Param("age") Integer age);
    List<Student> selectDynamicSQL2(ArrayList<Student> list);
}
  • 对应的mybatis配置文件
<?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:命名空间,写表的Dao的全限定名
    select:执行select语句
    id:sql语句的唯一表示
    resultType:查询结果的类型

    -->
<mapper namespace="com.bingmous.dao.StudentDao">
    <!--1 使用resultMap指定列与java对象的对应关系(可以复用)
        2 sql语句中使用别名
    -->
    <resultMap id="studentMap" type="com.bingmous.beans.Student">
        <id column="id" property="id"></id><!--主键-->
        <result column="name" property="name"></result><!--非主键-->
        <result column="email" property="email"></result>
        <result column="age" property="age"></result>
    </resultMap>
    <select id="selectStudents" resultMap="studentMap">
        select id, name, email, age from student order by id
    </select>
    <!--单个简单参数:可以不写-->
    <select id="selectStudentById" resultType="com.bingmous.beans.Student">
        select id, name, email, age from student where id = #{id}
    </select>
    <!--多个参数:使用@Param-->
    <select id="selectStudentByNameAndAge" resultType="com.bingmous.beans.Student">
        select id, name, email, age from student where name = #{name} or age = #{age}
    </select>
    <!--使用对象传递参数:使用对象的属性-->
    <select id="selectStudentByNameAndAge2" resultType="com.bingmous.beans.Student">
        select id, name, email, age from student where name = #{name} or age = #{age}
    </select>
    <select id="selectStudentLike" resultType="com.bingmous.beans.Student">
        <include refid="selectFragment"></include> where name like #{name}
    </select>

    <insert id="insertStudent">
        insert into student(id, name, email, age)
        values (#{id}, #{name}, #{email}, #{age})
    </insert>

    <!--动态sql-->
    <select id="selectDynamicSQL" resultType="com.bingmous.beans.Student">
        select id, name, email, age from student
        <where>
<!--            <if test="name=''">/*null和""都会解析成空字符串*/
                id=1001
            </if>-->
            <if test="age > 0">
                or age > 0
            </if>
        </where>
    </select>
    <select id="selectDynamicSQL2" resultType="com.bingmous.beans.Student">
        <include refid="selectFragment"></include> where id in
        <foreach collection="list" item="stu" open="(" close=")" separator=",">
            #{stu.id}
        </foreach>
    </select>
    <!--sql片段,可以复用-->
    <sql id="selectFragment">
        select id, name, email, age from student
    </sql>
</mapper>
  • 接口实现类测试
/**
 * created by Bingmous on 2021/7/6 14:14
 */
//public class StudentDaoImpl implements StudentDao {
//    @Override
//    public List<Student> selectStudents() {
//        SqlSession sqlSession = MybatisUtils.getSqlSession();
//        List<Student> list = sqlSession.selectList("com.bingmous.dao.StudentDao.selectStudents");
//        sqlSession.commit();
//        sqlSession.close();
//        return list;
//    }
//
//    @Override
//    public int insertStudent(Student student) {
//        SqlSession sqlSession = MybatisUtils.getSqlSession();
//        int nums = sqlSession.insert("com.bingmous.dao.StudentDao.insertStudent", student);
//        sqlSession.commit();
//        sqlSession.close();
//        return nums;
//    }
//
//}
  • 获取连接的工具类
/**
 * created by Bingmous on 2021/7/6 13:51
 */
public class MybatisUtils {
    private static SqlSessionFactory factory = null; //重量级对象,一个项目只有一份就可以了
    static {
        InputStream is = null;
        try {
            is = Resources.getResourceAsStream("mybatis.xml");
            factory = new SqlSessionFactoryBuilder().build(is);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //获取session
    public static SqlSession getSqlSession(){
        if (factory != null) {
            return factory.openSession();
        }
        return null;
    }
}
  • student实体类
/**
 * created by Bingmous on 2021/7/6 9:56
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student {
    private Integer id;
    private String name;
    private String email;
    private Integer age;

    /**
     * 如果没有无参构造方法,Mybatis会调用全参构造方法
     * 如果没有无参,没有全参,会调用其他有参,但必须只有一个
     */
//    public Student(Integer id, String name) {
//        this.id = id;
//        this.name = name;
//        System.out.println("构造方法被调用了。。。。" + id + " " + name);
//    }

//    public Student() {
//        System.out.println("无参构造方法被调用了。。。");
//    }

//    public Student(Integer id, String name, String email, Integer age) {
//        this.id = id;
//        this.name = name;
//        this.email = email;
//        System.out.println("全参构造方法:" + id + " " + name + " " + email + " " + age);
//    }
}
  • 主方法
/**
 * created by Bingmous on 2021/7/6 9:56
 */
public class MainApplication {
    public static void main(String[] args) throws IOException {
//        //获取配置文件
//        InputStream is = Resources.getResourceAsStream("mybatis.xml");
//        //获取SqlSessionFactory
//        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
//        //获取session
//        SqlSession sqlSession = factory.openSession();

        SqlSession sqlSession = MybatisUtils.getSqlSession();
        //执行配置文件中的sql语句
        List<Student> list = sqlSession.selectList("com.bingmous.dao.StudentDao.selectStudents");
        list.forEach(System.out::println);
        //关闭session
        sqlSession.close();
    }
}
  • 测试方法

/**
 * created by Bingmous on 2021/7/6 11:13
 */
public class TestMybatis {
    /**
     * like
     */
    @Test
    public void test06Like(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        StudentDao studentDao = sqlSession.getMapper(StudentDao.class);
        List<Student> students = studentDao.selectStudentLike("%a%");
        students.forEach(System.out::println);
    }
    /**
     * Dao方法传入的参数类型,多个参数:使用@Param()
     * Dao方法传入的参数类型,使用对象:使用对象的属性
     */
    @Test
    public void test05ParameterType(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        StudentDao studentDao = sqlSession.getMapper(StudentDao.class);
        List<Student> students = studentDao.selectStudentByNameAndAge("aa", 20);
        //使用对象传递参数
//        Student student = new Student();
//        student.setAge(20);
//        student.setName("bb");
//        List<Student> students = studentDao.selectStudentByNameAndAge2(student);
        students.forEach(System.out::println);
    }
    /**
     * Dao方法传入的参数类型,单个简单参数
     */
    @Test
    public void test04ParameterType(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        StudentDao studentDao = sqlSession.getMapper(StudentDao.class);
        Student student = studentDao.selectStudentById(1001);
        System.out.println(student);
    }

    /**
     * 使用Mybatis 的getMapper(),自动创建接口实现类的对象
     */
    @Test
    public void test03Mapper(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        StudentDao studentDao = sqlSession.getMapper(StudentDao.class); //自动创建接口实现类对象
        List<Student> students = studentDao.selectStudents();
        students.forEach(System.out::println);
    }
    /**
     * 使用Dao实现类
     */
    @Test
    public void test02DaoImpl() {
//        StudentDao studentDao = new StudentDaoImpl();
//        List<Student> students = studentDao.selectStudents();
//        students.forEach(System.out::println);
//
//        int num = studentDao.insertStudent(new Student(1005, "ee", "ee@xx", 22));
//        System.out.println("insert num: " + num);
    }

    //首次使用
    @Test
    public void test01() throws IOException {
        //获取session
//        InputStream is = Resources.getResourceAsStream("mybatis.xml");
//        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
//        SqlSession sqlSession = factory.openSession();
//        //执行sql
//        Student student = new Student(1004,"dd","dd@123.com",21);
//        int nums = sqlSession.insert("com.bingmous.dao.StudentDao.insertStudent",student);
//        System.out.println(nums);
//        //提交事务,mybatis默认不提交
//        sqlSession.commit();
//        sqlSession.close();
    }
}
  • 测试动态sql方法
/**
 * created by Bingmous on 2021/7/6 20:27
 */
public class TestDynamicSQL {

    /**
     * <where></where> <if></if>标签的使用
     * 注意:null值会被解析成空字符串,在标签中,空字符串用单引号表示
     *      Dao中即使是单个简单参数也必须使用@Param,或者使用对象参数
     */
    @Test
    public void test01() {
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        StudentDao studentDao = sqlSession.getMapper(StudentDao.class);
        Student student = new Student();
        student.setName("");
//        List<Student> students = studentDao.selectDynamicSQL(student);
//        List<Student> students = studentDao.selectDynamicSQL(null,10);
//        List<Student> students = studentDao.selectDynamicSQL(10);

        var student1 = new Student();
        student1.setId(1001);
        var student2 = new Student();
        student2.setId(1002);
        var list = new ArrayList<Student>();
        list.add(student1);
        list.add(student2);
        List<Student> students = studentDao.selectDynamicSQL2(list);
        students.forEach(System.out::println);
        sqlSession.commit();
        sqlSession.close();
    }
}
  • 测试pagehelper
/**
 * created by Bingmous on 2021/7/6 22:46
 */
public class TestPageHelper {
    @Test
    public void testPageHelper() {
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        StudentDao studentDao = sqlSession.getMapper(StudentDao.class);

        PageHelper.startPage(2,2); //在查询之前调用即可
        List<Student> students = studentDao.selectStudents();
        students.forEach(System.out::println);

        PageHelper.startPage(3,2);
        List<Student> students2 = studentDao.selectStudents();
        students2.forEach(System.out::println);

        sqlSession.commit();
        sqlSession.close();
    }
}

posted on 2021-07-07 10:33  Bingmous  阅读(68)  评论(0编辑  收藏  举报