栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Mybatis

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Mybatis

Mybatis

1.搭建环境

<dependencies>
   

    <dependency>
        <
groupId>mysqlgroupId>
        <
artifactId>mysql-connector-javaartifactId>
        <
version>8.0.16version>
    dependency>
   

    <dependency>
        <
groupId>org.mybatisgroupId>
        <
artifactId>mybatisartifactId>
        <
version>3.5.7version>
    dependency>
   

    <dependency>
        <
groupId>junitgroupId>
        <
artifactId>junitartifactId>
        <
version>4.12version>
    dependency>
dependencies>

2.创建模块

  1. 编写mybatis的核心配置文件&t;?xm version="1.0" encoding="UTF-8" ?> &t;!DOCTYPE configuration         PUBLIC "-//mybatis.org//DTD Config 3.0//EN"         "http://mybatis.org/dtd/mybatis-3-config.dtd"> &t;!--configuration核心配置文件--> &t;configuration>     &t;environments defaut="deveopment">         &t;environment id="deveopment">             &t;transactionManager type="JDBC"/>             &t;dataSource type="POOLED">                 &t;property name="driver" vaue="com.mysq.jdbc.Driver"/>                 &t;property name="ur" vaue="jdbc:mysq://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf8&useSSL=fase&serverTimezone=Asia/Shanghai&useSSL=fase&alowPublicKeyRetrieval=true"/>                 &t;property name="username" vaue="root"/>                 &t;property name="password" vaue="123456"/>             &t;/dataSource>         &t;/environment>     &t;/environments> &t;/configuration>

  1. 编写mybatis工具类pubic class MybatisUtis {     private static SqSessionFactory sqSessionFactory ;     static {         try {             //使用mybatis第一步,必须的一部             //获取sqSessionFactory对象             String resource = "mybatis-config.xm";             InputStream inputStream = Resources.getResourceAsStream(resource);             sqSessionFactory = new SqSessionFactoryBuilder().buid(inputStream);         } catch (IOException e) {             e.printStackTrace();         }     } //    既然有了 SqSessionFactory,顾名思义,我们可以从中获得 SqSession 的实例。 // SqSession 提供了在数据库执行 SQL 命令所需的所有方法。你可以通过 SqSession 实例来直接执行已映射的 SQL 语句。     pubic static SqSession getSqSession(){         return sqSessionFactory.openSession();     } }

3.编写代码

  1. 实体类pubic class User {     private int id;     private String name;     private String pwd;     pubic User() {     }     pubic User(int id, String name, String pwd) {         this.id = id;         this.name = name;         this.pwd = pwd;     }     pubic int getId() {         return id;     }     pubic void setId(int id) {         this.id = id;     }     pubic String getName() {         return name;     }     pubic void setName(String name) {         this.name = name;     }     pubic String getPwd() {         return pwd;     }     pubic void setPwd(String pwd) {         this.pwd = pwd;     }     @Override     pubic String toString() {         return "User{" +                 "id=" + id +                 ", name='" + name + ''' +                 ", pwd='" + pwd + ''' +                 '}';     } }
  2. 接口pubic interface UserDao {     List&t;User> getUserList(); }
  3. 接口实现类&t;?xm version="1.0" encoding="UTF-8" ?> &t;!DOCTYPE mapper         PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"         "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> &t;!--namespace=绑定一个对应的Dao/Mapper接口--> &t;mapper namespace="com.cheng.dao.UserDao">     &t;!--查询语句-->     &t;seect id="getUserList" resutType="com.cheng.pojo.User">        seect  * from  mybatis.user;     &t;/seect> &t;/mapper>

3.测试

public class UserDaoTest {

    @Test

    public void test(){



        //第一步:获取SqlSession对象

        SqlSession sqlSession = MybatisUtils.getSqlSession();



        //方式一:getMapper

        UserDao userDao = sqlSession.getMapper(UserDao.class);

        List<User> userList = userDao.getUserList();



        for (User user : userList) {

            System.out.println(user);

        }



        //关闭SqlSession

        sqlSession.close();

    }

}

maven文件导出失败的问题

<build>

    <resources>

        <resource>

            <directory>src/main/resourcesdirectory>

            <includes>

                <include>***.xmlinclude>

            includes>

            <filtering>falsefiltering>

        resource>

        <resource>

            <directory>src/main/javadirectory>

            <includes>

                <include>***.xmlinclude>

            includes>

            <filtering>falsefiltering>

        resource>

    resources>

build>

3.CRUD

1、namespace

Namespace中的包名要和Dao/Mapper接口的包名一致

2、select

选择,查询语句;

  1. Id:就是对应的namespace中的方法名
  2. resultType:sql语句的返回值
  3. parameterType:参数类型

增删改操作

  1. 接口

  2. //根据ID查询用户
    User getUserById(int id);

    //增加一个用户
    int addUser(User user);

    //修改用户
    int UpdateUser(User user);

    //删除一个用户
    int DeleteUser(int id);
  3. 实现类

  4. <insert id="addUser" parameterType="com.cheng.pojo.User" >
       
    insert into mybatis.user(id, name, pwd) values (#{id},#{name},#{pwd})
    insert>


    <update id="UpdateUser" parameterType="com.cheng.pojo.User">
       
    update mybatis.user set name=#{name},pwd=#{pwdwhere id=#{id} ;
    update>


    <delete id="DeleteUser" parameterType="int">
       
    delete from mybatis.user where id=#{id};
    delete>

3.测试

增删改测试需要提交事务

7、Map

假设,我们的实体类,或者数据库中的表,字段或者参数过多,我们应当考虑使用Map!

增加用户为例:

接口

//使用Map
int addUser2(Map<String,Object> map);

实现类


<insert id="addUser2" parameterType="map" >
   
insert into mybatis.user(id, name, pwd) values (#{userid},#{username},#{userpwd})
insert>

测试

@Test
public void addUser2(){
   
SqlSession sqlSession = MybatisUtils.getSqlSession();
    UserMapper mapper = sqlSession.getMapper(UserMapper.class);

    HashMap<String, Object> map = new HashMap<String, Object>();

    map.put("userid",4);
    map.put("username","haha");
    map.put("userpwd","123123");

    mapper.addUser2(map);
    sqlSession.commit();

    sqlSession.close();
}

Map传递参数,直接在sql中取出key即可

对象传递参数,直接在sql中取对象的属性即可

只有一个基本类型参数的情况下,可以直接在sql中取到

多个参数用Map,或者注解!

8、思考题

模糊查询写法

List<User> userList = mapper.getUserLike("%h%");

4、配置解析

1、核心配置文件

Mybatis-config.xml

MyBatis 的配置文件包含了会深深影响 MyBatis 行为的设置和属性信息。

configuration(配置)

  • properties(属性)
  • settings(设置)
  • typeAliases(类型别名)
  • typeHandlers(类型处理器)
  • objectFactory(对象工厂)
  • plugins(插件)
  • environments(环境配置)

  • environment(环境变量)

  • transactionManager(事务管理器)
  • dataSource(数据源)
  • databaseIdProvider(数据库厂商标识)
  • mappers(映射器)

    环境配置(environments)

    MyBatis 可以配置成适应多种环境

    不过要记住:尽管可以配置多个环境,但每个 SqlSessionFactory 实例只能选择一种环境。

  • 默认使用的环境 ID(比如:default="development")。
  • 每个 environment 元素定义的环境 ID(比如:id="development")。
  • 事务管理器的配置(比如:type="JDBC")。
  • 数据源的配置(比如:type="POOLED")。

    属性(properties)

    我们可以通过propertise属性类实现引用配置文件

    编写一个配置文件

    Db.properties

    driver=com.mysql.cj.jdbc.Driver
    url=jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai&useSSL=false&allowPublicKeyRetrieval=true
    username=root
    password=123456

    在核心配置文件引入


    <properties resource="db.properties">
        <
    property name="username" value="root"/>
        <
    property name="password" value="123456"/>
    properties>

    1. 可以直接引入外部文件
    2. 可以在其中增加一些属性配置
    3. 如果两个文件有同一个字段,优先使用外部配置文件!

    类型别名(typeAliases)

    类型别名可为 Java 类型设置一个缩写名字。 它仅用于 XML 配置,意在降低冗余的全限定类名书写

    给单个类起别名


    <select id="getUserList" resultType="User" >
      
    select  * from  mybatis.user;
    select>

    也可以指定一个包名,MyBatis 会在包名下面搜索需要的 Java Bean

    扫描实体类的包,它的默认别名为这个类名的首字母小写!

    <typeAliases>
        <
    package name="com.cheng.pojo">package>
    typeAliases>

    在实体类比较少的时候,建议使用第一种

    如果实体类比较多的时候,建议使用第二种

    第一种可以DIY,第二种则不行,如果非要进行diy,需要在实体类上加注解

    //实体类
    @Alias("hello")
    public class User {

    设置(settings)

    cacheEnabled:     全局性地开启或关闭所有映射器配置文件中已配置的任何缓存

    lazyLoadingEnabled: 延迟加载的全局开关。当开启时,所有关联对象都会延迟加载。 特定关联关系中可通过设置 fetchType 属性来覆盖该项的开关状态。

    其他配置

  • typeHandlers(类型处理器)
  • objectFactory(对象工厂)
  • plugins(插件)

    映射器(mappers)

    使用class文件绑定注册的注意点

    1. 接口和他的Mapper配置文件必须同名!
    2. 接口和他的Mapper配置文件必须在同一个包下

    解决属性名和字段名不一致的问题

    新建一个项目,拷贝之前的,测试实体类字段不一致的情况

    解决方法:

    1. 起别名
    2. <select id="getUserById" parameterType="int" resultType="com.cheng.pojo.User">
         
      select id,name,pwd as password from mybatis.user where id=#{id}
      select>
    3. resultMap

    结果集映射


    <resultMap id="UserMap" type="User">
       

        <result column="id" property="id"/>
        <
    result column="name" property="name"/>
        <
    result column="pwd" property="password"/>
    resultMap>


    <select id="getUserById" parameterType="int" resultMap="UserMap">
       
    select * from mybatis.user where id=#{id}
    select>

    resultMap 元素是 MyBatis 中最重要最强大的元素。

    6、日志

    6.1、日志工厂

    如果一个数据库操作,出现了异常,我们需要排错,日志就是最好的助手!

    曾经:sout、debug

    现在:日志工厂!

    logImpl       指定 MyBatis 所用日志的具体实现,未指定时将自动查找


    SLF4J

    LOG4J 【掌握】}

    LOG4J2

    JDK_LOGGING

    COMMONS_LOGGING

    STDOUT_LOGGING【掌握】}

    NO_LOGGING

    在Mybatis中具体使用哪个日志实现,在设置中设定

    STDOUT_LOGGING标准日志输出


    <settings>
        <
    setting name="logImpl" value="STDOUT_LOGGING"/>
    settings>

    6.2、Log4j

    1.先导入包

        log4j

        log4j

        1.2.17

    2.Log4g.properties

    #将等级为DEBUG的日志信息输出到console和file这两个目的地,console和file的定义在下面的代码
    log4j.rootLogger=DEBUG,console,file

    #控制台输出的相关设置
    log4j.appender.console = org.apache.log4j.ConsoleAppender
    log4j.appender.console.Target = System.out
    log4j.appender.console.Threshold=DEBUG
    log4j.appender.console.layout = org.apache.log4j.PatternLayout
    log4j.appender.console.layout.ConversionPattern=[%c]-%m%n

    #文件输出的相关设置
    log4j.appender.file = org.apache.log4j.RollingFileAppender
    log4j.appender.file.File=./log/cheng.log
    log4j.appender.file.MaxFileSize=10mb
    log4j.appender.file.Threshold=DEBUG
    log4j.appender.file.layout=org.apache.log4j.PatternLayout
    log4j.appender.file.layout.ConversionPattern=[%p][%d{yy-MM-dd}][%c]%m%n

    #日志输出级别
    log4j.logger.org.mybatis=DEBUG
    log4j.logger.java.sql=DEBUG
    log4j.logger.java.sql.Statement=DEBUG
    log4j.logger.java.sql.ResultSet=DEBUG
    log4j.logger.java.sql.PreparedStatement=DEBUG

    3.配置log4j为日志的实现


    <settings>
        <setting name="logImpl" value="LOG4J"/>
    settings>

    4.loh4j的使用,直接测试运行

    简单使用

    1. 在要使用log4j的类中,导入包import org.apache.log4j.Logger;
    2. 日志对象,参数为当前类的class

    static Logger logger = Logger.getLogger(UserDaoTest.class);

    1. 日志级别
    2. logger.info("info:进入了log4j");
      logger.debug("debug:进入了log4j");
      logger.error("error:进入了log4j");

    7、分页

    使用limit分页

    select * from user limit 0,2;

    使用mytatis实现分页

    1. 接口

    //分页
    List<User> getUserByLimit(Map<String,Integer> map);

    1. Mapper.xml


    <select id="getUserByLimit" parameterType="map" resultMap="UserMap">
       
    select * from mybatis.user limit #{startIndex},#{pageSize}
    select>

    1. 测试

    @Test
    public void getUserByLimit(){
       
    SqlSession sqlSession = MybatisUtils.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);

        HashMap<String, Integer> map = new HashMap<String, Integer>();
        map.put("startIndex",0);
        map.put("pageSize",2);


        List<User> userList = mapper.getUserByLimit(map);

        for (User user : userList) {
           
    System.out.println(user);
        }

    }

    7.1、RowBounds分页

    不在使用sql实现分页

    1.接口

    //分页RowBounds
    List<User> getUserByRowBounds();

    2.mapper.xml


    <select id="getUserByRowBounds"  resultMap="UserMap">
       
    select * from mybatis.user
    select>

    3.测试

    @Test
    public void getUserByRowBounds(){
       
    SqlSession sqlSession = MybatisUtils.getSqlSession();

        //通过RowBounds实现
        RowBounds rowBounds = new RowBounds(1, 2);

        //通过java代码层面实现分页
        List<User> userList = sqlSession.selectList("com.cheng.dao.UserMapper.getUserByRowBounds",null,rowBounds);

        for (User user : userList) {
           
    System.out.println(user);
        }

       
    sqlSession.close();
    }

    7.2、分页插件

    8、使用注解开发

    接口

    @Select("select * from user")
    List<User> getUsers();

    测试

    @Test
    public void test(){
       
    SqlSession sqlSession = MybatisUtils.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        List<User> users = mapper.getUsers();
        for (User user : users) {
           
    System.out.println(user);
        }
       
    sqlSession.close();
    }

    8.3、CRUD

    我们可以在工具类创建的时候实现自动提交事务

    接口

    @Select("select * from user")
    List<User> getUsers();

    //方法存在多个参数,所有的参数前面必须加上@Param("id")注解
    @Select("select * from user where id = #{id}")
    User getUserById(@Param("id") int id);

    @Insert("insert into user(id,name,pwd) value(#{id},#{name},#{password})")
    int addUser(User user);

    @Update("update user set name=#{name},pwd=#{password} where id=#{id} ")
    int upDateUser(User user);

    @Delete("delete from user where id=#{uid}")
    int deleteUser(@Param("uid") int id);

    【注意:我们必须将接口注册绑定到我们的核心配置文件中!】

    关于@Param()注解

    1. 基本类型的参数或者String类型,需要加上
    2. 引用类型不需要加

    9、Lombok(不建议使用)

    使用步骤:

    1. 在IDEA中安装Lombok插件!
    2. 在项目中导入lombok的jar包

        org.projectlombok

        lombok

        1.18.10

        provided

    @Data:无参构造,get,set,tostring,hashcode,equals

    @AllArgsConstructor

    @NoArgsConstructor

    10、多对一处理

    按照查询嵌套处理



    <select id="getStudent" resultMap="StudentTeacher">
       
    select * from student;
    select>
    <
    resultMap id="StudentTeacher" type="Student">
        <
    result property="id" column="id"/>
        <
    result property="name" column="name"/>
       

        <association property="teacher" column="tid" javaType="Teacher" select="getTeacher"/>

    resultMap>

    <
    select id="getTeacher" resultType="Teacher">
       
    select * from mybatis.teacher where id=#{id};
    select>

    按照结果嵌套处理


    <select id="getStudent2" resultMap="StudentTeacher2">
       
    select s.id sid,s.name sname,t.name tname
        from student s,teacher t
        where s.tid=t.id;
    select>
    <
    resultMap id="StudentTeacher2" type="Student">
        <
    result property="id" column="sid"/>
        <
    result property="name" column="sname"/>
        <
    association property="teacher" javaType="Teacher">
            <
    result property="name" column="tname"/>
        association>
    resultMap>

    11、一对多处理

    实体类

    老师

    @Data
    public class Teacher {
       
    private int id;
        private String name;

        //一个老师拥有多个学生
        private List<Student> students;
    }

    学生

    @Data
    public class Student {
       
    private int id;
        private String name;
        private int tid;
    }

    按照结果嵌套处理


    <select id="getTeacher" resultMap="TeacherStudent">
       
    select s.id sid,s.name sname,t.name tname,t.id tid
        from student s,teacher t
        where s.tid=t.id and t.id=#{tid};
    select>
    <
    resultMap id="TeacherStudent" type="Teacher">
        <
    result property="id" column="tid"/>
        <
    result property="name" column="tname"/>
       

        <collection property="students" ofType="Student">
            <
    result property="id" column="sid"/>
            <
    result property="name" column="sname"/>
            <
    result property="tid" column="tid"/>
        collection>
    resultMap>

    按照查询嵌套处理

    <select id="getTeacher2" resultMap="TeacherStudent2">
       
    select * from mybatis.teacher where id =#{tid};
    select>

    <
    resultMap id="TeacherStudent2" type="Teacher">
        <
    collection property="students" javaType="ArrayList" ofType="Student" select="getStudentByTeacherId" column="id"/>
    resultMap>

    <
    select id="getStudentByTeacherId" resultType="Student">
       
    select * from mybatis.student where tid=#{tid}
    select>

    小结

    1. 关联:association,多对一
    2. 集合:collection,一对多
    3. javaType   &  ofType
    1. javaType用来指定实体类中属性的类型
    2. ofType用来指定映射到List或者集合中的pojo类型,泛型中的约束类型!

    12、动态SQL

    搭建环境

    创建一个基础工程

    1. 导包
    2. 编写配置文件
    3. 编写实体类
    4. 编写实体类对应Mapper接口和Mapper.xml文件

    If