注意:表名和列名以及排序的字段不能使用占位符,其中表名和排序的字段使用占位符会报错,而列名使用占位符查询的结果不正确,由于占位符一般都是传递条件的,也就是在where子句中使用,对于其他的则需要进行拼串操作,这时就需要特殊的符号进行拼串操作,即${},通过此种方式传参数,参数作为sql文的一部分执行,也就是拼串操作,所以这时就应该注意sql注入的问题,如果是条件中使用参数,那么必须采用占位符,如果其他的场合,可以采用拼串,而且如果是用户输入的,也不能采用拼串的方式
3.关于模糊查询中的参数格式问题:
select * from t_user where username like '%admin%';
由于admin是需要外部传递参数进来,此时就需要注意参数的格式问题,可通过以下格式:
select * from t_user where username like '%${username}%';
但是不安全,因为在条件中进行了拼串的操作,必须采用占位符,就可以在后台加上%%后再将参数传进去
select * from t_user where username like #{username};
但是不方便,Java代码和sql语句的耦合性太高,应该各自独立,这时可以通过不同的数据库采用不同的方式来实现sql的字符串的拼接操作
MySQL:concat(s1,s2,s3…..)
select * from t_user where username like concat('%',#{username},'%');
Oracle和DB2:通过||或concat(s1,s2,s3…..)来进行拼串
select * from t_user where username like '%'||#{username}||'%';
或者
SELECT * FROM t_user WHERE name like CONCAT('%',#{name},'%')
SQLServer:通过+拼接
SELECT * FROM t_user WHERE name like '%'+#{name}+'%'
还有一种方式就是使用MyBatis自带的bind标签:
<select id="selectPersons" resultType="person" parameterType="person">
"pattern" value="'%' + _parameter.username + '%'" />
select id,sex,age,username,password from person where username LIKE #{pattern}
select>
4.MyBatis框架的输出,也就是sql的操作结果,增删改就返回数据库中被影响的数据条数。
resultType:该属性表示将查询结果转换为指定类型的对象,MyBatis框架是面向sql的,所以对像和sql没有关系,将查询结果转换为指定类型的对象时,需要遵循转换的规则,将查询结果字段名称和指定类型的属性名称进行匹配,如果匹配成功则反射调用,如果匹配不成功,什么也不做,在极限情况下,一个属性都没有匹配成功,那么对象不会创建,获取null,当名称不一致时也希望转换成功,那么需要改名,即将查询的结果使用别名,as xxxx,而且也可以将查询的结果字段的名称通过独立的配置方式进行改变,如下:
<resultMap type="com.ecjtu.test.bean.User",id=userMap>
<result column="ID" jdbcType="VARCHAR" property="id" />
<result column="password" property="password"/>
resultMap>
<select id="selectUsers" resultMap="userMap">
select * from t_user
select>
查询的结果转换为指定的类型:
a.自定义类型:(获取数据之间存在关系时使用)
将查询结果字段名称和自定义类型的属性名称一一对应
b.将查询结果转换为map(获取的数据之间没有任何关系时使用)
resultType="java.util.HashMap"
将查询结果字段名作为key,将查询结果值作为val,形成键值对的形式
c.基本数据类型
resultType="java.lang.String"
返回的是查询结果的第一个字段值
5.有关MyBatis的分页查询问题:
a.逻辑分页
一次性将数据库中所有数据查询出来,放置在缓存中,通过逻辑算法获取指定页码的数据,这种分页方式称为逻辑分页,这种方式查询效率快(内存操作),但第一次查询所有的数据可能会很慢,因为不确定数据库中有多少数据,如果数据量大的话就会很慢,会查询很多用户根本用不到的数据
而且会占用大量内存,降低了服务器的性能
RowBounds rb = new RowBounds((pageNo-1)*pageSize,pageSize);
session.selectList(sqlId,argObject,rowBounds);
b.物理分页
采用数据库本身的分页机制来实现分页查询操作,称之为物理分页,效率低(进程操作),但是一般使用这种,因为这种方式最适合我们的业务需要,毕竟客户只是想要翻页查看他们想要的数据,而不会一直去翻所有页的数据
mysql:limit 0(可省略不写),pagesize,limit startIndex,pagesize
int pageno = 1;
int pageSize = 5;
int pageIndex = (pageno-1)*pageSize
select * from t_user limit #{pageIndex},#{pageSize};
oracle:三层查询嵌套 + rowNum
select * from t_user where rownum > 5 and rownum <= 10;
由于oracle中rownum大于等于的条件是不支持的
select * from (
select t.*, rownum as num from t_user where rownum <= 10
)
where num > 5
又由于rownum无法和order by语句在一起使用
select * from (
select t.*, rownum as num from(
select * from t_user order by regdate
)t
where rownum <= 10)
where num > 5
注意:
嵌套查询其实很慢,我们可以根据需要进行选择,当从第一条数据并且没有排序的分页查询时,就可以只使用一层,当没有排序时使用两层,都有时才使用三层嵌套查询
6.数据库三个术语:
DDL:数据库定义语言,create drop
DML:数据库操作语言,insert delete update,涉及到事物的提交和回滚
DQL:数据库查询语言,select
增删改操作的SQL:
<insert id="addUser" parameterType="com.ecjtu.mybatis.entity.User" useGeneratedKeys="true" keyProperty="id">
insert into user values(#{id},#{userName},#{userAge},#{userAddress})
insert>
update user set userName=#{userName},userAge=#{userAge},userAddress=#{userAddress} where id=#{id}
<delete id="deleteUser" parameterType="int">
delete from user where id=#{id}
delete>
如果表的主键是自增长的,那么在插入数据之后需要立即获取自增长的主键值,而且MySql中自增长的一定是int类型,获取自增长主键格式如下:
insert into tab_user (
username,password
)values(
#{username},
#{password},
)
"id" resultType="java.lant.Integer">
select @@identity as id
Oracle:自增长的类型可以为int,也可以为String
insert into tab_user(id) values(userseq.nextval)
"id" resultType="java.lant.Integer">
select userseq.currval from dual
7.有关数据库的事物
传统的JDBC事物管理方式:
try{
conn.setAutoCommit(false);
}catch{
conn.rollback();
}finally{
conn.commit();
conn.setAutoCommit(true);
}
MyBatis中底层事物管理方式:没有提交就会在finally语句块中进行回滚,session.close()操作里面内含了回滚的操作
try{
session.commit();
}finally{
session.close();
}
0.事务的边界 :Service层
1.事务的传播行为 :多个事务在嵌套使用时的处理方式
2.事物的隔离级别: select * from t_user where id = 1 for update,加行级锁