🤭🤭
MyBatis获取参数的两种方式
${}
字符串拼接
若为字符串类型或日期类型的字段进行赋值时,需要手动添加单引号
#{}
占位符赋值
为字符串类型或日期类型的字段进行赋值时,可以自动添加单引号
开发小技巧
1、在idea中设置模板
1.1、核心配置文件

<?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>
    <!--读取properties配置文件-->
    <properties resource="jdbc.properties"/>
    <!--设置某个具体的类型的别名-->
    <typeAliases>
        <package name=""/>
    </typeAliases>
    <!--设置连接数据库的环境-->
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driver}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>
    </environments>
    <!--引入映射文件-->
    <mappers>
        <package name=""/>
    </mappers>
</configuration>
1.2、映射文件的模板
<?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="">
    
    
</mapper>
2、封装SqlSessionUtils工具类
😄只是方便自己划水罢了
public class SqlSessionUtils {
    public static SqlSession getSqlSession() {
        SqlSession sqlSession = null;
        try {
            InputStream resourceAsStream = Resources.getResourceAsStream("mybatis-config.xml");
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
            sqlSessionFactory.openSession(true);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return sqlSession;
    }
}
1、单个字面类型的参数
mapper接口中的方法的参数为单个的字面量类型,${}和#{}都可以用
他们只起到占位符的作用,${username}⭐!!${aaa}也行
<!--User getUserByUserName(String username);-->
<select id="getUserByUserName" resultType="User">
    select * from t_user where username = #{aaa}
    <!--或者 select * from t_user where username = '${aaa}'-->
</select>
2、多个字面量类型的参数
mapper接口中的方法参数为多个时
时MyBatis会自动将这些参数放在一个map集合中
以arg0,arg1...为键,以参数为值 ;以 param1,param2...为键,以参数为值;
因此只需要通过${}和#{}访问map集合的键就可以获取相对应的值
<!--User getUserByUserNameAndPassword(String username,String password);-->
<select id="getUserByUserNameAndPassword" resultType="User">
    select * from t_user where username = #{arg0} and password = '${param2}'
</select>
3、map集合类型的参数
手动创建map集合,将这些数据放在map中 只需要通过${}和#{}访问map集合的键就可以获取相对应的值
<!--User checkLoginByMap(Map<String,Object> map);-->
<select id="checkLoginByMap" resultType="User">
    select * from t_user where username = #{username} and password = '${password}'
</select>
@Test
public void checkLoginByMap(){
    SqlSession sqlSession = SqlSessionUtils.getSqlSession();
    ParameterMapper mapper = sqlSession.getMapper(ParameterMapper.class);
    Map<String,Object> map = new HashMap<String,Object>();
    map.put("username","haha");
    map.put("password","654321");
    System.out.println(mapper.checkLoginByMap(map));
}
4、实体类类型的参数
mapper接口中的方法参数为实体类对象
此时可以使用${}和#{},通过访问实体类对象中的属性名获取属性值
<!--int insertUser(User user);-->
<insert id="insertUser">
    insert into t_user values(null,#{username},#{password},#{age},#{sex},#{email})
</insert>
@Test
public void insertUser(){
    SqlSession sqlSession = SqlSessionUtils.getSqlSession();
    ParameterMapper mapper = sqlSession.getMapper(ParameterMapper.class);
    System.out.println(mapper.insertUser(new User(null,"www","123456",26,"男","123@qq.com")));
}
5、使用@Param标识参数
通过@Param注解标识mapper接口中的方法参数
会将这些参数放在map集合中,以@Param注解的value属性值为键,以参数为值;以 param1,param2…为键,以参数为值;只需要通过${}和#{}访问map集合的键就可以获取相对应的值
<!--User checkLoginByParam(@Param("username") String username,@Param("password") String password);-->
<select id="checkLoginByParam" resultType="User">
    select * from t_user where username = #{username} and password = #{password};
</select>
MyBatis的各种查询功能
MyBatis中,对于Java中常用的类型都设置了类型别名
| Alias | Mapped Type | 
|---|---|
| _byte | byte | 
| _long | long | 
| _short | short | 
| _int | int | 
| _integer | int | 
| _double | double | 
| _float | float | 
| _boolean | boolean | 
| string | String | 
| byte | Byte | 
| long | Long | 
| short | Short | 
| int | Integer | 
| integer | Integer | 
1、查询单个数据
resultType 属性使用了别名
<!--int getCount();-->
<select id="getCount" resultType="_int">
    select count(*) from t_user
</select>
2、查询一条数据转为Map集合
<!--Map<String,Object> getUserToMap(@Param("id") int id);-->
<select id="getUserToMap" resultType="map">
    select * from t_user where id = #{id}
</select>
@Test
public void getUserToMap(){
    SqlSession sqlSession = SqlSessionUtils.getSqlSession();
    ParameterMapper mapper = sqlSession.getMapper(ParameterMapper.class);
    Map<String, Object> userToMap = mapper.getUserToMap(2);
    System.out.println(userToMap);  // {password=123, sex=男, id=2, age=23, email=123@flzj.com, username=flzj_kl}
    System.out.println(userToMap.get("username"));  // flzj_kl
    System.out.println(userToMap.get("id"));    // 2
}
3、查询多条数据转为map集合
<!--List<Map<String, Object>> getAllUserToMap();-->
<select id="getAllUserToMap" resultType="map">
    select * from t_user
</select>
@Test
public void getAllUserToMap(){
    SqlSession sqlSession = SqlSessionUtils.getSqlSession();
    ParameterMapper mapper = sqlSession.getMapper(ParameterMapper.class);
    List<Map<String, Object>> allUserToMap = mapper.getAllUserToMap();
    System.out.println(allUserToMap);
}
@Map标签
@MapKey("id")
Map<String, Object> getAllUserToMap();
特殊SQL的执行
给我整😶了,这不就是正常的操作吗
1、模糊查询
<!--List<User> vagueQuery(@Param("vague") String vague);-->
<select id="vagueQuery" resultType="User">
    <!--select * from t_user where username like '%${vague}%'-->
<!--select * from t_user where username like concat('%',#{vague},'%')-->
    select * from t_user where username like "%"#{vague}"%"
</select>
public void TestVague(){
    SqlSession sqlSession = SqlSessionUtils.getSqlSession();
    ParameterMapper mapper = sqlSession.getMapper(ParameterMapper.class);
    List<User> list = mapper.vagueQuery("f");
    System.out.println(list);
}
2、批量删除
<!--int deleteMore(@Param("ids") String ids);-->
<delete id="deleteMore">
    delete from t_user where id in (${ids})
</delete>
@Test
public void deleteMore(){
    SqlSession sqlSession = SqlSessionUtils.getSqlSession();
    ParameterMapper mapper = sqlSession.getMapper(ParameterMapper.class);
    System.out.println(mapper.deleteMore("1,2,4"));
}
3、动态设置表名
<!--List<User> getAllUser(@Param("tableName") String tableName);-->
<select id="getAllUser" resultType="User">
    select * from ${tableName}
</select>
4、取自增的主键
useGenerateKeys : 设置使用自增的主键
keyProperty : 因为增删改有统一的返回值是受影响的行数,因此只能将获取的自增的主键放在传输的参 数user对象的某个属性中
<!--int insertUser(User user);-->
<insert id="insertUser" useGeneratedKeys="true" keyProperty="id">
    insert into t_user values(null,#{username},#{password},#{age},#{sex},#{email})
</insert>
@Test
public void insertUser(){
    SqlSession sqlSession = SqlSessionUtils.getSqlSession();
    ParameterMapper mapper = sqlSession.getMapper(ParameterMapper.class);
    User user = new User(null, "这里的id是有值的", "123456", 26, "男", "123@qq.com");
    mapper.insertUser(user);
    System.out.println(user); // User{id=10, username='这里的id是有值的', ...
}
自定义映射resultMap
1、resultMap处理字段和属性的映射关系
若字段名和实体类中的属性名不一致,则可以通过resultMap设置自定义映射
比如 : 字段user_name 和 属性名userName
需要来到我们的com/flzj/mapper/MyBatis3Mapper.xml文件下
所有的字段和属性都要设置映射关系
resultMap标签
设置自定义映射
id属性 : 表示自定义映射的唯一标识
type属性 : 查询的数据要映射的实体类的类型
id标签
用来设置主键
property属性 : 设置映射关系中实体类中的属性名
column属性 : 设置映射关系中的字段名
result标签
设置普通字段的映射关系
property属性 : 设置映射关系中实体类中的属性名
column属性 : 设置映射关系中的字段名
<resultMap id="empMap" type="Emp">
    <id property="id" column="id"></id>
    <result property="username" column="user_name"></result>
</resultMap>
<!--List<Emp> getAllEmp();-->
<select id="getAllEmp" resultMap="empMap">
    select * from emp
</select>
若字段名和实体类中的属性名不一致,但是字段名符合数据库的规则(使用_),实体类中的属性 名符合Java的规则(使用驼峰)
起别名
保证和实体类中的属性名保持一致
<!--List<Emp> getAllEmp();-->
<select id="getAllEmp" resultType="emp">
    select id,user_name username from emp
</select>
// 字段
private Integer id;
private String username;
// 属性
| id | user_name|
|  1 |     a    |
设置xml
可以到核心配置文件中设置
<settings>
    <!--将表中字段的下划线自动转换为驼峰 t_user : tUser -->
    <setting name="mapUnderscoreToCamelCase" value="true"/>
<settings>
<!--List<Emp> getAllEmp();-->
<select id="getAllEmp" resultType="emp">
    select id,user_name from emp
</select>
2、多对一映射处理
两个🤡javaBean
public class Emp {
    private Integer id;
    private String username;
    private Dept dept;
...
public class Dept {
   private Integer did;
   private String deptName;
两个🤡表
create table emp
(
    id        int         null,
    user_name varchar(32) null,
    did       int         null
);
create table dept
(
    did       int auto_increment primary key,
    dept_name varchar(32) null
);
2.1、级联方式处理映射关系
MyBatis3Mapper.xml
<resultMap id="empAndDeptResultMapOne" type="Emp">
    <id property="id" column="id"></id>
    <result property="username" column="user_name"></result>
    <result property="dept.did" column="did"></result>
    <result property="dept.deptName" column="dept_name"></result>
</resultMap>
<!--Emp getEmpAndDeptById(@Param("id") int id);-->
<select id="getEmpAndDeptById" resultMap="empAndDeptResultMapOne">
    select  * from emp left join dept on emp.did = dept.did where emp.id = #{id}
</select>
2.2、association处理映射关系
property属性 : 我们要处理的多对一的属性
javaType属性 : 属性的类型
<resultMap id="empAndDeptResultMapOne" type="Emp">
    <id property="id" column="id"></id>
    <result property="username" column="user_name"></result>
    <association property="dept" javaType="Dept">
        <id property="did" column="did"></id>
        <result property="deptName" column="dept_name"></result>
    </association>
</resultMap>
2.3、分步查询(多用)
select属性 : 设置分布查询,查询某个属性的值的sql的标识
column属性 : 将sql以及查询结果中的某个字段设置为分布查询的条件
我们需要用两个查询
<resultMap id="empDeptStepMap" type="Emp">
    <id property="id" column="id"></id>
    <result property="username" column="user_name" ></result>
    <association property="dept"
                 select="com.flzj.mapper.MyBatis3Mapper.getEmpByStepTwo"
                 column="did"   >
    </association>
</resultMap>
<!-- 关于写这个resultMap 那是因为部门名查不出来-->
<resultMap id="getEmpByStepTwoDept" type="dept">
    <id property="did" column="did"></id>
    <result property="deptName" column="dept_name"></result>
</resultMap>
<!--第二个查询-->
<!--Emp getEmpByStepTwo(@Param("did") int did);-->
<select id="getEmpByStepTwo" resultMap="getEmpByStepTwoDept">
    select * from dept where did = #{did}
</select>
<!--第一个查询-->
<!--Emp getEmpByStepOne(@Param("id") int id);-->
<select id="getEmpByStepOne" resultMap="empDeptStepMap">
    select * from emp where id = #{id}
</select>
可以实现延迟加载,但是必须在核心配置文件中设置全局配置信息
3、一对多映射处理
那我们的Dept类就要新增,一个集合
public class Dept {
    private Integer did;
    private String deptName;
    private List<Emp> emps;
 ....
3.1、collection
ofType属性:设置collection标签所处理的集合属性中存储数据的类型
<resultMap id="getDeptEmpByIdMapper" type="Dept">
    <id property="did" column="did"></id>
    <result property="deptName" column="dept_name"></result>
    <collection property="emps" ofType="Emp">
        <id property="id" column="id"></id>
        <result property="username" column="user_name"></result>
    </collection>
</resultMap>
<!--Dept getDeptEmpById(@Param("did") int did);-->
<select id="getDeptEmpById" resultMap="getDeptEmpByIdMapper">
    select * from dept left join emp on dept.did = emp.did where dept.did = #{did}
</select>
3.2、分步查询(多用)
column属性 : 将sql以及查询结果中的某个字段设置为分布查询的条件
查询部门信息 + 根据部门id查询部门中的所有员工
<resultMap id="deptAndEmpByStepResultMap" type="Dept">
    <id property="did" column="did"></id>
    <result property="deptName" column="dept_name"></result>
    <collection property="emps"
                select="com.flzj.mapper.MyBatis3Mapper.getDeptByStepTwo"
                column="did"
                ></collection>
</resultMap>
<!--List<Emp> getDeptByStepTwo(@Param("did") Integer did);-->
<select id="getDeptByStepTwo" resultType="Emp">
    select * from emp where did = #{did}
</select>
<!--Dept getDeptByStepOne(@Param("did") int did);-->
<select id="getDeptByStepOne" resultMap="deptAndEmpByStepResultMap">
    select * from dept where did = #{did}
</select>
4、延迟加载
在核心配置文件中
lazyLoadingEnabled属性 : 延迟加载的全局开关。当开启时所有对象都会延迟加载(分步的第二、第三…步)
aggressiveLazyLoading属性:当开启时,任何方法的调用都会加载该对象的所有属性。 否则,每个属性会按需加载 (默认为false)
<settings>
    <!--开启懒加载-->
    <setting name="lazyLoadingEnabled" value="true"/>
</settings>
开启延迟加载后的效果
System.out.println(emp.getUsername());  // 需要查1张表
/*
DEBUG 04-04 22:41:52,010                                                    ==>  Preparing: select * from emp where id = ? (BaseJdbcLogger.java:137) 
DEBUG 04-04 22:41:52,033                                                    ==> Parameters: 1(Integer) (BaseJdbcLogger.java:137) 
DEBUG 04-04 22:41:52,086                                                    <==      Total: 1 (BaseJdbcLogger.java:137) 
a
*/
System.out.println(emp);		// 需要查2张表
/*
DEBUG 04-04 22:43:21,362                                                    ==>  Preparing: select * from emp where id = ? (BaseJdbcLogger.java:137) 
DEBUG 04-04 22:43:21,387                                                    ==> Parameters: 1(Integer) (BaseJdbcLogger.java:137) 
DEBUG 04-04 22:43:21,435                                                    <==      Total: 1 (BaseJdbcLogger.java:137) 
DEBUG 04-04 22:43:21,435                                                    ==>  Preparing: select * from dept where did = ? (BaseJdbcLogger.java:137) 
DEBUG 04-04 22:43:21,436                                                    ==> Parameters: 1(Integer) (BaseJdbcLogger.java:137) 
DEBUG 04-04 22:43:21,439                                                    <==      Total: 1 (BaseJdbcLogger.java:137) 
Emp{id=1, username='a', dept=Dept{did=1, deptName='部门1'}}
*/
在Mapper中
当开启全局的延迟加载之后,可以通过此属性手动控制延迟加载效果
fetchType属性 : eager立即加载 lazy懒加载
<resultMap id="empDeptStepMap" type="Emp">
    <id property="id" column="id"></id>
    <result property="username" column="user_name" ></result>
    <association property="dept"
                 select="com.flzj.mapper.MyBatis3Mapper.getEmpByStepTwo"
                 column="did"
                 fetchType="eager">
    </association>
</resultMap>
效果
System.out.println(emp.getUsername());
/*
DEBUG 04-04 22:48:37,551                                                    ==>  Preparing: select * from emp where id = ? (BaseJdbcLogger.java:137) 
DEBUG 04-04 22:48:37,572                                                    ==> Parameters: 1(Integer) (BaseJdbcLogger.java:137) 
DEBUG 04-04 22:48:37,587                                                    ====>  Preparing: select * from dept where did = ? (BaseJdbcLogger.java:137) 
DEBUG 04-04 22:48:37,587                                                    ====> Parameters: 1(Integer) (BaseJdbcLogger.java:137) 
DEBUG 04-04 22:48:37,591                                                    <====      Total: 1 (BaseJdbcLogger.java:137) 
DEBUG 04-04 22:48:37,591                                                    <==      Total: 1 (BaseJdbcLogger.java:137) 
a
*/
嗨呀呀,好像1不小心,又写长了,四月来了,给我充充充!!!!这个月🈲和舍友训练,再训练我是🐕










