MyBatis技术练习

一.CRUD的练习操作

在此之前,CRUD的操作都是基于TEST文件上的修改,有必要对教材上原始代码深入理解


public class TestMybatis {
    public static void main(String[] args) throws IOException {
1        String resource = "mybatis-config.xml";
2        InputStream inputStream = Resources.getResourceAsStream(resource);
3        SqlSessionFactory sqlSessionFactory = new 
4     SqlSessionFactoryBuilder().build(inputStream);
5        SqlSession session=sqlSessionFactory.openSession();
         
6        List<Category> cs=session.selectList("listCategory");
7       for (Category c : cs) {
8           System.out.println(c.getName());

第一二行:定义MyBatis的配置文件的路径,并作为输出流加载配置文件

配置文件就涉及到了数据源和SQL映射的配置文件,前者就像之前学的MVC中的model层和JDBC驱动用于与数据库连接,包括数据库驱动、数据库URL、用户名、密码等。一些全局配置项等等,通常放到类路径下;后者用于配置SQL语句与Java方法的映射关系。它包括了一系列的<select><insert><update><delete>等元素,每个元素都对应一个SQL语句和一个Java方法。简单来说就是一个负责连接,一个负责Java和SQL方法映射

第三行往后就是会话工厂的实例对象,依照配置文件的映射关系,将Java方法转换成sql语句完成对数据库进行操作

所以,在开始CRUD操作之前,从整体框架出发需要完成对配置文件的修改,完成数据库连接和映射方法的定义,

数据库连接池配置:

<configuration>
    <typeAliases>
      <package name="com.how2java.pojo"/>
    </typeAliases>

    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/how2java?characterEncoding=UTF-8"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
    </environments>
    
    <mappers>
        <mapper resource="com/how2java/pojo/Category.xml"/>
    </mappers>
</configuration>
  1. <typeAliases>:MyBatis框架的类型别名配置,用于指定Java对象的别名,提高编码效率。但<package name="com.how2java.pojo"/>并不是一个具体的别名,而是一个将com.how2java.pojo包下的所有Java类注册为别名的配置。也就是说,如果在com.how2java.pojo包下有一个名为Category的Java类,那么它的别名就是category,如果有一个名为Product的Java类,那么它的别名就是product,以此类推。那么在SQL映射文件中就可以使用<select id="getCategory" resultType="category">来引用com.how2java.pojo.Category类,其中resultType属性的值为category,即该类的别名

  2. <environments>:定义MyBatis框架所需的数据库环境,可以包含多个<environment>元素,每个<environment>对应一个数据源,default属性指定了默认的数据库环境,

  3. <transactionManager>:事务管理器配置,用于指定事务的管理方式,常用的包括JDBCMANAGEDSPRING等。这里指定的是JDBC

  4. <dataSource>:数据源配置,是本质上用来配置数据库信息的,在其中<property>属性配置,包含了driverurlusernamepassword等数据库的配置信息
  5. <mappers>标签用于指定MyBatis的映射器,也就是SQL映射文件的位置。在这个例子中,<mappers>标签包含了一个<mapper>标签,指定了com/how2java/pojo/Category.xml文件作为MyBatis的映射器。通过将映射器的位置配置在MyBatis配置文件中,MyBatis可以自动扫描指定位置下的所有映射文件,并将它们加载到内存中,以便在Java应用程序中使用。这样,我们就可以在Java应用程序中方便地使用MyBatis进行数据库操作,而不需要手动编写SQL语句。

SQL映射文件配置:因为要使用到CRUD操作,所以这里要给出相关方法的映射配置 :

    <mapper namespace="com.how2java.pojo">
        <insert id="addCategory" parameterType="Category" >
            insert into category_ ( name ) values (#{name})   
        </insert>
         
        <delete id="deleteCategory" parameterType="Category" >
            delete from category_ where id= #{id}  
        </delete>
         
        <select id="getCategory" parameterType="_int" resultType="Category">
            select * from   category_  where id= #{id}   
        </select>
 
        <update id="updateCategory" parameterType="Category" >
            update category_ set name=#{name} where id=#{id}   
        </update>
        <select id="listCategory" resultType="Category">
            select * from   category_     
        </select>    
    </mapper>
  1. <mapper>是映射文件的根节点,namespace属性指定操作的接口名。

  2. <insert>为插入操作,id为操作的标识符,parameterType为传入参数的数据类型,其中category_是表名,name是表中的一个字段名,#{name}是MyBatis的占位符,表示name字段的值由Category对象中的name属性提供。insert,delete后面的操作也是同理

  3. <select>为查询操作,根据不同的参数类型返回不同的实体结果。id、parameterType、resultType分别为操作的标识符、传入参数的数据类型和返回结果的数据类型。#{id}表示传入的参数。SQL语句中的*表示查询所有字段,后面的表名为被查询的表名。

 

 以上是insert和delete的操作结果演示,后面冗余的操作也是同理

核心部分:

 Category c = new Category();
    c.setId(1);
    session.delete("deleteCategory",c);

 Category c = new Category();
    c.setName("ihui永不放弃");
    session.insert("addCategory",c);

  Category c= session.selectOne("getCategory",3);
        System.out.println(c.getName()); //获取

  listAll(session);//查询

核心代码的地方直接是用java的crud方法,最后是通过配置文件转换成对应的SQL语句

2.动态SQL练习

IF:用条件语句实现模糊查询和整体查询

<?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="com.how2java.pojo">
        <select id="listProduct" resultType="Product">
            select * from product_
            <if test="name!=null">
                where name like concat('%',#{name},'%')
            </if>        
        </select>
         
    </mapper>

        核心字段在配置文件中,因为要查询的对象多,相应需要的SQL语句也需要更多,这里在配置文件中实用IF标签来制定SQL语句的查询条件。如果name属性存在,则将它作为查询条件来实现模糊查询,如果没有name属性传入,就查询所有

        where name like concat('%',#{name},'%') 在SQL语句中添加查询条件,即查询name属性中包含指定字符的记录。其中,#{name}是MyBatis的占位符,表示在执行SQL语句时,将会使用name属性的值来替换这个占位符。concat('%',#{name},'%')是SQL语句中的字符串拼接函数,用于将查询条件中的字符与通配符%拼接起来,形成模糊查询的效果

 WHERE:自动去掉多余的and或or关键字

        如果添加了多个查询条件,那么就需要用and或or连接这些条件。但是,如果其中某个条件没有成立,就会导致SQL语句中出现多余的and或or关键字,从而导致SQL语句语法错误。<where>标签会自动判断这种情况,并且去掉多余的and或or关键字,以保证SQL语句的正确性。

例如:这个多条件语句,如果传值参数不全的话,就会变成select * from product_ and price > 10.很明显此时 多余了一个and,所以用where标签能自动判断并且删除不必要的连接符以保证正确性

        类似的,还有set标签和trim标签

  1. <set>标签用于在SQL语句中添加更新字段,并且会自动去掉多余的逗号和空格,以保证SQL语句的正确性。

  2. <trim>标签用于在SQL语句中添加任意的SQL片段,并且可以自定义前缀、后缀和连接符。

 Choose:实现多条件判断,类似于java中的switch语句

<select id="selectProduct" parameterType="Product" resultType="Product">
  select * from product
  <where>
    <choose>
      <when test="id != null">
        and id = #{id}
      </when>
      <when test="name != null">
        and name like concat('%',#{name},'%')
      </when>
      <when test="price != null">
        and price = #{price}
      </when>
      <otherwise>
        and 1 = 1
      </otherwise>
    </choose>
  </where>
</select>

        如果所需要的值都没有传入,就会默认执行otherwise中的语句,即全部查询,主要是由when和otherwise两个标签构成

Foreach:遍历集合生成查询条件

foreach标签通常用于in 这样的语法里,用于实现遍历集合或数组中的元素,并将它们作为查询条件的一部分,生成类似于SELECT * FROM product_ WHERE ID IN (1, 2, 3)的SQL语句,基本结构如下:
 

<foreach collection="collection" item="item" index="index"
         open="open" close="close" separator="separator">
  ...
</foreach>
  • collection:指定要遍历的集合或数组的名称,可以是OGNL表达式或者是Java对象的属性名。
  • item:指定遍历过程中每个元素的名称,可以是任意合法的Java变量名。
  • index:指定遍历过程中每个元素的索引,可以是任意合法的Java变量名。
  • open:指定遍历过程中生成的SQL语句的开头部分。
  • close:指定遍历过程中生成的SQL语句的结尾部分。
  • separator:指定遍历过程中每个元素之间的分隔符。

根据教材中的代码 

 

在这个例子中,#{item}表示要查询的ID值,它会在运行时被list集合中的每个元素所替换。<foreach>标签将List<Integer>类型的ids集合中的元素转化为id查询条件,并以IN符号连接查询条件,从而查询出所有在135范围内的产品

三.分页功能

这里实现的分页功能是一种分页查询的方式,与之前的MVC中的翻页有所不同,并没有实现交互功能

但是,相同的是这里也两种方式来实现可以用注解或者xml配置

private static void xmlWay(SqlSession session) {
        Map<String,Object> params = new HashMap<>();
        params.put("start", 0);
        params.put("count", 5);
        List<Category>  cs =session.selectList("listCategory", params);
        for (Category c : cs) {
            System.out.println(c);
        }

    private static void annotationWay(SqlSession session) {
        CategoryMapper mapper = session.getMapper(CategoryMapper.class);
         
        List<Category>  cs =mapper.listByPage(0, 5);
        for (Category c : cs) {
            System.out.println(c);

        在MyBatis中,用两种方式来定义SQL语句:XML文件配置SQL语句或者通过注解方式在Java接口中定义SQL语句。前者使用session.selectList("statementId", parameter)的方式来执行查询操作,即  List<Category>  cs =session.selectList("listCategory", params);后者调用该SQL语句时,需要先通过session.getMapper()方法获取该接口的实现类实例,再进一步执行查询操作

        先说配置方式:params对象中添加startcount两个参数,分别表示查询结果的起始位置和查询结果的数量,调用session.selectList()方法,传入查询语句的ID和params对象作为参数,执行查询操作,事先要在配置文件中定义好相关需要被调用的映射方法

 <mapper namespace="com.how2java.pojo">
        <insert id="addCategory" parameterType="Category" >
            insert into category_ ( name ) values (#{name})   
        </insert>
         
        <delete id="deleteCategory" parameterType="Category" >
            delete from category_ where id= #{id}  
        </delete>
         
        <select id="getCategory" parameterType="_int" resultType="Category">
            select * from   category_  where id= #{id}   
        </select>
 
        <update id="updateCategory" parameterType="Category" >
            update category_ set name=#{name} where id=#{id}   
        </update>
        <select id="listCategory" resultType="Category">
            select * from   category_
                <if test="start!=null and count!=null">
                    limit #{start},#{count}
                </if>
        </select>    
    </mapper>

        其中在CRUD的方法上新加了 listCategory方法:即查询category_表中所有的分类信息记录,如果传入了start和count参数,则进行分页查询。使用了<if>标签来判断是否传入了分页查询的参数,如果传入了,则使用limit关键字进行分页查询,parameterType和resultype属性指定了SQL语句中使用的参数类型和查询结果的返回类型

        注解方式:session.getMapper()方法获取一个CategoryMapper接口的实现类实例。调用mapper.listByPage()方法,传入查询结果的起始位置和查询结果的数量作为参数,执行查询操作

事先要定义好接口类:

public interface CategoryMapper {

    @Select(" select * from category_ ")

    @Results({@Result(property = "products", javaType = List.class, column = "id"

many = @Many(select = "com.how2java.mapper.ProductMapper.listByCategory"))})     

    public List<Category> list();

    @Select(" select * from category_ limit #{start},#{count}")

    public List<Category> listByPage(@Param("start"int start, @Param("count")int count);

        其中@Param注解用来指定方法参数的名称,方便在SQL语句中引用;@Results注解定义了一个products属性,用来存放该分类下的所有产品信息;@Many注解表示该属性为一对多关系,select属性指定了查询该分类下所有产品信息的SQL语句

       参数类型和结果类型可以是Java基本类型、JavaBean、Map、List等类型。例如,parameterType="int"表示参数类型为整型,resultType="Category"表示结果类型为Category类。

注解的方式调用了接口类来实现相关功能,代码也相对简洁一些,但是觉得在这个地方xml的配置对新手还是要友好些,配置中方法的编写更容易懂一些更易上手,注解的方式相对较难

 Pagehelper:第三方插件便于实现分页功能,相当分页功能的一个封装体

在看完how2j的教材后有一个疑问,chartgpt给出了完美的回答

 运行效果:

         其主要就是帮助减少xml配置中sql动态标签,自动来进行分页处理,适合用于用xml方法来查询,减少代码工作量和复用性

此外,常用的方法有:

  1. startPage(int pageNum, int pageSize):开始分页,指定当前页码和每页显示的记录数。
  2. startPage(int pageNum, int pageSize, boolean count):开始分页,指定当前页码、每页显示的记录数和是否进行总记录数的统计。
  3. offsetPage(int offset, int limit):开始分页,指定偏移量和每页显示的记录数。
  4. setPageSize(int pageSize):设置每页显示的记录数。
  5. setPageNum(int pageNum):设置当前页码。
  6. setCount(boolean count):设置是否进行总记录数的统计。
  7. setOrderBy(String orderBy):设置排序字段和排序方式。
  8. setOrderByOnly(boolean orderByOnly):设置是否仅按照排序字段进行排序。
  9. getPageInfo():获取分页信息,包括当前页码、每页显示的记录数、总记录数、总页数等
  10. clearPage():清除分页设置,恢复默认设置。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值