ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

Mybatis框架技术总结(一),Java高级进阶学习资料

2021-09-20 09:34:04  阅读:114  来源: 互联网

标签:Java 进阶 UserMapper public mybatis sqlSession user Mybatis id


[](

)2.3.1.1、标准日志实现

指定 MyBatis 应该使用哪个日志记录实现,如果此设置不存在,则会自动发现日志记录实现

mybatis-config.xml核心配置文件配置


<settings>

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

</settings>



[](

)2.3.1.2、Log4j日志实现

使用步骤:

  1. 导入Log4j的包

<!-- https://mvnrepository.com/artifact/log4j/log4j -->

<dependency>

    <groupId>log4j</groupId>

    <artifactId>log4j</artifactId>

    <version>1.2.17</version>

</dependency>



  1. Log4j配置文件编写

    • 在resources目录下新建log4j.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/kuang.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



  1. 在mybatis核心配置文件中实现

<settings>

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

</settings>



  1. 测试类中测试

//注意导包:org.apache.log4j.Logger

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



@Test

public void textLog4j(){

    logger.info("info:进入了selectUser方法");

    logger.debug("debug:进入了selectUser方法");

    logger.error("error:进入了selectUser方法");

}



  1. 可以看到生成的日志文件

在这里插入图片描述

[](

)2.3.2、开启驼峰命名法

在这里插入图片描述

使用步骤:

  • 在mybatis核心配置文件中设置下划线驼峰自动转换

<settings>

	<!-- 开启驼峰命名转化-->

    <setting name="mapUnderscoreToCamelCase" value="true"/>

</settings>



[](

)1.6、mappers标签


该标签的作用是加载映射的,加载方式有如下几种(主要使用第三种):

  • 使用相对类路径的资源引用xml文件,注意路径是用/而不是用点

<mappers>

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

</mappers>



  • 使用映射器接口实现类的完全限定类名,引用的是接口

<mappers>

    <mapper class="com.kuang.dao.TeacherMapper" />

    <mapper class="com.kuang.dao.StudentMapper" />

</mappers>



  • 使用扫描包进行注册绑定

<!-- 定义dao接口所在的包。要求xml文件存放的路径和dao接口的包名要对应 -->

<mappers>

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

</mappers>



[](

)3、Mybatis相应API

================================================================================

[](

)3.1、Resources


加载资源的工具类:

| 返回值 | 方法名 | 说明 |

| --- | --- | --- |

| InputStream | getResourceAsStream(String fileName) | 通过类加载器返回指定资源的字节输入流 |


//1.加载核心配置文件

InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");

// 我们也可以自己加载

InputStream inputStream = 类名.class.getClassLoader().getResourceAsStream("mybatis-config.xml");



[](

)3.2、SqlSessionFactoryBuilder


SqlSessionFactoryBuilder工厂构建器:

  • SqlSessionFactory.build(InputStream inputStream)

  • 通过加载mybatis的核心文件的输入流的形式构建一个SqlSessionFactory对象


String resource = "org/mybatis/example/mybatis-config.xml";

InputStream inputStream = Resources.getResourceAsStream(resource);

SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);



[](

)3.3、SqlSessionFactory


SqlSessionFactory有多个方法创建SqlSession实例,常用的有如下两个:

  • SqlSessionFactory.openSession :会默认开启一个事务,但事务不会自动提交,也就意味着需要手动提交该事务,更新操作数据才会持久化到数据库中

  • SqlSessionFactory.openSession(boolean autoCommit) : 参数为是否自动提交,如果设置为true,那么不需要手动提交事务

| 返回值 | 方法名 | 说明 |

| --- | --- | --- |

| SqlSession | openSession() | 通过SqlSession构建者对象,并开启手动提交事务 |

| SqlSession | openSession(boolean autoCommit) | 通过SqlSession构建者对象,如果参数为true,则开启自动提交事务 |

[](

)3.4、SqlSession


SqlSession 提供了在数据库执行 SQL 命令所需的所有方法 。它还提供了事务的相关操作。

成员方法如下:

  • sqlSession.commit():提交事务

  • sqlSession.rollback():回滚事务

  • sqlSession.close():释放资源

[](

)3.5、mybatis工具类


我们通常将mybatis获取SqlSession实例封装成一个工具类


public class MybatisUtils {

    private static SqlSessionFactory sqlSessionFactory;

    static{

        try {

            // 使用Mybatis

            // 第一步: 获取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(){

//        SqlSession sqlSession = sqlSessionFactory.openSession();

//        return sqlSession;

        return sqlSessionFactory.openSession();

    }

}



[](

)4、Mybatis开发方式

===============================================================================

[](

)4.0、Mybatis传统方式开发


[](

)4.0、Dao 层传统实现方式


  • 分层思想:控制层(controller)、业务层(service)、持久层(dao)。

  • 调用流程

在这里插入图片描述

[](

)4.1、Dao层代理开发方式


  • Mapper 接口开发方法只需要程序员编写Mapper 接口(相当于Dao 接口)

  • 我们之前的开发规范是编写Dao接口,之后再编写实现类DaoImpl

  • 代理开发规范是编写Dao接口,之后再编写xml配置文件

Mapper 接口开发需要遵循以下规范:

  1. Mapper.xml文件中的namespace与mapper接口的全限定名相同

  2. Mapper接口方法名和Mapper.xml中定义的每个statement的id相同

  3. Mapper接口方法的输入参数类型和mapper.xml中定义的每个sql的parameterType的类型相同

  4. Mapper接口方法的输出参数类型和mapper.xml中定义的每个sql的resultType的类型相同

在这里插入图片描述

[](

)4.2、参数的获取


[](

)4.2.1、一个参数

[](

)4.2.1.1、基本参数

我们可以使用#{}直接来取值,写任意名字都可以获取到参数。但是一般用方法的参数名来取。

例如:

  • 接口中方法定义如下

public interface UserDao {

    

    User findUser(Integer id);

    

}



  • xml中的内容如下

<select id="findUser" parameterType="int" resultType="com.sangeng.pojo.User">

    select * from user where id = #{id}

</select>



  • 测试

@Test

public void findUser() throws IOException {

   //定义mybatis配置文件的路径

   String resource = "mybatis-config.xml";

   InputStream inputStream = Resources.getResourceAsStream(resource);

   SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);



   //获取Sqlsession对象

   SqlSession sqlSession = sqlSessionFactory.openSession();

   //获取UserDao实现类对象

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

   //调用方法测试

   User user = userDao.findUser(2);

   System.out.println(user);

   //释放资源

   sqlSession.close();

}



[](

)4.2.1.2、POJO

我们可以使用POJO中的属性名来获取对应的值。

例如:

  • 接口中方法定义如下

public interface UserDao {

    

    User findByUser(User user);

    

}



  • xml中的内容如下

<select id="findByUser" resultType="com.sangeng.pojo.User">

    select * from user where id = #{id} and username = #{username} and age = #{age} and address = #{address}

</select>



  • 测试

@Test

public void findByUser() throws IOException {

    //定义mybatis配置文件的路径

    String resource = "mybatis-config.xml";

    InputStream inputStream = Resources.getResourceAsStream(resource);

    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);



    //获取Sqlsession对象

    SqlSession sqlSession = sqlSessionFactory.openSession();

    //获取UserDao实现类对象

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

    //调用方法测试

    User byUser = userDao.findByUser(new User(2, "PDD", 25, "上海"));

    System.out.println(byUser);

    //释放资源

    sqlSession.close();

}



[](

)4.2.1.3、Map

我们可以使用map中的key来获取对应的值。

例如:

  • 接口中方法定义如下

public interface UserDao {

    

    User findByMap(Map map);

    

}



  • xml中内容如下

<select id="findByMap" resultType="com.sangeng.pojo.User">

    select * from user where id = #{id} and username = #{username} and age = #{age} and address = #{address}

</select>



  • 测试

@Test

public void findByMap() throws IOException {

    //定义mybatis配置文件的路径

    String resource = "mybatis-config.xml";

    InputStream inputStream = Resources.getResourceAsStream(resource);

    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);



    //获取Sqlsession对象

    SqlSession sqlSession = sqlSessionFactory.openSession();

    //获取UserDao实现类对象

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

    //调用方法测试

    Map map = new HashMap();

    map.put("id",2);

    map.put("username","PDD");

    map.put("age",25);

    map.put("address","上海");

    User byMap = userDao.findByMap(map);

    System.out.println(byMap);

    //释放资源

    sqlSession.close();

}



[](

)4.2.2、多个参数

Mybatis会把多个参数放入一个Map集合中,默认的key是argx和paramx这种格式。

例如:

  • 接口中方法定义如下

    • 我们一般在方法参数前使用@Param来设置参数名。

public interface UserDao {

    

    User findByCondition(@Param("tid") Integer id,@Param("username")String username);

    

}



  • xml中内容如下

<select id="findByCondition" resultType="com.sangeng.pojo.User">

     select * from user where id = #{tid} and username = #{username}

</select>



  • 测试

@Test

public void findByCondition() throws IOException {

    //定义mybatis配置文件的路径

    String resource = "mybatis-config.xml";

    InputStream inputStream = Resources.getResourceAsStream(resource);

    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);



    //获取Sqlsession对象

    SqlSession sqlSession = sqlSessionFactory.openSession();

    //获取UserDao实现类对象

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

    //调用方法测试

    User pdd = userDao.findByCondition(2, "PDD");

    System.out.println(pdd);

    //释放资源

    sqlSession.close();

}



[](

)4.2.3、总结

  • 建议如果只有一个参数的时候不用做什么特殊处理。

  • 如果是有多个参数的情况下一定要加上@Param来设置参数名。

[](

)4.2.4、获取参数时 #{}和${}的区别

  • 如果使用#{}.他是预编译的sql可以防止SQL注入攻击

  • 如果使用${}他是直接把参数值拿来进行拼接,这样会有SQL注入的危险

[](

)5、CRUD操作

==========================================================================

[](

)5.1、select


select 语句有很多属性可以详细配置每一条SQL语句

  • id: 就是对应的namespace中的方法名

  • resultType: Sql语句执行的返回值【完整的类名或者别名】

  • parameterType:传入SQL语句的参数类型

示例

  1. 在UserMapper中添加对应方法

public interface UserMapper {

    // 查询全部用户

    List<User> getUserList();

}    



  1. 在UserMapper.xml中添加Select语句

<mapper namespace="com.kuang.dao.UserMapper">

    <select id="getUserList" resultType="com.kuang.pojo.User">

        select * from mybatis.user;

    </select>

</mapper>



  1. 在测试类中测试

public void test(){

   //第一步:获得SqlSession对象

   SqlSession sqlSession = MybatisUtils.getSqlSession();

	//方式一:执行SQL

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

    

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

    for (User user : userList) {

            System.out.println(user);

        }

        // 关闭SqlSession

        sqlSession.close();    

}



示例2:根据id查询用户

  1. 在UserMapper中添加对应方法

public interface UserMapper {

    // 根据ID查询用户

    User getUserById(int id);

}  



  1. 在UserMapper.xml中添加Select语句

<select id="getUserById" parameterType="int" resultType="com.kuang.pojo.User">

    select * from mybatis.user where id = #{id}

</select>



  1. 在测试类中测试

@Test

public void getUserById(){

    SqlSession sqlSession = MybatisUtils.getSqlSession();

    UserMapper mapper = sqlSession.getMapper(UserMapper.class);

    

    

    User user = mapper.getUserById(1);

    System.out.println(user);



    sqlSession.close();

}



[](

)5.2、insert


需求:给数据库增加一个用户

  1. 在UserMapper接口中添加对应的方法

public interface UserMapper{

    // insert

    int addUser(User user);

}



  1. 在UserMapper.xml中添加insert语句

<insert id="addUser" parameterType="com.kuang.pojo.User">

        insert into mybatis.user(id, name, pwd) VALUES (#{id},#{name},#{pwd})

</insert>



  1. 在测试类中测试

// 增删改需要提交事务

@Test

public void addUser(){

    SqlSession sqlSession = MybatisUtils.getSqlSession();

    UserMapper mapper = sqlSession.getMapper(UserMapper.class);



    int res = mapper.addUser(new User(5, "哈哈2", "1234"));

    if(res > 0) {

        System.out.println("插入成功");

    }

    // 提交事务

    sqlSession.commit();

    sqlSession.close();

}



  • 在插入操作中,使用parameterType属性指定要插入的数据类型

  • Sql语句中使用#{实体属性名}方式引用实体中的属性值

  • 增、删、改操作涉及数据库数据变化,所以要使用sqlSession对象显式的提交事务,即sqlSession.commit()

[](

)5.3、update


需求:修改用户的信息

  1. 在UserMapper接口中添加对应的方法

public interface UserMapper{

    // 修改用户

    int updateUser(User user);

}



  1. 在UserMapper.xml中添加update语句

<update id="updateUser" parameterType="com.kuang.pojo.User">

        update mybatis.user set name=#{name},pwd=#{pwd} where id = #{id};

</update>



  1. 在测试类中测试

@Test

    public void updateUser(){

        SqlSession sqlSession = MybatisUtils.getSqlSession();

        UserMapper mapper = sqlSession.getMapper(UserMapper.class);

        

        

        int res = mapper.updateUser(new User(4, "呵呵", "123123"));

        if(res > 0){

            System.out.println("修改成功");

        }



        sqlSession.commit();

        sqlSession.close();

    }



[](

)5.4、delete


需求:根据id删除一个用户

  1. 在UserMapper接口中添加对应的方法

public interface UserMapper{

    // 删除一个用户

    int deleteUser(int id);

}



  1. 在UserMapper.xml中添加update语句

<delete id="deleteUser" parameterType="int">

        delete from mybatis.user where id = #{id}

</delete>



  1. 在测试类中测试

@Test

public void deleteUser(){

    SqlSession sqlSession = MybatisUtils.getSqlSession();

    UserMapper mapper = sqlSession.getMapper(UserMapper.class);

    int res = mapper.deleteUser(4);

    if(res > 0){

        System.out.println("删除成功");

    }



    sqlSession.commit();

    sqlSession.close();

}



[](

)5.5、万能Map


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

[](

)5.5.1、select

  1. 在UserMapper中添加对应方法

public interface UserMapper{

    // 万能的map

    User getUserById2(Map<String,Object> map);

}



  1. 在UserMapper.xml中添加insert语句

<select id="getUserById2" parameterType="map" resultType="com.kuang.pojo.User">

        select * from mybatis.user where id = #{helloid} and name = #{name};

</select>



  1. 在测试类中测试

@Test

public void getUserById2(){

    SqlSession sqlSession = MybatisUtils.getSqlSession();

    UserMapper mapper = sqlSession.getMapper(UserMapper.class);

    

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

    map.put("helloId",1);

    sqlSession.close();

}



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

[](

)5.5.2、insert

  1. 在UserMapper中添加对应方法

public interface UserMapper{

    // 万能的map

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

}



  1. 在UserMapper.xml中添加insert语句

<insert id="addUser2" parameterType="map">

        insert into mybatis.user(id, name, pwd) VALUES (#{id},#{name},#{pwd})

</insert>



  1. 在测试类中测试

// 传递map的key

@Test

public void addUser2(){

    SqlSession sqlSession = MybatisUtils.getSqlSession();

    UserMapper mapper = sqlSession.getMapper(UserMapper.class);

    

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

    map.put("id",5);

    map.put("name","啦啦啦");

    map.put("pwd","123456");

    

    sqlSession.close();

}



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

[](

)6、动态SQL

=========================================================================

在实际开发中的SQL语句没有之前的这么简单,很多时候需要根据传入的参数情况动态的生成SQL语句。Mybatis提供了动态SQL相关的标签让我们使用。

[](

)6.1、if标签


可以使用if标签进行条件判断,条件成立才会把if标签中的内容拼接进sql语句中。

例如:


<select id="findByCondition" resultType="com.sangeng.pojo.User">

     select * from user 

     where  id = #{id}

    <if test="username!=null">

       and username = #{username}

    </if>

</select>



  • 如果参数username为null则执行的sql为:select * from user where id = ?

  • 如果参数username不为null则执行的sql为:select * from user where id = ? and username = ?

  • 注意:在test属性中表示参数的时候不需要写#{},写了会出问题。

[](

)6.2、trim标签


可以使用该标签动态的添加前缀或后缀,也可以使用该标签动态的消除前缀。

注意:trim标签其实在真正开发中不会太用到,主要是为了理解后面的where标签,所以这里理解即可

[](

)6.2.1、prefixOverridess属性

用来设置需要被清除的前缀,多个值可以用|分隔,注意|前后不要有空格。例如: and|or

例如:


<select id="findByCondition" resultType="com.sangeng.pojo.User">

    select * from user

    <trim prefixOverrides="and|or" >

        and

    </trim>

</select>



最终执行的sql为: select * from user

[](

)6.2.2、suffixOverrides属性

用来设置需要被清除的后缀,多个值可以用|分隔,注意|前后不要有空格。例如: and|or


<select id="findByCondition" resultType="com.sangeng.pojo.User">

    select * from user

    <trim suffixOverrides="like|and" >

        where 1=1 like

    </trim>

</select>



最终执行的sql为: select * from user 去掉了后缀like

[](

)6.2.3、prefix属性

用来设置动态添加的前缀,如果标签中有内容就会添加上设置的前缀


<select id="findByCondition" resultType="com.sangeng.pojo.User">

    select * from user

    <trim prefix="where" >

       1=1

    </trim>

</select>



最终执行的sql为:select * from user where 1=1 动态增加了前缀where

[](

)6.2.4、 suffix属性

? 用来设置动态添加的后缀,如果标签中有内容就会添加上设置的后缀


<select id="findByCondition" resultType="com.sangeng.pojo.User">

    select * from user

    <trim suffix="1=1" >

       where

    </trim>

</select>



最终执行的sql为:select * from user where 1=1 动态增加了后缀1=1

[](

)6.2.5、trim综合使用

动态添加前缀where 并且消除前缀and或者or


<select id="findByCondition" resultType="com.sangeng.pojo.User">

    select * from user

    <trim prefix="where" prefixOverrides="and|or" >

        <if test="id!=null">

            id = #{id}

        </if>

        <if test="username!=null">

            and username = #{username}

        </if>

    </trim>

</select>


## 最后

针对最近很多人都在面试,我这边也整理了相当多的面试专题资料,也有其他大厂的面经。希望可以帮助到大家。

> 最新整理面试题
> ![在这里插入图片描述](https://upload-images.jianshu.io/upload_images/24616006-379dee2451e757a1?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

> 上述的面试题答案都整理成文档笔记。也还整理了一些面试资料&最新2021收集的一些大厂的面试真题
>
> **[CodeChina开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频】](https://ali1024.coding.net/public/P7/Java/git)**

> 最新整理电子书

![在这里插入图片描述](https://upload-images.jianshu.io/upload_images/24616006-4b35c587fdc28ff3?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

> 最新整理大厂面试文档

![在这里插入图片描述](https://upload-images.jianshu.io/upload_images/24616006-ed2b9d216983310f?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

标签:Java,进阶,UserMapper,public,mybatis,sqlSession,user,Mybatis,id
来源: https://www.cnblogs.com/Java668/p/15313623.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有