JAVAEE框架技术之8-myBatis ORM框架技术参数和动态SQL语句

简介: JAVAEE框架技术之8-myBatis ORM框架技术参数和动态SQL语句

parameterType

传入多个参数

确切点是方法的输入参数,一般都是采用直接使用pojo类。此时在mapper.xml文件中的SQL语句不用再写parameterType属性,而是用arg0,arg1,arg2,arg3…或者param1,param2,param3…代替。

引出问题

/**
     * 登录
     * @param name
     * @param passworld
     */
    public User login(String name ,String password);
<!--登录-->
<select id="login" resultType="User">
    select * from tb_user where user_name = #{username} and password = #{password}
</select>
@Test
public void testLogin(){
    User u = userMapper.login("jack","123");
    System.out.println(u);
}

如果传入两个参数或者更多的参数,会发现,多个参数是找不到了,错误如下:

解决方式1

在mapper.xml中使用 0,1这样的序号去,0表示第一个参数,1表示第二个参数。(从0开始数)

<!--登录-->
    <select id="login" resultType="User">
        select * from tb_user where user_name = #{arg0} and password = #{arg1}
    </select>

或者 用param1 param2 这个时就是从1开始

<!--登录-->
    <select id="login" resultType="User">
        select * from tb_user where user_name = #{param1} and password = #{param2}
    </select>

解决方式2

通过@Param来指定参数名,你写什么就接受什么

#与$区别

1、$字符串拼接,#参数站位相当于?
2、$不能够防止sql注入,#可以防止sql注入的
3、$要考虑参类型 ,#不用考虑参数类型  
4、$可以替换sql语句任何一个内容,#只能替换参数

#的用法

######不用考虑参数类型

######可以防止sql注入

<!--登录-->
<select id="login" resultType="User">
    <!--使用#-->
    select * from tb_user where user_name = #{name} and passworld = #{password}
</select>
/**
 * 登录
 */
public User login(@Param("name") String name ,@Param("passworld") String passworld);
@Test
    public void testLogin(){
        User u = userMapper.login("jack", "123");//#不用考虑参数类型
        User u = userMapper.login("' or '1' = '1", "' or '1' = '1");//#防止sql注入
        System.out.println(u);
    }
  • 根据姓名进行模糊查询
/**
     * 根据姓名进行模糊查询
     * @param name
     * @return
     */
    public List<User> queryByLikeName(String name);
<!--根据姓名进行模糊查询-->
    <select id="queryByLikeName" resultType="User">
        select * from tb_user where user_name like concat('%',#{name},'%')
    </select>
@Test
    public void teseQueryByLikeName(){
        List<User> list = this.userMapper.queryByLikeName("ja");
        for(User user : list){
            System.out.println(user);
        }
    }

$的用法

用于字符串拼接

/**
     * 根据表名来查询
     * @param name
     */
    public List<User> queryByTableName(String name);
<!--根据表名来查询-->
    <select id="queryByTableName" resultType="User">
        select * from ${name}
    </select>
@Test
    public void testqueryByTableName(){
        List<User> list = this.userMapper.queryByTableName("tb_user");
        for(User user : list){
            System.out.println(user);
        }
    }

$ 需要考虑参数类型

$不防止sql注入

<!--登录-->
    <select id="login" resultType="User">
         <!--使用$ 需要考虑参数类型-->
        select * from tb_user where user_name = '${name}' and passworld = '${passworld}'
    </select>
/**
 * 登录
 */
public User login(@Param("name") String name ,@Param("passworld") String passworld);
@Test
    public void testLogin(){
        User u = userMapper.login("jack", "123");//$不用考虑参数类型
        User u = userMapper.login("' or '1' = '1", "' or '1' = '1");//$防止sql注入
        System.out.println(u);
    }

#和$的区别

$可以代替所有#
如果传入的数据,不是sql中的字段的时候,就不能够使用#. 
通常使用#。
选择获取参数的时候,首要选择的# 的方式
(1、可以防止sql注入,2、可以不用考虑数据类型,简化书写,3、sql是参数的话的sql,预编译的sql,速度会块一些)
当#用不了的时候,去选择$例如 ,sql需要改变是表名的情况,就可使用$的方式。
总结:能用# 就不选择$

ResultMap 用法

ResultMap 是Mybatis中最为重要的元素,使用ResultMap 可以解决两大问题:

1、pojo属性名与数据库字段名不一致问题

2、完成高级查询,一对一,一对多, 多对多(后面讲)

代码实现

<!--查询所有映射-->
    <!--
        id:resultMap的标识
        type:映射的类型
        autoMapping:true(默认) 支持 属性名与字段名自动映射  false:只针对resultMap定义的属性映射
    -->
    <resultMap id="userResultMap" type="User" autoMapping="true">        
        <!--id一般作为主键,它有自己的标签,实现属性名与字段名一一映射-->
        <id column="id" property="id"/>        
        <!--除了id以外的字段,用result标签实现属性名与字段名一一映射-->
        <result column="user_name" property="userName"/>        
        <!--如果,属性名与字段一致,可以省略不写-->
        <result column="sex" property="sex"/>
    </resultMap>
    <!--查询所有-->
    <select id="queryAllUser" resultMap="userResultMap">
        select * from tb_user
    </select>

sql片段

作用:把重复的sql语句抽出来来放到sql标签中,然后通来引入

用法1

<!--抽取sql-->
    <sql id="userColumn">
        id ,user_name ,passworld , sex
    </sql>
    <!--查询所有-->
    <select id="queryAllUser" resultMap="userResultMap">
        select <include refid="userColumn"/> from tb_user
    </select>

如出现以下问题,请参考解决即可:

去掉xml:iBatis3:sql|select|insert|update|delete|statement里面的sql校验即可

用法2

以下用法1抽取的sql只能在本xml中使用,那如何这个抽取的sql其他xml也想使用怎么办呢?用法2就是可以将sql单独抽取到一个文件中,这样其他的xml就可以直接使用

<mapper namespace="abc">
    <!--抽取sql-->
    <sql id="userColumn">
        id ,user_name ,passworld , sex
    </sql>
</mapper>
<!--查询所有-->
    <select id="queryAllUser" resultMap="userResultMap">
        select <include refid="abc.userColumn"/> from tb_user
    </select>
<!--注意别忘了:mybatis-config.xml 引入-->
<mapper resource="UserSQLMapper.xml"/>

动态sql

业务场景:在我们生活中很多业务常常遇到动态搜索的情况,比如搜索民宿,根据位置,价格,面积等等情况动态搜索,参数等信息可以根据我们需求改变,这里就涉及到了我们Mybatis常说的动态SQL。

Mybatis 动态SQL,通过 if, choose, when, otherwise, trim, where, set, foreach等标签,可组合成非常灵活的SQL语句,从而在提高 SQL 语句的准确性的同时,也大大提高了开发人员的效率。

Mybatis提供了动态SQL,也就是可以根据用户提供的参数,动态决定查询语句依赖的查询条件或SQL语句的内容。

标签名 解释
if 单条件分支判断
choose, when, otherwise 多条件分支判断
where 处理sql条件接拼where
set 处理sql条件接拼set
foreach 循环操作
trim 处理sql条件拼接

动态sql-if标签

需求1:查询男性用户,如果输入了姓名,姓名进行模糊查找,如果不输入就按男性用户来查询

/**
        查询男性用户,如果输入了姓名,姓名进行模糊查找,如果不输入就按男性用户来查询
     */
    public List<User> queryLikeByName(String name);
<!--查询男性用户,如果输入了姓名,姓名进行模糊查找,如果不输入就按男性用户来查询-->
    <select id="queryLikeByName" resultType="User">
        select * from tb_user where sex = '男'
        <if test="name != null and name !=''">
            and user_name like concat('%',#{name},'%')
        </if>
    </select>
//查询男性用户,如果输入了姓名,姓名进行模糊查找,如果不输入就按男性用户来查询
    @Test
    public void queryLikeByName() {
        List<User> list = this.userMapper.queryLikeByName("ck");
        for(User user : list){
            System.out.println(user);
        }
    }

动态sql-choose, when, otherwise标签

choose,when,otherwise 相当于java中的 if, else if的逻辑

如果其中的一个when 成立,则后的都不执行,如果所有when的都不成立,那么就执行otherwise

也就是谁在前面谁优先

需求2:查询男性用户,如果输入了姓名则按照姓名模糊查找,否则如果输入了年龄则按照年龄查找

/**
     * 查询男性用户,如果输入了姓名则按照姓名模糊查找,否则如果输入了年龄则按照年龄查找
     */
    public List<User> queryByLikeNameAndAge(@Param("name") String name , @Param("age") Integer age);
<!--查询男性用户,如果输入了姓名则按照姓名模糊查找,否则如果输入了年龄则按照年龄查找-->
    <select id="queryByLikeNameAndAge" resultType="User">
        select * from tb_user where sex = '男'
        <choose>
            <when test="name != null and name !=''">
                and user_name like concat('%',#{name},'%')
            </when>
            <when test="age != null and age !=''">
                and age like concat('%',#{age},'%')
            </when>
            <otherwise>
                and id = 12
            </otherwise>
        </choose>
    </select>
//查询男性用户,如果输入了姓名则按照姓名模糊查找,否则如果输入了年龄则按照年龄查找
  @Test
    public void queryByLikeNameAndAge(){
        List<User> list = this.userMapper.queryByLikeNameAndAge("jack", null);
        for(User user : list){
            System.out.println(user);
        }
    }

动态sql-where标签

where标签代替 sql中的where关键字

需求3:查询所有用户,如果输入了姓名按照姓名进行模糊查询,如果输入年龄,按照年龄进行查询

/**
* 查询所有用户,如果输入了姓名按照姓名进行模糊查询,如果输入年龄,按照年龄进行查询
*/
public List<User> queryByAllUserLikeNameAndAge(@Param("name") String name , @Param("age") Integer age);
<!--查询所有用户,如果输入了姓名按照姓名进行模糊查询,如果输入年龄,按照年龄进行查询-->
    <select id="queryByAllUserLikeNameAndAge" resultType="User">
        select * from tb_user
        <where>
            <if test="name != null and name!=''">
                user_name like concat('%',#{name},'%')
            </if>
            <if test="age != null and age!=''">
                and age like concat('%',#{age},'%')
            </if>
        </where>
    </select>
//查询所有用户,如果输入了姓名按照姓名进行模糊查询,如果输入年龄,按照年龄进行查询
    @Test
    public void queryByAllUserLikeNameAndAge(){
        List<User> list = this.userMapper.queryByAllUserLikeNameAndAge("c", 2);
        for(User user : list){
            System.out.println(user);
        }
    }

动态sql-set标签

set标签代替 sql中set关键字

需求4:如果名字信息不是null,则修改名字, 如果age信息不是null,同时也修改age

/**
* 如果名字信息不是null,则修改名字, 如果age信息不是null,同时也修改age
*/
public Integer updateByNameOrAge(@Param("name") String name , @Param("age") Integer age , @Param("id") Integer id);
<!--如果名字信息不是null,则修改名字, 如果age信息不是null,同时也修改age-->
    <update id="updateByNameOrAge">
        update tb_user
        <set>
            <if test="name != null and name!=''">
                user_name =  #{name},
            </if>
            <if test="age != null and age!=''">
                age = #{age}
            </if>
        </set>
        where id = #{id}
    </update>
//如果名字信息不是null,则修改名字, 如果age信息不是null,同时也修改age
    @Test
    public void updateByNameOrAge(){
        Integer integer = this.userMapper.updateByNameOrAge("一燕", 26, 2);
        sqlSession.commit();
        System.out.println(integer);
    }

动态sql-foreach标签

需求5:按照多个id查询用户信息 Select * from t_user where id in(1,2,3)

/**
     * 按照多个id查询用户信息
     * @param ids
     * @return
     */
    public List<User> queryIds(@Param("ids") int[] ids);
<!--按照多个id查询用户信息-->
    <!--
        collection:接受的是一个集合
        item: 表示遍历的就量
        open: 字符串拼接的开头
        close: 字符串拼接的结尾
        separator: 每一个变量拼接的分隔符
    -->
    <select id="queryIds" resultType="User">        
        select * from tb_user where id in
        <foreach collection="ids" item="id" open="(" close=")" separator=",">
            #{id}
        </foreach>
    </select>
// 按照多个id查询用户信息
    @Test
    public void queryIds(){
        int[] arr ={1,2};
        List<User> list = this.userMapper.queryIds(arr);
        for(User user : list){
            System.out.println(user);
        }
    }

动态sql-trim标签

trim元素的主要功能是可以在自己包含的内容前加上某些前缀,也可以在其后加上某写后缀,与之对应的属性是prefix和suffix;

可以把包含内容的首部某些内容覆盖,即忽略,也可以把尾部的某些内容覆盖,对应的属性是prefixOverrides和suffixOver

  • 案例一 prefix用法
/**
 * 查询所有,如果输入姓名,按姓名查询,如果输入性别,就按性别来查询
 */
public List<User> queryNameAndSexTrim(@Param("name") String name , @Param("sex") String sex);
<!--查询所有,如果输入姓名,按姓名查询,如果输入性别,就按性别来查询-->
    <select id="queryNameAndSexTrim" resultType="User">
        select * from tb_user
        /*加前缀,去掉第一个前缀*/
        <trim prefix="where" prefixOverrides="and">
            <if test="name != null and name !=''">
                and user_name = #{name}
            </if>
            <if test="sex != null and sex !=''">
                and sex = #{sex}
            </if>
        </trim>
    </select>
//查询所有,如果输入姓名,按姓名查询,如果输入性别,就按性别来查询
    @Test
    public void queryNameAndSexTrim(){
        List<User> list = this.userMapper.queryNameAndSexTrim("jack", "男");
        for(User user : list){
            System.out.println(user);
        }
    }
  • **案例二 ** suffix用法
/**
* 如果名字信息不是null,则修改名字, 如果sex不为null,同时也修改null
*/
public Integer updateByNameOrAgeTrim(@Param("name") String name , @Param("sex") String sex , @Param("id") Integer id);
<!--如果名字信息不是null,则修改名字, 如果sex不为null,同时也修改null-->
    <update id="updateByNameOrAgeTrim">
        update tb_user
        <trim prefix="set" suffixOverrides="," suffix="where id = #{id}">
            <if test="name != null and name !=''">
                user_name = #{name},
            </if>
            <if test="sex != null and sex !=''">
                sex = #{sex},
            </if>
        </trim>
    </update>
//如果名字信息不是null,则修改名字, 如果sex不为null,同时也修改null
@Test
public void updateByNameOrAgeTrim(){
    Integer integer = this.userMapper.updateByNameOrAgeTrim("小江", "女", 2);
    sqlSession.commit();
    System.out.println(integer);
}

缓存

一级缓存

Mybatis的一级缓存的作用域session,当openSession()后,如果执行相同的sql和参数,Mybatis不再执行SQL,而是从缓存中命中并返回;

原理:mybatis执行查询时首先去缓存中命中,如果命中就直接返回,没有命中则执行SQL,从数据库中查

在mybatis中,一级缓存默认是开启的,并且一直无法关闭(我们没法去管理一级缓存

测试一级缓存

@Test
    public void queryById(){
        User user = this.userMapper.queryById(2);//发送sql
        System.out.println(user);
        User user2 = this.userMapper.queryById(2);//不发送sql
        System.out.println(user2);
    }

清空缓存

使用sqlsession.clearCache()清除缓存

@Test
    public void queryById(){
        User user = this.userMapper.queryById(2);//发送sql
        System.out.println(user);
        sqlSession.clearCache();//清空缓存
        User user2 = this.userMapper.queryById(2);//重新发送sql
        System.out.println(user2);
    }

执行update,delete,insert 语句的时候,清空缓存 刷新缓存

@Test
    public void queryById(){
        User user = this.userMapper.queryById(2);//发送sql
        System.out.println(user);
        Integer i = this.userMapper.deleteById(1);//执行删除操作
        sqlSession.commit();
        System.out.println(i);
  //只要执行任意的增删改,则会清空缓存;
        User user2 = this.userMapper.queryById(2);//发送sql
        System.out.println(user2);
    }

二级缓存

mybatis 的二级缓存的作用域是一个mapper的namespace ,同一个namespace中查询sql可以从缓存中命中。

二级缓存是跨session

开启二级缓存

需要在当前sql映射文件中开启二缓缓存

<?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="cn.yanqi.mapper.UserMapper">    
    <!--开启二级缓存-->
    <cache/>

测试二级缓存

@Test
public void queryById(){
    User user = this.userMapper.queryById(2);//发送sql
    System.out.println(user);
    //关闭sqlSession
    sqlSession.close(); 
    SqlSession sqlSession = sqlSessionFactory.openSession();
    userMapper = sqlSession.getMapper(UserMapper.class);
    User user2 = this.userMapper.queryById(2);//不发送sql,表明二级缓存存在
    System.out.println(user2);
}

查看日志输出

关闭二级缓存

<settings>
    <!--开启驼峰匹配-->
    <setting name="mapUnderscoreToCamelCase" value="true"/>
    <!--关闭二级缓存  默认是开启的-->
    <setting name="cacheEnabled" value="false"/>
</settings>

Mybatis一级缓存

1.为什么需要Mybatis一级缓存

当我们使用Mybatis进行数据库的操作时候,会创建一个SqlSession来进行一次数据库的会话,会话结束则关闭SqlSession对象。

如果我们很有可能多次查询完全相同的sql语句,每一次查询都查询一次数据库,那查询数据库代价是比较大的,这会导致系统的资源浪费。

为了解决这个问题,Mybatis对每一次会话都添加了缓存操作,不用相同的SQL每次都需要查询数据库,这就是Mybatis一级缓存的作用。

2.Mybatis一级缓存的实现

我们知道对SqlSession的操作,mybatis内部都是通过Executor来执行的,Executor的生命周期和SqlSession是一致的。

Mybatis在Executor中创建了本地缓存(一级缓存),如下图所示:

大致的流程如下:

第一次查询用户id信息,先去缓存中查询是否有,如果没有,从数据库中查询用户信息,得到用户信息后在将用户信息储存到一级缓存中。

如果sqlSession去执行commit操作(插入、更新、删除),清空sqlSession中的一级缓存,保证缓存中始终保存的是最新的信息,避免脏读。

第二次查询用户id信息,先去缓存中查询,如缓存中有,直接从缓存中获取。

注意:两次查询须在同一个sqlsession中完成,否则将不会走mybatis的一级缓存。

在mybatis与spring进行整合开发时,事务控制在service中进行,重复调用两次servcie将不会走一级缓存,因为在第二次调用时session方法结束,SqlSession就关闭了。

3.Mybatis一级缓存配置

mybatis一级缓存的范围有SESSION和STATEMENT两种,默认是SESSION。

如果不想使用一级缓存,可以把一级缓存的范围指定为STATEMENT,这样每次执行完一个Mapper中的语句后都会将一级缓存清除。

如果需要更改一级缓存的范围,可以在Mybatis的配置文件中,在下通过localCacheScope指定。

Mybatis二级缓存 1.为什么需要Mybatis二级缓存? MyBatis 一级缓存最大的共享范围就是一个SqlSession内部,那么如果多个 SqlSession 需要共享缓存,则需要开启二级缓存。

2.Mybatis二级缓存的实现

开启二级缓存后,会使用 CachingExecutor 装饰 Executor,进入一级缓存的查询流程前,先在 CachingExecutor 进行二级缓存的查询,具体的工作流程如下所示。

二级缓存开启后,同一个 namespace 下的所有操作语句,都影响着同一个 Cache,即二级缓存被多个 SqlSession 共享,是一个全局的变量。

当开启缓存后,数据的查询执行的流程就是 二级缓存 -> 一级缓存 -> 数据库。

MyBatis 是默认关闭二级缓存的,因为对于增删改操作频繁的话,那么二级缓存形同虚设,每次都会被清空缓存。

Mybatis一级缓存与二级缓存的区别

1)一级缓存 Mybatis的一级缓存是指SQLSession,一级缓存的作用域是SQlSession, Myabits默认开启一级缓存。

在同一个SqlSession中,执行相同的SQL查询时;第一次会去查询数据库,并写在缓存中,第二次会直接从缓存中取。 当执行SQL时候两次查询中间发生了增删改的操作,则SQLSession的缓存会被清空。

每次查询会先去缓存中找,如果找不到,再去数据库查询,然后把结果写到缓存中。 Mybatis的内部缓存使用一个HashMap,key为hashcode+statementId+sql语句。Value为查询出来的结果集映射成的java对象。 SqlSession执行insert、update、delete等操作commit后会清空该SQLSession缓存。

2) Mybatis二级缓存是默认不开启的,作用于一个Application,是Mapper级别的,多个SqlSession使用同一个Mapper的sql能够使用二级缓存。

xecutor 装饰 Executor,进入一级缓存的查询流程前,先在 CachingExecutor 进行二级缓存的查询,具体的工作流程如下所示。

[外链图片转存中…(img-TITjBxut-1665230984236)]

二级缓存开启后,同一个 namespace 下的所有操作语句,都影响着同一个 Cache,即二级缓存被多个 SqlSession 共享,是一个全局的变量。

当开启缓存后,数据的查询执行的流程就是 二级缓存 -> 一级缓存 -> 数据库。

MyBatis 是默认关闭二级缓存的,因为对于增删改操作频繁的话,那么二级缓存形同虚设,每次都会被清空缓存。

Mybatis一级缓存与二级缓存的区别

1)一级缓存 Mybatis的一级缓存是指SQLSession,一级缓存的作用域是SQlSession, Myabits默认开启一级缓存。

在同一个SqlSession中,执行相同的SQL查询时;第一次会去查询数据库,并写在缓存中,第二次会直接从缓存中取。 当执行SQL时候两次查询中间发生了增删改的操作,则SQLSession的缓存会被清空。

每次查询会先去缓存中找,如果找不到,再去数据库查询,然后把结果写到缓存中。 Mybatis的内部缓存使用一个HashMap,key为hashcode+statementId+sql语句。Value为查询出来的结果集映射成的java对象。 SqlSession执行insert、update、delete等操作commit后会清空该SQLSession缓存。

2) Mybatis二级缓存是默认不开启的,作用于一个Application,是Mapper级别的,多个SqlSession使用同一个Mapper的sql能够使用二级缓存。

目录
相关文章
|
2月前
|
Java 数据库连接 Spring
后端框架入门超详细 三部曲 Spring 、SpringMVC、Mybatis、SSM框架整合案例 【爆肝整理五万字】
文章是关于Spring、SpringMVC、Mybatis三个后端框架的超详细入门教程,包括基础知识讲解、代码案例及SSM框架整合的实战应用,旨在帮助读者全面理解并掌握这些框架的使用。
后端框架入门超详细 三部曲 Spring 、SpringMVC、Mybatis、SSM框架整合案例 【爆肝整理五万字】
|
2月前
|
SQL Java 关系型数据库
MyBatis-Plus 分页魅力绽放!紧跟技术热点,带你领略数据分页的高效与便捷
【8月更文挑战第29天】在 Java 开发中,数据处理至关重要,尤其在大量数据查询与展示时,分页功能尤为重要。MyBatis-Plus 作为一款强大的持久层框架,提供了便捷高效的分页解决方案。通过封装数据库分页查询语句,开发者能轻松实现分页功能。在实际应用中,只需创建 `Page` 对象并设置页码和每页条数,再通过 `QueryWrapper` 构建查询条件,调用 `selectPage` 方法即可完成分页查询。MyBatis-Plus 不仅生成分页 SQL 语句,还自动处理参数合法性检查,并支持条件查询和排序等功能,极大地提升了系统性能和稳定性。
38 0
|
2月前
|
SQL Java 数据库连接
【Java 第十三篇章】MyBatis 框架介绍
MyBatis 原名 iBATIS,2001 年由 Clinton Begin 创建,以其简易灵活著称。2010 年更名以重塑品牌形象。MyBatis 通过 SQL 映射文件将 SQL 语句与 Java 代码分离,支持编写原生 SQL 并与方法映射。具备对象关系映射功能,简化数据库记录处理。支持动态 SQL 构建,灵活应对不同查询条件。内置缓存机制,提升查询效率。相比全功能 ORM,MyBatis 提供更高 SQL 控制度和更好的维护性,并易于与 Spring 等框架集成,广泛应用于 Java 数据访问层。
17 0
|
2月前
|
druid Java 数据库连接
SpringBoot项目整合MybatisPlus持久层框架+Druid数据库连接池,以及实现增删改查功能
SpringBoot项目整合MybatisPlus和Druid数据库连接池,实现基本的增删改查功能。
179 0
|
2月前
|
SQL Java 数据库连接
后端框架的学习----mybatis框架(5、分页)
这篇文章介绍了如何在MyBatis框架中实现分页功能,包括使用SQL的`limit`语句进行分页和利用MyBatis的`RowBounds`对象进行分页的方法。
|
8天前
|
关系型数据库 MySQL 网络安全
5-10Can't connect to MySQL server on 'sh-cynosl-grp-fcs50xoa.sql.tencentcdb.com' (110)")
5-10Can't connect to MySQL server on 'sh-cynosl-grp-fcs50xoa.sql.tencentcdb.com' (110)")
|
3月前
|
SQL 存储 监控
SQL Server的并行实施如何优化?
【7月更文挑战第23天】SQL Server的并行实施如何优化?
68 13
|
3月前
|
SQL
解锁 SQL Server 2022的时间序列数据功能
【7月更文挑战第14天】要解锁SQL Server 2022的时间序列数据功能,可使用`generate_series`函数生成整数序列,例如:`SELECT value FROM generate_series(1, 10)。此外,`date_bucket`函数能按指定间隔(如周)对日期时间值分组,这些工具结合窗口函数和其他时间日期函数,能高效处理和分析时间序列数据。更多信息请参考官方文档和技术资料。
|
3月前
|
SQL 存储 网络安全
关系数据库SQLserver 安装 SQL Server
【7月更文挑战第26天】
48 6
|
2月前
|
SQL 安全 Java
驱动程序无法通过使用安全套接字层(SSL)加密与 SQL Server 建立安全连接。错误:“The server selected protocol version TLS10 is not accepted by client
驱动程序无法通过使用安全套接字层(SSL)加密与 SQL Server 建立安全连接。错误:“The server selected protocol version TLS10 is not accepted by client
232 0
下一篇
无影云桌面