mybatis
1.三层结构
-
三层架构
界面层: 和用户打交道的, 接收用户的请求参数, 显示处理结果的。(jsp ,html ,servlet)
业务逻辑层: 接收了界面层传递的数据,计算逻辑,调用数据库,获取数据
数据访问层: 就是访问数据库, 执行对数据的查询,修改,删除等等的。三层对应的包
界面层: controller包 (servlet)
业务逻辑层: service 包(XXXService类)
数据访问层: dao包(XXXDao类)三层中类的交互
用户使用界面层–> 业务逻辑层—>数据访问层(持久层)–>数据库(mysql)三层对应的处理框架
界面层—servlet—springmvc(框架)
业务逻辑层—service类–spring(框架)
数据访问层—dao类–mybatis(框架)
2.框架
框架特点:
1. 框架一般不是全能的, 不能做所有事情
2. 框架是针对某一个领域有效。 特长在某一个方面,比如mybatis做数据库操作强,但是他不能做其它的。
3. 框架是一个软件
mybatis框架
一个框架,早期叫做ibatis, 代码在github。
mybatis是 MyBatis SQL Mapper Framework for Java (sql映射框架)
1)sql mapper :sql映射
可以把数据库表中的一行数据 映射为 一个java对象。
一行数据可以看做是一个java对象。操作这个对象,就相当于操作表中的数据
2) Data Access Objects(DAOs) : 数据访问 , 对数据库执行增删改查。
mybatis提供了哪些功能:
- 提供了创建Connection ,Statement, ResultSet的能力 ,不用开发人员创建这些对象了
- 提供了执行sql语句的能力, 不用你执行sql
- 提供了循环sql, 把sql的结果转为java对象, List集合的能力
while (rs.next()) {
Student stu = new Student();
stu.setId(rs.getInt(“id”));
stu.setName(rs.getString(“name”));
stu.setAge(rs.getInt(“age”));
//从数据库取出数据转为 Student 对象,封装到 List 集合
stuList.add(stu);
}
4.提供了关闭资源的能力,不用你关闭Connection, Statement, ResultSet
开发人员做的是: 提供sql语句
最后是: 开发人员提供sql语句–mybatis处理sql—开发人员得到List集合或java对象(表中的数据)
总结:
mybatis是一个sql映射框架,提供的数据库的操作能力。增强的JDBC,
使用mybatis让开发人员集中精神写sql就可以了,不必关心Connection,Statement,ResultSet
的创建,销毁,sql的执行。
3.封装MyBatis输出结果
#和 $区别
1. #使用 ?在sql语句中做站位的, 使用PreparedStatement执行sql,效率高
2. #能够避免sql注入,更安全。
3. $不使用占位符,是字符串连接方式,使用Statement对象执行sql,效率低
4. $有sql注入的风险,缺乏安全性。
5. $:可以替换表名或者列名
列名属性名不同的两种解决方案
1.resultMap:
自定义列名和java对象的属性名对应关系
<!--使用resultMap
1)先定义resultMap
2)在select标签,使用resultMap来引用定义的-->
<!--定义resultMap
id:自定义名称,表示你定义的这个resultMap
type:java类型的全限名称-->
<resultMap id="studentMap" type="com.powernode.domian.MyStudent">
<!--定义列名和java属性的关系-->
<!--主键列,使用id标签-->
<!--column:数据库列名
property:java类型的属性名-->
<id column="id" property="stu_id"/>
<!--非主键列,使用result-->
<result column="name" property="stu_name"/>
<result column="email" property="stu_email"/>
<result column="age" property="stu_age"/>
</resultMap>
<select id="selectAllStudent" resultMap="studentMap">
select * from student
</select>
2.使用列别名和< resultType >:
resultType:表示sql语句的执行结果,转为的java对象的类型(全限定名称);
sql语句的列名重命名
id 重命名为:stu_id
select id as stu_id from student
<!--列名和属性名不一样:第二种方式
resultType的默认原则是 同名的列值赋值给同名的属性,使用列别名(java对象的属性名)-->
<select id="selectDiffColProperty" resultType="com.powernode.domian.MyStudent">
select id as stu_id, name as stu_name, email as stu_email, age as stu_age from student
</select>
like查询的两种方案
模糊查询 like “%2%”
第一种模糊查询,在java代码中来指定 like内容
List students = dao.selectLikeOne ("%郭%");
@Test
public void testselectListOne(){
SqlSession sqlSession = MyBatisUtils.getSqlSession();
StudentDao dao = sqlSession.getMapper(StudentDao.class);
//准备like的内容
String name = "%郭%";
List<Student> students = dao.selectLikeOne(name);
for (Student stu:students){
System.out.println("学生="+stu);
}
sqlSession.close();
}
第二种 在mapper文件中拼接 like的内容
<!--第一种like-->
<select id="selectLikeOne" resultType="com.powernode.domian.Student">
select * from student where name like #{name}
</select>
<!--第二种:在mapper文件中拼接like内容-->
<select id="selectLikeTwo" resultType="com.powernode.domian.Student">
select * from student where name like "%" #{name} "%"
</select>
@Test
public void testselectListTwo(){
SqlSession sqlSession = MyBatisUtils.getSqlSession();
StudentDao dao = sqlSession.getMapper(StudentDao.class);
//准备like的内容
String name = "郭";
List<Student> students = dao.selectLikeTwo(name);
for (Student stu:students){
System.out.println("学生="+stu);
}
sqlSession.close();
}
4.Mybatis框架动态SQL
动态sql:sql的内容是变化的,可以根据条件获取到不同的sql语句。主要是where部分发生变化。
动态sql的实现,使用的是mybatis提供的标签,< if >,< where > ,< foreach>
动态SQL之< if>
1)< if>是判断条件的,
语法:
< if test="判断java对象的属性值">
部分sql语句
< /if>
在mapper标签中设置if标签
<!--if
<if:test="使用参数java对象的属性值作为判断条件,语法,属性=xxx值">
-->
<select id="selectStudentIf" resultType="com.powernode.domian.Student">
select id,name,email,age from student
where 1=1
<if test="name!=null and name!=''">
name = #{name}
</if>
<if test="age>0">
or age > #{age}
</if>
</select>
存在的缺陷:当有些条件不满足的时候,造成sql语句语法错误。
动态SQL之< where>
2)< where> 用来包含 多个< if>的, 当多个if有一个成立的, < where>会自动增加一个where关键字,并去掉 if中多余的 and ,or等。
弥补了< if>标签存在的sql语法问题
<!--where:<where> <if> <if>...</where>-->
<select id="selectStudentWhere" resultType="com.powernode.domian.Student">
select * from student
<where>
<if test="name!=null and name!=''">
name = #{name}
</if>
<if test="age>0">
or age > #{age}
</if>
</where>
</select>
动态SQL之< foreach>
< foreach> 循环java中的数组,list集合的。 主要用在sql的in语句中。
例如:查询学生id是 1001,1002,1003的三个学生
select * from student where id in (1001,1002,1003)
public List<Student> selectFor(List<Integer> idlist)
List<Integer> list = new ...
list.add(1001);
list.add(1002);
list.add(1003);
dao.selectFor(list)
< foreach>标签的使用
< foreach collection="" item="" open="" close="" separator="">
#{xxx}
< /foreach>
collection:表示接口中的方法参数的类型, 如果是数组使用array , 如果是list集合使用list
item:自定义的,表示数组和集合成员的变量
open:循环开始是的字符
close:循环结束时的字符
separator:集合成员之间的分隔符
循环的方法1
<!--foreach使用1 List<Integer>-->
<select id="selectForeachOne" resultType="com.powernode.domian.Student">
select * from student where id in
<foreach collection="list" item="myid" open="(" close=")" separator=",">
#{myid}
</foreach>
</select>
循环的方法2,循坏的对象
接口
//foreach 用法1 list集合
List<Student> selectForeachOne(List<Integer> idlist);
//foreach 用法2 循环对象
List<Student> selectForeachTwo(List<Student> stulist);
配置文件
<select id="selectForeachTwo" resultType="com.powernode.domian.Student">
select * from student where id in
<foreach collection="list" item="stu" open="(" close=")" separator=",">
#{stu.id}
</foreach>
</select>
动态SQL之代码片段
4)sql代码片段, 就是复用一些语法
步骤
1.先定义 < sql id=“自定义名称唯一”> sql语句, 表名,字段等 < /sql>
2.再使用, < include refid=“id的值” />