mybatis中的#和$的区别?
这是我在使用mybatis时候最蛋疼的问题,下面做出总结
1. #将传入的数据都当成一个字符串,会对自动传入的数据加一个双引号。
如:order by #user_id#,如果传入的值是111,那么解析成sql时的值为order by "111",
如果传入的值是id,则解析成的sql为order by "id".
2. $将传入的数据直接显示生成在sql中。
如:order by $user_id$,如果传入的值是111,那么解析成sql时的值为order by user_id,
如果传入的值是id,则解析成的sql为order by id.
3. #方式能够很大程度防止sql注入。
4.$方式无法防止Sql注入。
5.$方式一般用于传入数据库对象,例如传入表名.
6.一般能用#的就别用$.
注入攻击 就不用我多说了吧~
<![CDATA[ ]]> 这个是什么?
标明是纯文本的,没有这个的话 < > & 字符是不能直接存入XML的,需要转义,而用这个标记则不需要转义而将这些符号存入XML文档。
可以避免未预料的特殊符号导致XML解析出错。
在XML中的所有的text将被parser解析,当一个XML的元素被解析,XML tags之间的text也将别解析,之所以这样做,是因为在XML tags之间可能包含其它元素,例如:
<name><first>Bill</first><last>Gates</last></name> 。
<name>中包含<first>和<last>两个其它元素。Parser也必须对它们进行解析,并把它们解析成为<name>的两个字元素,但是如果在text中出现了“<”这种符号,例如:
<message>if salary < 1000 then</message>。
Parser将面临着一些困难,因为它需要判断:这是XML tag的开始;还是“<”小于号,这会导致解析错误。为了解决这个问题,代替符号“&”被使用,用它来代替“<”符号。
但是如果text中包含太多的“<”和“&”,例如程序中的逻辑判断。代替符号便不是一个好的办法。因此XML提供了CDATA section。
一个CDATA section 以"<![CDATA["开始,并以"]]>"结束。例如:
<script>
<![CDATA[
function matchwo(a,b)
{
if (a < b && a < 0) then
{
return 1
}
else
{
return 0
}
}
]]>
</script>
其中所有在CDATA section里的符号都将被忽略。
另:CDATA section中不能包含字符串“]]>”,因此CDATA section 不能嵌套。并且在“]]>”中不能有空格符或换行符。
1
程序代码
//声明一个session管理工厂 SqlSessionFactory factory =null; //声明读取器 Reader reader =null; try{ //通过读取器定位到主配置文件 reader = Resources.getResourceAsReader ("SqlMapConfig.xml"); //初始化工厂 factory =newSqlSessionFactoryBuilder().build(reader); }catch(IOException //TODOAuto-generated e.printStackTrace(); } //打开一个会话(类似于 SqlSession session = factory.openSession(); Person p =newPerson(); p.setName("张三" p.setAge(11); p.setBirthday(newDate()); //进行插入 try{ session.insert("org.leadfar.mybatis.Person.insert", //事务提交 session.commit(); System.out.println("保存成功!" }catch(Exception e.printStackTrace(); //事务回滚 session.rollback(); }finally{ //关闭连接 session.close(); } |
2sql
参数传递
1. 简单参数
<deleteid="delete"parameterType="int"> delete from t_person where id=#{id} <!—无所谓写什么都可以à </delete> |
2. 多个参数,建议采用
Map 包装
<selectid="selectLikeNameAndAgeBetween"parameterType="map"resultType="Person"> <includerefid="selectBasic"/>where </select> |
SqlSession session =factory.openSession(); Mapmap =newHashMap(); map .put("name","%张%" map .put("age1", map .put("age2", List persons=session.selectList(Person.class.getName()+".selectLikeNameAndAgeBetween",map System.out.println(((Person)(persons.get(0))).getName()); session.close(); |
3.sql
语句块
<sqlid="selectBasic"> select * from t_person </sql> <selectid="selectLikeName"parameterType="string"resultType="Person"> <includerefid="selectBasic"/>where </select> |
4属性名与字段名不匹配
<resultMaptype="Person"id="select-reusltMap">
<resultcolumn="sex"property="gender"/>
</resultMap>
<selectid="selectLikeNameAndAgeBetweenResultMap"parameterType="map"resultMap="select-reusltMap">
<includerefid="selectBasic"/>where
name like #{name} and age between #{age1} and #{age2}
</select>
5
动态 sql
5.1
.if
<selectid="selectIf"parameterType="map"resultType="Person"> select * from t_person <iftest="name where name like #{name} </if> <iftest="age and age=#{age} </if> </select> |
注:如果 name==null
,则 sql 拼写错误
<selectid="selectWhere"parameterType="map"resultType="Person"> select * from t_person <where> <iftest="name name like #{name} </if> <iftest="age and age=#{age} </if> </where> </select> |
注 :
加 <where> 后则确保一定是where开头
5.2
.choose
类似于 switch
<selectid="selectChoose"parameterType="map"resultType="Person"> select * from t_person <choose> <whentest="name!=null"> where name like #{name} </when> <otherwise> where name like ‘%%‘ </otherwise> </choose> <iftest="age and age=#{age} </if> </select> |
5.3
.foreach
如 in
操作
<selectid="selectFor"parameterType="list"resultType="Person"> select * from t_person where id in <foreachcollection="list"item="p"open="("close=")"separator=","> #{p} </foreach> </select> |
SqlSession session =factory.openSession(); Listl =newArrayList(); l .add(1); l .add(2); l .add(3); l .add(4); List persons=session.selectList(Person.class.getName()+".selectFor",l System.out.println(((Person)(persons.get(1))).getName()); session.close(); |
5.4
$
相当于转义,字符串替换
<selectid="selectIn"parameterType="map"resultType="Person"> select * from t_person where id in ${instr} </select> |
SqlSession session =factory.openSession(); Map params=newHashMap(); //params.put("name", "%张%"); params.put("instr","(1,2,3,4)"); List persons=session.selectList(Person.class.getName()+".selectIn",params); System.out.println(((Person)(persons.get(1))).getName()); session.close(); |
另外对于排序时由外部传入某字段
<selectid="selectOrderBy"parameterType="map"resultType="Person"> select * from t_person </select> |
SqlSession session =factory.openSession(); Map params=newHashMap(); //params.put("name", "%张%"); params.put("by","age List persons=session.selectList(Person.class.getName()+".selectOrderBy",params); System.out.println(((Person)(persons.get(1))).getName()); session.close(); |
6
一对一映射
6.1
简单方法
设 Person
与 Address 是一对一关系
PersonMapper.xml
<resultMaptype="Person"id="select-resultMap"> <!--一对一(多对一 <associationproperty="address"select="org.leadfar.mybatis.Address.selectAll"column="id"javaType="Address">
</association> </resultMap> |
<selectid="selectAll"resultMap="select-resultMap"> select * from t_person </select> |
AddressMapper.xml
<selectid="selectAll"parameterType="int"resultType="Address"> select * from t_address where person_id=#{pId} </select> |
6.2
解决 N+1
问题
<selectid="selectAllN1"resultMap="select-resultMapN1"> select a.*,b.id addr_id, b.postCode,b.area from t_person a left join t_address b on a.id=b.person_id </select> |
<!--这种方式能解决N+1问题,但是自动对象赋值将不行--> <resultMaptype="Person"id="select-resultMapN1"> <idcolumn="id"property="id"/> <resultcolumn="sex"property="gender"/> <resultcolumn="name"property="name"/> <resultcolumn="birthday"property="birthday"/> <resultcolumn="age"property="age"/> <associationproperty="address"column="id"javaType="Address"> <idcolumn="addr_id"property="id"/> <resultcolumn="area"property="area"/> <resultcolumn="postCode"property="postCode"/> </association> </resultMap> |
7
一对多映射
设 Person
和 Car 为一对多关系
<selectid="selectAllN1"resultMap="select-resultMapN1"> select a.*,b.id addr_id, b.postCode,b.area from t_person a left join t_address b on a.id=b.person_id </select> |
<!--这种方式能解决N+1问题,但是自动对象赋值将不行--> <resultMaptype="Person"id="select-resultMapN1"> <idcolumn="id"property="id"/> <resultcolumn="sex"property="gender"/> <resultcolumn="name"property="name"/> <resultcolumn="birthday"property="birthday"/> <resultcolumn="age"property="age"/> <associationproperty="address"column="id"javaType="Address"> <idcolumn="addr_id"property="id"/> <resultcolumn="area"property="area"/> <resultcolumn="postCode"property="postCode"/> </association> <!--将t_car中相关的数据与目标对象(Person)中的cars属性进行对应--> <collectionproperty="cars"column="id"select="org.leadfar.mybatis.Car.selectByPerson"></collection> </resultMap> |