Maven有哪些优缺点
优点:
- 简化了项目依赖管理
- 易于上手,对于新手可能一个mvn clean package命令就坑你满足他的工作
- 便于与持续集成工具(jenkins)整合
- 便于项目升级,无论项目本身升级还是项目使用的依赖升级
- 有助于多模块项目的开发,一个模块开发好后,发布到仓库,依赖该模块时可以直接去仓库更新,而不用自己去编译
- maven有很多插件,便于功能扩展,比如生产站点,自动发布版本等
缺点如下:
- maven是一个庞大的构件系统,学习难度大
- maven采用约定由于配置的策略(convention over configuration),虽然上手容易,但是一旦出了问题,难以调试
- 当依赖很多时,会导致编程软件变卡
- 不能访问外国的仓库
Maven的依赖范围有哪些
依赖范围:
A 依赖B,需要再A的pom.xml文件中添加B的坐标,添加坐标时需要指定依赖范围,依赖范围包括:
(1)compile:编译范围, 编译范围的依赖会在编译,测试,运行,打包(war)都会使用依赖jar包
(2)provided:提供依赖,provided依赖在编译,测试时需要,运行,打包都不会包含。
(3)runtime:运行依赖,runtime依赖在运行、测试、打包的需要,但在编译的时候不需要,比如:jdbc的驱动包
(4)test:测试依赖,在编译和运行时不需要,他们只有在测试编译和测试运行时使用, 比如junit,也不会被打包
(5)system:系统依赖,system依赖与provided类似,但是你必须显示的提供一个对于本地系统中jar文件的路径,需要指定systemPath磁盘路径,system依赖不推荐使用。
依赖范围 | 编译 | 测试 | 运行 | 打包(war) | 例子 |
---|---|---|---|---|---|
compile | yes | yes | yes | yes | beanutils、fileupload |
test | no | yes | no | no | junit |
provided | yes | yes | no | no | serlvet-api、jsp-api |
runtime | no | yes | yes | yes | jdbc驱动 |
system | yes | yes | no | no | 本地jar包。maven仓库之外的jar包 |
注意:打包jar包时,不会包含任何依赖包的。
默认依赖范围:compile
依赖范围由强到弱的顺序是:compile-->provided-->runtime-->test
MyBatis中#和$符号的区别
#{}
使用#{}意味着使用的预编译的语句,即在使用jdbc时的preparedStatement,sql语句中如果存在参数则会使用?作占位符,我们知道这种方式可以防止sql注入,并且在使用#{}时形成的sql语句,已经带有引号,例,select * from table1 where id=#{id} 在调用这个语句时我们可以通过后台看到打印出的sql为:select * from table1 where id=‘2’ 加入传的值为2.也就是说在组成sql语句的时候把参数默认为字符串。
${}
使用 $ {} 时的sql不会当做字符串处理,是什么就是什么,如上边的语句:select * from table1 where id=${id} 在调用这个语句时控制台打印的为:select * from table1 where id=2 ,假设传的参数值为2
从上边的介绍可以看出这两种方式的区别,我们最好是能用#{}则用它,因为它可以防止sql注入,且是预编译的,在需要原样输出时才使用${},如,
select * from ${tableName} order by ${id} 这里需要传入表名和按照哪个列进行排序 ,加入传入table1、id 则语句为:select * from table1 order by id
如果是使用#{} 则变成了select * from ‘table1’ order by ‘id’ 我们知道这样就不对了。
另,在使用以下的配置时,必须使用#{}
<select id="selectMessageByIdI" parameterType="int" resultType="Message">
select * from message where id=#{id};
</select>
在parameterType是int时,sql语句中必须是#{}。
MyBatis中如何传递多个参数?
方法1:顺序传参法
public User selectUser(String name, int deptId);
<select id="selectUser" resultMap="UserResultMap">
select * from user
where user_name = #{0} and dept_id = #{1}
</select>
#{}里面的数字代表你传入参数的顺序。
这种方法不建议使用,sql层表达不直观,且一旦顺序调整容易出错。
方法2:@Param注解传参法
public User selectUser(@Param(“userName”) String name, int @Param(“deptId”) deptId);
<select id="selectUser" resultMap="UserResultMap">
select * from user
where user_name = #{userName} and dept_id = #{deptId}
</select>
#{}里面的名称对应的是注解 @Param括号里面修饰的名称。
这种方法在参数不多的情况还是比较直观的,推荐使用。
方法3:Map传参法
public User selectUser(Map<String, Object> params);
<select id="selectUser" parameterType="java.util.Map" resultMap="UserResultMap">
select * from user
where user_name = #{userName} and dept_id = #{deptId}
</select>
#{}里面的名称对应的是 Map里面的key名称。
这种方法适合传递多个参数,且参数易变能灵活传递的情况。
方法4:Java Bean传参法
public User selectUser(User params);
<select id="selectUser" parameterType="com.test.User" resultMap="UserResultMap">
select * from user
where user_name = #{userName} and dept_id = #{deptId}
</select>
#{}里面的名称对应的是 User类里面的成员属性。
这种方法很直观,但需要建一个实体类,扩展不容易,需要加属性,看情况使用。
也可以用集合和数组传值,具体的可以看我上一个文章
Mybatis动态sql有什么用?执行原理?有哪些动态sql?
对于一些复杂的查询,我们可能会指定多个查询条件,但是这些条件可能存在也可能不存在,如果不使用持久层框架我们可能需要自己拼装SQL语句,不过MyBatis提供了动态SQL的功能来解决这个问题。MyBatis中用于实现动态SQL的元素主要有:if 、choose、 when、otherwise、trim、where、set 、foreach。执行原理是sql语句的拼接。