本文已参与「新人创作礼」活动,一起开启掘金创作之路。
1.lombok 补充
之前项目用到了lombok 来简化开发,省去了写get,set和构造等繁琐的操作,但是有的朋友引入了依赖却无法使用,这里从头介绍下。
Project Lombok 是一个 java 库,可自动插入您的编辑器和构建工具,为您的 java 增添趣味。 永远不要再编写另一个 getter 或 equals 方法,使用一个注释,您的类就有一个功能齐全的构建器、自动化您的日志记录变量等等
1.1 安装依赖
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.10</version>
</dependency>
</dependencies>
或者
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok-maven-plugin</artifactId>
<version>1.18.12.0</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
或者直接去maven官网
1.2 idea开启插件
安装Lombok plugin
Setting -> plugin->搜Lombok 安装后重启
设置 Setting -> Compiler -> Annotation Processors -> Enable annotation processing勾选。
1.3 常用的注解
@NoArgsConstructor: 自动生成无参数构造函数。 @AllArgsConstructor: 自动生成全参数构造函数。 @Data: 自动为所有字段添加@ToString, @EqualsAndHashCode, @Getter方法, 对应的实体类中加上上面三个注解即可
2.xml进阶
2.1模糊查询like(concat)
之前查询都是id= #{}这种变量传参,对于模糊查询like 直接加上%% 可能会有sql注入的风险。 我们有两种方式防止sql注入。 1.直接字串串传参的方式
String name = “%smi%”;
2.concat
WHERE name like concat('%',#{name},'%')
2.2 ResultMap的用法
对于通常我们查询到的sql结果和实体类是一一对应的,我们用resultType即可。 但是如果我们的查询结果和实体类不对应就需要使用ResultMap了。
<resultMap id="UserMap" type="User">
<id column="id" property="id"/>
<result column="name" property="name"/>
<result column="pwd" property="password"/>
</resultMap>
<select id="selectUserById" resultMap="UserMap">
select id , name , pwd from user where id = #{id}
</select>
指定对应的id即可 column是数据库表的列名 , property是对应实体类的属性名 我们还可以加入jdbcType="VARCHAR"
<result column="name" jdbcType="VARCHAR" property="name"/>
2.3 标签
和ResultMap类似,对于需要查询的结果如果不是*,但是字段特别多,我们每个sql都写比较麻烦,可以写在sql标签中
<resultMap id="UserMap" type="User">
<id column="id" property="id"/>
<result column="name" property="name"/>
<result column="pwd" property="password"/>
</resultMap>
<sql id="Base_Column_List">
id , name , pwd
</sql>
<select id="selectUserById" resultMap="UserMap">
select
<include refid="Base_Column_List" />
from user where id = #{id}
</select>
这样查询结果通用的情况,指定sql就行。
2.4 万能map
通常我们都是传一个对象进行传参,其实实际开发为了方便,一些简单的sql我们传map作为参数也可。 在接口方法中,参数直接传递Map;
User selectUserByNP2(Map<String,Object> map);
编写sql语句的时候,需要传递参数类型,参数类型为map
<select id="selectUserByNP2" parameterType="map" resultType="com.liu.pojo.User">
select * from user where name = #{username} and pwd = #{pwd}
</select>
在使用方法的时候,Map的 key 为 sql中取的值即可,没有顺序要求!
Map<String, Object> map = new HashMap<String, Object>();
map.put("username","小明");
map.put("pwd","123456");
User user = mapper.selectUserByNP2(map);
3.分页
4.动态sql
MyBatis 的强大特性之一便是它的动态 SQL。如果你有使用 JDBC 或其它类似框架的经验,你就能体会到根据不同条件拼接 SQL 语句的痛苦。例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号。利用动态 SQL 这一特性可以彻底摆脱这种痛苦。
4.1 if 标签
if语句就是动态的判断是否为真,通常我们实际开发过程中,对于下拉框搜索,我们写一个sql即可,通过传来的不同的参数判断是否进行拼接判断,比如
<select id="selectUserById" resultType="com.liu.pojo.User">
select * from user where id = #{id} and name like concat('%',#{name},'%')
</select>
我们要的效果是,如果User是空的,就查询所有,如果有id就查询id,如果有name就查询name,如果都有就一起拼接。 改为if标签即可
<select id="selectUserById" resultType="com.liu.pojo.User">
select * from user where 1=1
<if test="id!= null">
and id= #{id}
</if>
<if test="author != null">
and name like concat('%',#{name},'%')
</if>
</select>
4.2 Where 标签
上面的语句我们都使用了where 1=1,因为不拼接的话,哪里要加and哪里不加不好判断,where标签就为我们解决了这一个问题。
<select id="selectUserById" resultType="com.liu.pojo.User">
select * from user
<where>
<if test="id!= null">
id= #{id}
</if>
<if test="author != null">
name like concat('%',#{name},'%')
</if>
</where>
</select>
这个“where”标签会知道如果它包含的标签中有返回值的话,它就插入一个‘where’。此外,如果标签返回的内容是以AND 或OR 开头的,则它会剔除掉
4.3 Set 标签
和where标签类似,set标签帮我们去除多余的逗号,多用于update
<update id="updateUser" parameterType="com.liu.pojo.User">
update user set name=#{name},pwd=#{pwd} where id = #{id}
</update>
我们用set标签
<update id="updateUser" parameterType="com.liu.pojo.User">
update user
<set>
<if test="name!= null">
name= #{name},
</if>
<if test="pwd!= null">
pwd= #{pwd}
</if>
</set>
where id = #{id}
</update>
这样如果我们的pwd不需要修改,没有传值,set标签会自动去除name后面的标签。
4.4 trim标签
除了where和set,我们还有更为灵活的标签,trim标签,他的作用通过配置做到和set更为强大的作用。
prefix :给sql语句拼接的前缀 suffix :给sql语句拼接的后缀 prefixOverrides:去除sql语句前面的关键字或者字符,该关键字或者字符由prefixOverrides属性指定,假设该属性指定为"AND",当sql语句的开头为"AND",trim标签将会去除该"AND" suffixOverrides:去除sql语句后面的关键字或者字符,该关键字或者字符由suffixOverrides属性指定
通常我们在insert用的比较多
<insert id="addUser" parameterType="com.liu.pojo.User">
insert into user (id,name,pwd) values (#{id},#{name},#{pwd})
</insert>
使用trim标签
<insert id="addUser" parameterType="com.liu.pojo.User">
insert into user
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="id!= null">
id,
</if>
<if test="name!= null">
name,
</if>
<if test="pwd!= null">
pwd,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="id != null">
#{id},
</if>
<if test="name != null">
#{name},
</if>
<if test="pwd != null">
#{pwd},
</if>
</trim>
</insert>
自动在前面帮我们拼接()和value。
4.5 Foreach标签
我用的不多,后面用到再我学
5.使用注解开发
动态sql实际开发没有xml开发灵活,对于多对多的关系无法处理,但是我们对于简单的sql可以用注解开发,实际还是按照公司规范来。 虽然简单的sql开发用注解会简单,但是公司统一用配置文件的话我们还是不建议用注解 因为通用mapper或者mybatisplus都能更好的开发。 MyBatis-Plus快速入门
5.1 修改配置文件mybatis-config.xml
<mappers>
<!--<mapper resource="com/liu/mapper/userMapper.xml"/>-->
<mapper class="com.liu.mapper.UserMapper2"/>
</mappers>
其中UserMapper2文件是我们为了测试新建的类
5.2 新建UserMapper2
public interface UserMapper2 {
//查询全部用户
@Select("select id,name,pwd password from user")
public List<User> getAllUser();
}
5.3修改之前的测试类
@Test
public void selectUser() {
SqlSession session = MybatisUtils.getSession();
UserMapper2 mapper = session.getMapper(UserMapper2.class);
List<User> users = mapper.getAllUser();
for (User user: users){
System.out.println(user);
}
session.close();
}
5.4 CURD
5.4.1查询
//根据id查询用户
@Select("select * from user where id = #{id}")
User selectUserById(@Param("id") int id);
5.4.2新增
//添加一个用户
@Insert("insert into user (id,name,pwd) values (#{id},#{name},#{pwd})")
int addUser(User user);
5.4.3修改
//修改一个用户
@Update("update user set name=#{name},pwd=#{pwd} where id = #{id}")
int updateUser(User user);
5.4.4删除
//根据id删除用
@Delete("delete from user where id = #{id}")
int deleteUser(@Param("id")int id);
对于注解开发,无论是增删改查都不需要提交事务。