JavaWeb框架梳理(四)——Mybatis提高


来源于how2j

Mybatis提高

Mybatis动态SQL
if标签

基于之前多对一的工程基础上

  • 假设需要对Product执行两条sql语句,一个是查询所有,一个是根据名称模糊查询。

  • 那么按照现在的方式,必须提供两条sql语句:listProduct和listProductByName

  • 就像这样:

    • Product.xml :
    <?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_         
            </select>
            <select id="listProductByName" resultType="Product">
                select * from product_  where name like concat('%',#{name},'%')        
            </select>
             
        </mapper>
    
    • TestMybatis.java
    package com.how2java;
      
    import java.io.IOException;
    import java.io.InputStream;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
     
    import org.apache.ibatis.io.Resources;
    import org.apache.ibatis.session.SqlSession;
    import org.apache.ibatis.session.SqlSessionFactory;
    import org.apache.ibatis.session.SqlSessionFactoryBuilder;
     
    import com.how2java.pojo.Product;
      
    public class TestMybatis {
      
        public static void main(String[] args) throws IOException {
            String resource = "mybatis-config.xml";
            InputStream inputStream = Resources.getResourceAsStream(resource);
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
            SqlSession session = sqlSessionFactory.openSession();
      
            System.out.println("查询所有的");
            List<Product> ps = session.selectList("listProduct");
            for (Product p : ps) {
                System.out.println(p);
            }
             
            System.out.println("模糊查询");
            Map<String,Object> params = new HashMap<>();
            params.put("name","a");
            List<Product> ps2 = session.selectList("listProductByName",params);
            for (Product p : ps2) {
                System.out.println(p);
            }      
             
            session.commit();
            session.close();
      
        }
    }
    
  • 效果:在这里插入图片描述

  • 利用if标签优化

    • 如果没有传参数name,那么就查询所有,如果有name参数,那么就进行模糊查询。
    • 代码:
    <select id="listProduct" resultType="Product">
    	select * from product_
    	<if test="name!=null">
    		where name like concat('%',#{name},'%')
    	</if>		 	
    </select>
    
    • 只需要定义一条sql语句即可应付多种情况了,在测试的时候,也只需要调用这么一条sql语句listProduct 即可。

    • 代码:

      • Pro’duct.xml
      <?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>
      
      • TestMybatis.java
      package com.how2java;
        
      import java.io.IOException;
      import java.io.InputStream;
      import java.util.HashMap;
      import java.util.List;
      import java.util.Map;
       
      import org.apache.ibatis.io.Resources;
      import org.apache.ibatis.session.SqlSession;
      import org.apache.ibatis.session.SqlSessionFactory;
      import org.apache.ibatis.session.SqlSessionFactoryBuilder;
       
      import com.how2java.pojo.Product;
        
      public class TestMybatis {
        
          public static void main(String[] args) throws IOException {
              String resource = "mybatis-config.xml";
              InputStream inputStream = Resources.getResourceAsStream(resource);
              SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
              SqlSession session = sqlSessionFactory.openSession();
        
              System.out.println("查询所有的");
              List<Product> ps = session.selectList("listProduct");
              for (Product p : ps) {
                  System.out.println(p);
              }
               
              System.out.println("模糊查询");
              Map<String,Object> params = new HashMap<>();
              params.put("name","a");
              List<Product> ps2 = session.selectList("listProduct",params);
              for (Product p : ps2) {
                  System.out.println(p);
              }      
               
              session.commit();
              session.close();
        
          }
      }
      
  • 效果:在这里插入图片描述

where标签
  • 在if的基础上,增加一个price>10的条件,即当name = null时select * from product where price>10,当name有值:select * from product where name like concat('%',a,'%') and price > 10
  • 改Product.xml:
<?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>        
        <if test="price!=0">
            and price > #{price}
        </if>        
    </select>
         
    </mapper>
  • TestMybatis.java:
public class TestMybatis {
  
    public static void main(String[] args) throws IOException {
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        SqlSession session = sqlSessionFactory.openSession();
  
        System.out.println("多条件查询");
        Map<String,Object> params = new HashMap<>();
        params.put("name",null);
        params.put("price","10");
        List<Product> ps2 = session.selectList("listProduct",params);
        for (Product p : ps2) {
            System.out.println(p);
        }      
         
        session.commit();
        session.close();
  
    }
}
  • 结果:在这里插入图片描述
    即这么写的问题是:当没有name参数,却有price参数的时候,执行的sql语句就会是:select * from product_ and price > 10.
  • 利用<where>标签:
<select id="listProduct" resultType="Product">
	select * from product_
	<where>
		<if test="name!=null">
			and name like concat('%',#{name},'%')
		</if>		 	
		<if test="price!=null and price!=0">
			and price > #{price}
		</if>	
	</where>	 	
</select>
  • <where>标签会进行自动判断
    • 如果任何条件都不成立,那么就在sql语句里就不会出现where关键字
    • 如果有任何条件成立,会自动去掉多出来的 and 或者 or。
  • 测试代码:
public class TestMybatis {
  
    public static void main(String[] args) throws IOException {
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        SqlSession session = sqlSessionFactory.openSession();
  
        System.out.println("多条件查询");
        Map<String,Object> params = new HashMap<>();
//        params.put("name","a");
        params.put("price","10");
        List<Product> ps2 = session.selectList("listProduct",params);
        for (Product p : ps2) {
            System.out.println(p);
        }      
         
        session.commit();
        session.close();
  
    }
}
  • 当两个参数都没有,即where不成立select * from product
    在这里插入图片描述
  • 有 price 条件 即 select * from product where price >10 :在这里插入图片描述
  • price和name 都有:即 select * from product where name like .. and price >10;:在这里插入图片描述
set标签
  • 与where标签类似的,在update语句里也会碰到多个字段相关的问题。 在这种情况下,就可以使用set标签:
<set>
     	<if test="name != null">name=#{name},</if>
     	<if test="price != null">price=#{price}</if>
    </set>
  • 测试:
package com.how2java;
  
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
 
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
 
import com.how2java.pojo.Product;
  
public class TestMybatis {
  
    public static void main(String[] args) throws IOException {
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        SqlSession session = sqlSessionFactory.openSession();
 
        Product p = new Product();
        p.setId(6);
        p.setName("product zz");
        p.setPrice(99.99f);
        session.update("updateProduct",p);
         
        listAll(session);
 
        session.commit();
        session.close();
  
    }
 
    private static void listAll(SqlSession session) {
        Map<String,Object> params = new HashMap<>();
//        params.put("name","a");
//        params.put("price","10");
        List<Product> ps2 = session.selectList("listProduct",params);
        for (Product p : ps2) {
            System.out.println(p);
        }
    }
}
  • res:在这里插入图片描述
trim标签
  • trim 用来定制想要的功能,比如where标签就可以用
<trim prefix="WHERE" prefixOverrides="AND |OR ">
  ... 
</trim>

来替换

  • set标签就可以用
<trim prefix="SET" suffixOverrides=",">
 ...
</trim>

来替换

  • 代码 :
<?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_
        <trim prefix="WHERE" prefixOverrides="AND |OR ">
            <if test="name!=null">
                and name like concat('%',#{name},'%')
            </if>        
            <if test="price!=null and price!=0">
                and price > #{price}
            </if>
        </trim>      
    </select>
     
    <update id="updateProduct" parameterType="Product" >
        update product_
        <trim prefix="SET" suffixOverrides=",">
            <if test="name != null">name=#{name},</if>
            <if test="price != null">price=#{price}</if>
              
        </trim>
         
         where id=#{id}   
    </update>
         
    </mapper>
注解方式
注解实现CRUD
  • Mapper接口

    • 新增加接口CategoryMapper ,并在接口中声明的方法上,加上注解
    • 对比配置文件Category.xml,其实就是把SQL语句从XML挪到了注解上来
    • 代码:
    package com.how2java.mapper;
      
    import java.util.List;
     
    import org.apache.ibatis.annotations.Delete;
    import org.apache.ibatis.annotations.Insert;
    import org.apache.ibatis.annotations.Select;
    import org.apache.ibatis.annotations.Update;
     
    import com.how2java.pojo.Category;
      
    public interface CategoryMapper {
      
        @Insert(" insert into category_ ( name ) values (#{name}) ") 
        public int add(Category category); 
            
        @Delete(" delete from category_ where id= #{id} ") 
        public void delete(int id); 
            
        @Select("select * from category_ where id= #{id} ") 
        public Category get(int id); 
          
        @Update("update category_ set name=#{name} where id=#{id} ") 
        public int update(Category category);  
            
        @Select(" select * from category_ ") 
        public List<Category> list(); 
    }
    
  • mybatis-config.xml

    • 增加对CategoryMapper映射,原来的Category.xml 是否保留随意
    • 代码:
    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE configuration
    PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
    "http://mybatis.org/dtd/mybatis-3-config.dtd">
    <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="admin"/>
                </dataSource>
            </environment>
        </environments>
        <mappers>
            <mapper resource="com/how2java/pojo/Category.xml"/>
            <mapper resource="com/how2java/pojo/Product.xml"/>
            <mapper class="com.how2java.mapper.CategoryMapper"/> 
        </mappers>
    </configuration>
    
  • CRUD测试类:

package com.how2java;
   
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
 
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
 
import com.how2java.mapper.CategoryMapper;
import com.how2java.pojo.Category;
   
public class TestMybatis {
   
    public static void main(String[] args) throws IOException {
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        SqlSession session = sqlSessionFactory.openSession();
        CategoryMapper mapper = session.getMapper(CategoryMapper.class);
  
//        add(mapper);
//        delete(mapper);
//        get(mapper);
//        update(mapper);
        listAll(mapper);
              
        session.commit();
        session.close();
   
    }
  
    private static void update(CategoryMapper mapper) {
        Category c= mapper.get(8);
        c.setName("修改了的Category名稱");
        mapper.update(c);
        listAll(mapper);
    }
  
    private static void get(CategoryMapper mapper) {
        Category c= mapper.get(8);
        System.out.println(c.getName());
    }
  
    private static void delete(CategoryMapper mapper) {
        mapper.delete(2);
        listAll(mapper);
    }
  
    private static void add(CategoryMapper mapper) {
        Category c = new Category();
        c.setName("新增加的Category");
        mapper.add(c);
        listAll(mapper);
    }
   
    private static void listAll(CategoryMapper mapper) {
        List<Category> cs = mapper.list();
        for (Category c : cs) {
            System.out.println(c.getName());
        }
    }
}
注解配置1对多
  • 新增加CategoryMapper接口,查询所有Category

    • @Select注解获取Category类本身
    • @Select(" select * from category_ ")
    • @Results 通过@Result和@Many中调用ProductMapper.listByCategory()方法相结合,来获取一对多关系
    @Results({@Result(property = "products", javaType = List.class, column = "id",  
             many = @Many(select = "com.how2java.mapper.ProductMapper.listByCategory"))})
    
  • ProductMapper

  • 新增接口ProductMapper

    • 注解@Select用于根据分类id获取产品集合
    • @Select(" select * from product_ where cid = #{cid}")
    • 代码:
    package com.how2java.mapper;
      
    import java.util.List;
     
    import org.apache.ibatis.annotations.Select;
     
    import com.how2java.pojo.Product;
      
    public interface ProductMapper {
      
        @Select(" select * from product_ where cid = #{cid}")
        public List<Product> listByCategory(int cid);
         
    }
    
  • mybatis-config.xml

<mappers>
        <mapper resource="com/how2java/pojo/Category.xml"/>
        <mapper class="com.how2java.mapper.CategoryMapper"/> 
        <mapper class="com.how2java.mapper.ProductMapper"/> 
    </mappers>
  • res:在这里插入图片描述
注解配置动态SQL
  • CategoryDynaSqlProvider

    • 新增CategoryDynaSqlProvider,提供CRUD对应的SQL语句。
    • 代码:
    package com.how2java;
     
    import org.apache.ibatis.jdbc.SQL;
     
    public class CategoryDynaSqlProvider {
        public String list() {
             return new SQL()
                     .SELECT("*")
                     .FROM("category_")
                     .toString();
             
        }
        public String get() {
            return new SQL()
                    .SELECT("*")
                    .FROM("category_")
                    .WHERE("id=#{id}")
                    .toString();
        }
         
        public String add(){
            return new SQL()
                    .INSERT_INTO("category_")
                    .VALUES("name", "#{name}")
                    .toString();
        }
        public String update(){
            return new SQL()
                    .UPDATE("category_")
                    .SET("name=#{name}")
                    .WHERE("id=#{id}")
                    .toString();
        }
        public String delete(){
            return new SQL()
                    .DELETE_FROM("category_")
                    .WHERE("id=#{id}")
                    .toString();
        }
         
    }
    
  • 修改CategoryMapper

    • 把本来是手写SQL的CategoryMapper接口,修改为注解引用CategoryDynaSqlProvider类的方式
      比如增加,本来是手写SQL语句的
    @Insert(" insert into category_ ( name ) values (#{name}) ")  
    public int add(Category category);
    
    • 修改为了注解@InsertProvider配合CategoryDynaSqlProvider的add方法
    @InsertProvider(type=CategoryDynaSqlProvider.class,method="add")  
    public int add(Category category);
    
    • 代码 :
    package com.how2java.mapper;
      
    import java.util.List;
     
    import org.apache.ibatis.annotations.DeleteProvider;
    import org.apache.ibatis.annotations.InsertProvider;
    import org.apache.ibatis.annotations.SelectProvider;
    import org.apache.ibatis.annotations.UpdateProvider;
     
    import com.how2java.CategoryDynaSqlProvider;
    import com.how2java.pojo.Category;
      
    public interface CategoryMapper {
      
        @InsertProvider(type=CategoryDynaSqlProvider.class,method="add") 
        public int add(Category category); 
            
        @DeleteProvider(type=CategoryDynaSqlProvider.class,method="delete")
        public void delete(int id); 
            
        @SelectProvider(type=CategoryDynaSqlProvider.class,method="get") 
        public Category get(int id); 
          
        @UpdateProvider(type=CategoryDynaSqlProvider.class,method="update") 
        public int update(Category category);  
            
        @SelectProvider(type=CategoryDynaSqlProvider.class,method="list")     
        public List<Category> list(); 
    }
    
  • 测试 :

package com.how2java;
   
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
 
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
 
import com.how2java.mapper.CategoryMapper;
import com.how2java.pojo.Category;
   
public class TestMybatis {
   
    public static void main(String[] args) throws IOException {
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        SqlSession session = sqlSessionFactory.openSession();
        CategoryMapper mapper = session.getMapper(CategoryMapper.class);
  
//        add(mapper);
//        delete(mapper);
//        get(mapper);
//        update(mapper);
        listAll(mapper);
              
        session.commit();
        session.close();
   
    }
  
    private static void update(CategoryMapper mapper) {
        Category c= mapper.get(14);
        c.setName("修改了的Category名稱");
        mapper.update(c);
        listAll(mapper);
    }
  
    private static void get(CategoryMapper mapper) {
        Category c= mapper.get(14);
        System.out.println(c.getName());
    }
  
    private static void delete(CategoryMapper mapper) {
        mapper.delete(13);
        listAll(mapper);
    }
  
    private static void add(CategoryMapper mapper) {
        Category c = new Category();
        c.setName("新增加的Category");
        mapper.add(c);
        listAll(mapper);
    }
   
    private static void listAll(CategoryMapper mapper) {
        List<Category> cs = mapper.list();
        for (Category c : cs) {
            System.out.println(c.getName());
        }
    }
}
  • res:在这里插入图片描述
  • 关于sql类:
private String selectPersonSql() {
  return new SQL() {{
    SELECT("P.ID, P.USERNAME, P.PASSWORD, P.FULL_NAME");
    SELECT("P.LAST_NAME, P.CREATED_ON, P.UPDATED_ON");
    FROM("PERSON P");
    FROM("ACCOUNT A");
    INNER_JOIN("DEPARTMENT D on D.ID = P.DEPARTMENT_ID");
    INNER_JOIN("COMPANY C on D.COMPANY_ID = C.ID");
    WHERE("P.ID = A.ID");
    WHERE("P.FIRST_NAME like ?");
    OR();
    WHERE("P.LAST_NAME like ?");
    GROUP_BY("P.ID");
    HAVING("P.LAST_NAME like ?");
    OR();
    HAVING("P.FIRST_NAME like ?");
    ORDER_BY("P.ID");
    ORDER_BY("P.FULL_NAME");
  }}.toString();
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值