mybatis学习

mybatis

1、第一个mybatis程序

1.1、搭建环境

 <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.5.4</version>
  </dependency>

1.2、创建一个模块

创建配置文件(在resource文件下添加mybatis-config.xml,db.properties文件)

  1. db.properties
driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/mybatis?serverTimezone=GMT%2B8&userSSL=true&userUnicode=true&characterEncoding=UTF-8
username=root
password=root
  1. mybatis-config.xml
<?xml version="1.0" encoding="UTF8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<!--核心配置文件-->
<configuration>
<!--    引入外部配置文件-->
    <properties resource="db.properties"/>
    
<!--设置日志-->
    <settings>
        <setting name="logImpl" value="STDOUT_LOGGING"/>
    </settings>
    
<!--设置别名-->
    <typeAliases>
        <package name="com.kuang.pojo"/>
    </typeAliases>

    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <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>
    
    <mappers>
        <mapper resource="com/kuang/dao/UserMapper.xml"/>
    </mappers>
</configuration>

xml中URL需要转义

jdbc:mysql://localhost:3306/mybatis?erverTimezone=GMT%2B8&amp;userSSL=true&amp;
userUnicode=true&amp;characterEncoding=UTF-8

编写mybatis工具类(由SqlSessionFactory获取SqlSession实例)

public class MybatisUtils {

    private static SqlSessionFactory sqlSessionFactory;

    static{
        try {
            //获取SqlSessionFactory对象
            String resource = "mybatis-config.xml";
            InputStream inputStream = Resources.getResourceAsStream(resource);
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    //由SqlSessionFactory获取SqlSession实例
    public static SqlSession getSqlSession(){
        return sqlSessionFactory.openSession();
    }
}

1.3、编写代码

  • 实体类

    package com.kuang.pojo;
    
    public class User {
        private int id;
        private String name;
        private String pwd;
    
        public int getId() {
            return id;
        }
    
        public void setId(int id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getPwd() {
            return pwd;
        }
    
        public void setPwd(String pwd) {
            this.pwd = pwd;
        }
    
        public User() {
        }
    
        public User(int id, String name, String pwd) {
            this.id = id;
            this.name = name;
            this.pwd = pwd;
        }
    
        @Override
        public String toString() {
            return "User{" +
                    "id=" + id +
                    ", name='" + name + '\'' +
                    ", pwd='" + pwd + '\'' +
                    '}';
        }
    }
    
  • Dao接口

    public interface UserDao {
        List<User> getUserList();
    }
    
  • 接口实现类

    <?xml version="1.0" encoding="UTF8" ?>
    <!DOCTYPE mapper
            PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
            "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <!--namespace=绑定一个对应的Dao/Mapper接口-->
    <mapper namespace="com.kuang.dao.UserDao">
        <select id="getUserList" resultType="com.kuang.pojo.User">
            select * from mybatis.user
        </select>
    </mapper>
    

1.4、测试

资源过滤问题解决

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

数据库连接失败

 <property name="url" value="jdbc:mysql://localhost:3306/mybatis?serverTimezone=GMT%2B8&amp;userSSL=true&amp;

UTF-8问题

将xml文件UTF-8改为UTF8

2、CRUD

增删改注意提交事务

2.1、namespace

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

2.2、select

  • id:就是对应的namespace中的方法名;
  • resultType:Sql语句执行的返回值;
  • parameterType:参数类型
  1. 编写接口

    List<User> getUserList();
    
  2. 编写对应的mapper中的sql语句

    <select id="getUserList" resultType="com.kuang.pojo.User">    select * from mybatis.user</select>
    
  3. 测试

        @Test    public void test(){        SqlSession sqlSession = MybatisUtils.getSqlSession();        UserDao userDao = sqlSession.getMapper(UserDao.class);        List<User> userList = userDao.getUserList();        for (User user : userList) {            System.out.println(user);        }//        关闭sqlSession        sqlSession.close();    }
    

2.3、Insert

<insert id="addUser" parameterType="com.kuang.pojo.User">    insert into mybatis.user (id,name,pwd) value (#{id},#{name},#{pwd});</insert>

2.4、update

<update id="updateUser" parameterType="com.kuang.pojo.User">    update mybatis.user set name = #{name},pwd=#{pwd} where id=#{id};</update>

2.5、delete

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

2.6、万能的Map

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

int addUser2(Map<String,Object> map);
<insert id="addUser2" parameterType="com.kuang.pojo.User">    insert into mybatis.user (id,name,pwd) value (#{userid},#{username},#{password});</insert>
@Testpublic void addUser2(){    SqlSession sqlSession = MybatisUtils.getSqlSession();    UserDao mapper = sqlSession.getMapper(UserDao.class);    Map<String, Object> map = new HashMap<>();    map.put("userid",7);    map.put("username","xiaohua");    map.put("password","15544");    mapper.addUser2(map);    sqlSession.commit();    sqlSession.close();}

2.7、模糊查询

  1. Java代码执行的时候,传递通配符% %

    List<User> userList = mapper.getUserLike("%李%")
    
  2. 在sql拼接中使用通配符

    select * from mybatis.user where name like "%"#{value}"%"
    

3、配置解析

  • MyBatis 的配置文件(mybatis-config.xml)包含了会深深影响 MyBatis 行为的设置和属性信息。
- configuration(配置)  - [properties(属性)]  - [settings(设置)]  - [typeAliases(类型别名)]  - [typeHandlers(类型处理器)]  - [objectFactory(对象工厂)]  - [plugins(插件)]  - environments(环境配置)    - environment(环境变量)      - transactionManager(事务管理器)      - dataSource(数据源)  - [databaseIdProvider(数据库厂商标识)]  - [mappers(映射器)

Mybatis 默认transactionManager(事务管理器):JDBC , dataSource(数据源):POOLED

3.1 类型别名(typeAliases)

类型别名可为 Java 类型设置一个缩写名字。

   <typeAliases>        <typeAlias type="com.kuang.pojo.User" alias="user"/>    </typeAliases>

也可以指定一个包名,MyBatis 会在包名下面搜索需要的 Java Bean,默认会使用首字母小写的类名作为别名

<typeAliases>    <package name="com.kuang.pojo"/></typeAliases>

也可通过在实体类上添加注解自定义别名

@Alias("user")

3.2、映射器

MapperRegistry:注册绑定我们的Mapper文件

方式一【推荐使用】

<mappers>    <mapper resource="com/kuang/dao/UserMapper.xml"/></mappers>

方式二:使用class文件注册绑定

<mappers>    <mapper class="com.kuang.dao.UserMapper"/></mappers>

方式三:使用扫描包进行绑定

<mappers>    <package name="com.kuang.dao"/></mappers>

方式2、3的注意点:

  • 接口和他的Mapper配置文件必须同名
  • 接口和他的Mapper配置文件必须在同一包下

3.3、生命周期和作用域

不同作用域和生命周期类别是至关重要的,因为错误的使用会导致非常严重的并发问题

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vS55G0Od-1633312136266)(E:\docs\笔记\图片\Mybatis.png)]

SqlSessionFactoryBuilder:

  • 一旦创建了 SqlSessionFactory,就不再需要它了 。
  • 局部变量

SqlSessionFactory

  • 就是数据库连接池。
  • 一旦被创建就应该在应用的运行期间一直存在 ,没有任何理由丢弃它或重新创建另一个实例 。
  • 因此 SqlSessionFactory 的最佳作用域是应用作用域。
  • 最简单的就是使用单例模式或者静态单例模式。

SqlSession

  • 每个线程都应该有它自己的 SqlSession 实例。
  • 连接到连接池的请求!
  • SqlSession 的实例不是线程安全的,因此是不能被共享的 ,所以它的最佳的作用域是请求或方法作用域。
  • 用完之后赶紧关闭,否则资源被占用。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pj2V24yn-1633312136279)(E:\docs\笔记\图片\sqlsession.png)]

这里面的每个Mapper,就代表一个具体的业务!

3、属性名与字段名不一致

User

package com.hou.pogo;public class User {    private int id;    private String name;    private String password;}

问题:

User{id=2, name=‘wang’, password=‘null’}

解决方法:

  • 起别名
<select id="getUserById" resultType="User"    parameterType="int">        select id,name,pwd as password from mybatis.user where id = #{id}</select>
  • resultMap 结果集映射
<?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绑定一个对应的mapper接口--><mapper namespace="com.hou.dao.UserMapper">    <select id="getUserById" resultMap="UserMap" parameterType="int">        select * from mybatis.user where id = #{id}    </select>    <!--结果集映射-->    <resultMap id="UserMap" type="User">        <!--colunm 数据库中的字段,property实体中的属性-->        <result column="id" property="id"></result>        <result column="name" property="name"></result>        <result column="pwd" property="password"></result>    </resultMap></mapper>

4、日志

4.1、日志工厂

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

  • SLF4J
  • LOG4J [掌握]
  • LOG4J2
  • JDK_LOGGING
  • COMMONS_LOGGING
  • STDOUT_LOGGING [掌握]
  • NO_LOGGING

STDOUT_LOGGING 标志日志输出

4.2、 Log4j使用

  • 导包
<dependency>     <groupId>log4j</groupId>     <artifactId>log4j</artifactId>     <version>1.2.17</version></dependency>
  • 新建log4j.properties文件
### set log levels ###log4j.rootLogger = DEBUG,console,file### 输出到控制台 ###log4j.appender.console = org.apache.log4j.ConsoleAppenderlog4j.appender.console.Target = System.outlog4j.appender.console.Threshold = DEBUGlog4j.appender.console.layout = org.apache.log4j.PatternLayoutlog4j.appender.console.layout.ConversionPattern = [%c]-%m%n### 输出到日志文件 ###log4j.appender.file=org.apache.log4j.RollingFileAppenderlog4j.appender.file.File=./log/hou.loglog4j.appender.file.MaxFileSize=10mb log4j.appender.file.Threshold=DEBUG log4j.appender.file.layout=org.apache.log4j.PatternLayoutlog4j.appender.file.layout.ConversionPattern=[%p][%d{yy-MM-dd}][%c]%m%n# 日志输出级别log4j.logger.org.mybatis=DEBUGlog4j.logger.java.sql=DEBUGlog4j.logger.java.sql.Statement=DEBUGlog4j.logger.java.sql.ResultSet=DEBUGlog4j.logger.java.sql.PreparedStatement=DEBUG
  • 配置实现
<settings>    <setting name="logImpl" value="LOG4J"/></settings>
  • Log4j使用
package com.hou.dao;import com.hou.pojo.User;import com.hou.utils.MybatisUtils;import org.apache.ibatis.session.SqlSession;import org.apache.log4j.Logger;import org.junit.Test;public class UserDaoTest {    static Logger logger = Logger.getLogger(UserDaoTest.class);    @Test    public void test(){        // 获得sqlsession对象        SqlSession sqlSession = MybatisUtils.getSqlSession();        try{            // 1.执行 getmapper            UserMapper userDao = sqlSession.getMapper(UserMapper.class);            logger.info("测试");            User user = userDao.getUserById(2);            System.out.println(user);        }catch(Exception e){            e.printStackTrace();        }finally{            //关闭            sqlSession.close();        }    }    @Test    public void testLog4j(){        logger.info("info:进入了testlog4j");        logger.debug("debug:进入了testlog4j");        logger.error("error:进入了testlog4j");    }}

简单使用

  1. 导包

    import org.apache.log4j.Logger;
    
  2. 日志对象

    static Logger logger = Logger.getLogger(UserDaoTest.class);
    
  3. 日志级别

      logger.info("info:进入了testlog4j");         logger.debug("debug:进入了testlog4j");        logger.error("error:进入了testlog4j");
    

5. 分页

5.1、Limit 分页

SELECT * from user limit startIndex,pageSize;SELECT * from user limit 0,2;public interface UserMapper {    List<User> getUserByLimit(Map<String, Integer> map);}

xml

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

test类

@Testpublic void getByLimit(){    SqlSession sqlSession = MybatisUtils.getSqlSession();    UserMapper mapper = sqlSession.getMapper(UserMapper.class);    Map<String, Integer> map = new HashMap<String, Integer>();    map.put("startIndex", 1);    map.put("pageSize", 2);    List<User> userList = mapper.getUserByLimit(map);    for(User user:userList){        System.out.println(user);    }    sqlSession.close();}

2. RowBounds分页

@Test

@Testpublic void getUserByRow(){    SqlSession sqlSession = MybatisUtils.getSqlSession();    //RowBounds实现    RowBounds rowBounds = new RowBounds(1, 2);    //通过java代码层面    List<User> userList = sqlSession.selectList        ("com.hou.dao.UserMapper.getUserByRowBounds",         null,rowBounds);    for (User user : userList) {        System.out.println(user);    }    sqlSession.close();}

3. 分页插件

  • pageHelper

6、Mybatis详细执行流程:

  1. Resource获取全局配置文件
  2. 实例化SqlsessionFactoryBuilder
  3. 解析配置文件流XMLCondigBuilder
  4. Configration所有的配置信息
  5. SqlSessionFactory实例化
  6. trasactional事务管理
  7. 创建executor执行器
  8. 创建SqlSession
  9. 实现CRUD
  10. 查看是否执行成功
  11. 提交事务
  12. 关闭

7、 Lombok

@Data:无参构造,get,set,toString,hashCode

@AllArgsConstructor :有参构造

@NoArgsConstructor:无参构造

上一篇:Spring整理_06_整合MyBatis


下一篇:每天一个Linux命令 3