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集合
方式1
<!--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);
}
方式2
@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、一对多映射处理
例子 : 根据部门id查新部门以及部门中的员工信息
那我们的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不小心,又写长了,四月来了,给我充充充!!!!这个月🈲和舍友训练,再训练我是🐕