MyBatis使用说明与总结

MyBatis使用文档

1、开篇两个小知识点

  • 针对MyBatis的配置文件没有提示的解决方案(引入dtd约束):利用解压缩文件打开mybatis.jar,解压出来org.apache.ibatis.builder.xml中的两个dtd文件,如http://mybatis.org/dtd/mybatis-3-config.dtdhttp://mybatis.org/dtd/mybatis-3-mapper.dtd,选择解压出来的dtd文件,然后重新打开配置文件即可
    MyBatis使用说明与总结_第1张图片

  • 利用logback在控制台打印sql日志

//在pom.xml引入logback日志依赖

    ch.qos.logback
    logback-classic
    1.2.3
    test


//在src/main/resources目录下,引入logback配置文件
"1.0" encoding="UTF-8"?>
"http://ch.qos.logback/xml/ns/logback"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://ch.qos.logback/xml/ns/logback https://raw.githubusercontent.com/enricopulatzo/logback-XSD/master/src/main/xsd/logback.xsd">

    
    "STDOUT" class="ch.qos.logback.core.ConsoleAppender" >

        
        "ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50}:  %msg%n
        
    

    
    "com.security.dao" level="DEBUG" />

    "INFO">
        "STDOUT" />
    

2、MyBatis的简单测试使用

  • MySQL数据库资源配置文件db.properties
url=jdbc:mysql://localhost:3306/spring?characterEncoding=utf-8&allowMultiQueries=true
driver=com.mysql.jdbc.Driver
username=root
password=root
  • MyBatis全局配置文件
"1.0" encoding="UTF-8" ?>
"-//mybatis.org//DTD Config 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-config.dtd">


    
    "db.properties">

    
        
        "mapUnderscoreToCamelCase" value="true" />
        
        "lazyLoadingEnabled" value="true" />
        
        "aggressiveLazyLoading" value="false" />
        
        "cacheEnabled" value="true" />
        
        "useGeneratedKeys" value="true" />
    

    
        
        <package name="com.security.model" />
    

    default="development">
        "development">
            "JDBC" />
            "POOLED">
                "driver" value="${driver}" />
                "url" value="${url}" />
                "username" value="${username}" />
                "password" value="${password}" />
            
        
    

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

  • 在src/test/java目录下建立JUnit测试类,获取SqlSessionFactory,并且测试使用
public class MyBatisTest {

    private SqlSessionFactory sqlSessionFactory;

    /**
     * 获取SqlSessionFactory
     */
    @Before
    public void getSessionFactory(){
        String resource = "mybatis-config.xml";
        try {
            InputStream inputStream = Resources.getResourceAsStream(resource);
            sqlSessionFactory= new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 测试UserMapper
     */
    @Test
    public void testUserMapper() {
        SqlSession session=sqlSessionFactory.openSession();
        UserMapper userMapper=session.getMapper(UserMapper.class);
        User user=userMapper.findEntityById(1);
        System.out.println(user);
    }
}

3、MyBatis参数处理

  • #{}${}的区别:#{}是以预编译的形式,将参数设置到sql语句中,PreparedStatement防止sql注入;${}取出的值直接拼装在sql语句中,可能出现安全问题;大多情况下,建议使用#{},特殊情况除外,如定义结果的排序order by ${}
public List getEmployeeOrderBy(@Param("name")String name);


//sql语句为:select * from Employee order by id desc; 


//sql语句为:select * from Employee order by ? desc; 
  • 使用Insert语句时主键自增长:对于mysql获取自增主键的值,需要在insert方法中利用两个属性:useGeneratedKeys="true"使用自增主键获取主键值策略;keyProperty指定对应的主键属性,也就是mybatis获取到主键值以后,将这个值封装给JavaBean的哪个属性
"addEmployee" parameterType="employee"
    useGeneratedKeys="true"  keyProperty="id">
    insert into employee(name,gender,email) values(#{name},#{gender},#{email});
  • 在sql语句中只需要一个参数的情况:mybatis不会做特殊处理,#{参数名/任意名}即可取出参数值
public void add(User user);


"addUser" useGeneratedKeys="true" keyProperty="id" >
    insert into user(name,age) values(#{name},#{age})
  • 在sql语句中需要两个或者以上参数的情况:
public void addByUserAndAge(String name,int age);

"addByUserAndAge">
    insert into user(name,age) values(#{0},#{1})


Or
"addByUserAndAge">
    insert into user(name,age) values(#{param1},#{param2})


Or将接口中的方法改为:
public void addByUserAndAge(@Param("name")String name,@Param("age")int age);

"addByUserAndAge">
    insert into user(name,age) values(#{name},#{age})
  • MyBatis种sql语句多参数处理时会把多个参数封装为一个map,key:param1...paramN,或者参数的索引也可以;value:传入的参数值#{}就是从map中获取指定的key的值
public User getUserByMap(Map map);



测试:Map map=new HashMap<>();
    map.put("id",1);
    map.put("name","冯朗");
    System.out.println(mapper.getUserByMap(map));

---------------------------------------------------------------------------
②public Employee getEmp(@Param("id")Integer id,String lastName);
 取值:id==>#{id/param1}   lastName==>#{param2}


------------------------------------------------------------------------
③public Employee getEmp(Integer id,@Param("e")Employee emp);
取值:id==>#{param1}    lastName===>#{param2.lastName/e.lastName}

----------------------------------------------------------------
④##特别注意:如果是Collection(List、Set)类型或者是数组,也会特殊处理。也是把传入的list或者数组封装在map中。
    key:Collection(collection),如果是List还可以使用这个key(list)
    数组(array)
public Employee getEmpById(List ids);
取值:取出第一个id的值: #{list[0]}
  • MyBatis的两个内置参数_parameter_databaseId,其中_parameter代表整个参数,当sql方法需要单个参数时_parameter即为该参数,若需要多个参数时,参数会被封装为一个map,_parameter即代表这个map_databaseId:如果配置了databaseIdProvider标签,则_databaseId就是代表当前数据库的别名
public List getUsersWithParameter(String name);



----------------------------------------------------------------------

public List getUsersWithParameterBean(Map map);

  • bindsql标签的使用:bind可以将OGNL表达式的值绑定到一个变量中,方便后来引用这个变量的值;sql用于抽取可重用的片段,方便后期引用,include用于引用已抽取的sql片段
public List getUsersWithBinds(@Param("name")String name);

"selectuser" >
    select id,name,age from user


4、MyBatis中的动态SQL

  • whereif的使用
public List getUserByConditionIf(User user);

  • trim的使用
public List getUserByConditionTrim(User user);



 

  • set的使用
public void updateEmp(User user);

"updateEmp">
    update user
    
        <if test="name!=null and !name.equals("")">
            name=#{name},
        if>
        <if test="age!=null">
            age=#{age}
        if>
    
    
        id=#{id}
    
  • foreach的使用
方式一:
public List getUserByConditionForeach(List list);

  • 批量插入数据
public void addByBatch(List list);

"addByBatch">
    insert into user(name,age,did) values
    "list" item="u" separator=",">
        (#{u.name},#{u.age},#{u.department.id})
    


---------------------------------------------------------------------------------------
方式二:


"saveEmployeeWithForEach" >
   "list" item="emp">
       insert into employee(name,gender,email,d_id) values(#{emp.name},#{emp.gender},#{emp.email},#{emp.dept.id});
   

5、MyBatis中的模糊查询

  • 常规方式:利用bind进行数据绑定
public List getEmployeesWithNameLike(@Param("name")String name);

  • 利用MyBatis的内置函数_parameter
public List testInnerParameter(String name);

  • 利用MySQL的内置函数concat(str1,str2,…)
public List getEmployeesWithNameLike(@Param("name")String name);
    select * from employee
    
        <if test="name!=null">
            name like concat('%',#{name},'%')
        if>
    
  • 升级版模糊查询
public List getEmployeeWithUncertainQuery(String query);

6、MyBatis的级联查询

6.1场景一:Employee对应一个Department,查询Employee的同时查询员工对应的部门

  • 使用association进行单步查询,association代表的是一对一关系

"com.security.ben.Employee" id="MyEmp1">
    "id" property="id" />
    
    "name" property="name" />
    "gender" property="gender" />
    "email" property="email" />
    "dept" javaType="com.security.ben.Department">
        "id" property="id" />
        
        "deptName" property="deptName" />
    


  • 使用association进行分布查询


"com.security.ben.Employee" id="MyEmp2">
    "id" property="id" />
    
    "name" property="name" />
    "gender" property="gender" />
    "email" property="email" />
    
    "dept" column="d_id"     select="com.security.mapper.DepartmentMapper.getDeptById">
    



6.2场景二:一个Department对应多个Employee,查询部门信息的时候将其多对应的所有员工信息也查询出来

  • 使用collection单步查询,collection代表一对多关系

"com.security.ben.Department" id="SimpleDept">
    "id" property="id"/>
    "deptName" property="deptName"/>
    "emps" ofType="com.security.ben.Employee">
        "eid" property="id"/>
        "name" property="name"/>
        "email" property="email"/>
        "gender" property="gender"/>
    



  • 使用collection进行分步查询

"com.security.ben.Department" id="DifDept">
   "id" property="id"/>
   "deptName" property="deptName"/>
   "emps" select="com.security.mapper.EmployeeMapperPlus.getEmpsByDeptId" column="id"  fetchType="lazy">






6.3场景三:用户和角色属于多对多关联关系,参考MyBatis多对多关联查询

  • 建立数据表,use和role是多对多的关系,需要采用关联表t_user_role,建立相应的实体类
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class User implements Serializable {

    private static final long serialVersionUID = 1L;

    private Integer id;

    private String name;

    private String email;

    private List roles;
}


@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class Role {

    private Integer id;
    private String name;
    private List users;

}
  • 建立UserMapper和RoleMapper的接口,并定义相应的方法
public interface UserMapper {

    public User findUserById(Integer id);

    public List findUserByRoleId(Integer roleId);

}

public interface RoleMapper {

    public Role findRoleById(Integer id);

    public List findRoleByUserId(Integer userId);

}
  • 建立相应的UserMppaer.xml,并且定义sql语句
"1.0" encoding="UTF-8"?>
"-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
"com.security.dao.UserMapper">

    "userMapper" type="user">
        "id" property="id" />
        "name" property="name" />
        "email" property="email" />
        "roles" column="id"
            select="com.security.dao.RoleMapper.findRoleByUserId">
    

    

    

    

  • 建立相应的RoleMppaer.xml,并且定义sql语句
"1.0" encoding="UTF-8"?>
"-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
"com.security.dao.RoleMapper">

    "roleMapper" type="role">
        "id" property="id" />
        "name" property="name" />
        "users" column="id"
            select="com.security.dao.UserMapper.findUserByRoleId">
    

    

    

    

  • 多对多关联关系测试
public class MoreToMoreTest {

    private SqlSessionFactory sqlSessionFactory;

    /**
     * 获取SqlSessionFactory
     */
    @Before
    public void getSessionFactory() {
        String resource = "mybatis-config.xml";
        try {
            InputStream inputStream = Resources.getResourceAsStream(resource);
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Test
    public void testMoreToMore() {
        SqlSession session = sqlSessionFactory.openSession();
        try {
            /*RoleMapper roleMapper =      session.getMapper(RoleMapper.class);
            Role role = roleMapper.findRoleById(1);
            System.out.println(role);*/
            UserMapper userMapper=session.getMapper(UserMapper.class);
            User user=userMapper.findUserById(2);
            System.out.println(user);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (session != null) {
                session.close();
            }
        }
    }
}

你可能感兴趣的:(学习笔记,MyBatis)