第1章 框架概述
-
1.1软件开发常用结构
-
1.1.1三层架构
三层架构包括:界面层(User Interface Iayer)、业务逻辑层(Business Logic Iayer)、数据访问层(Data access Iayer)
三层对应的包
界面层:controller包(servlet)
业务逻辑层:service包(XXXService类)
数据访问层:dao包(XXXDao类)三层中类的交互
用户使用界面层->业务逻辑层->数据访问层(持久层)->数据库(MySQL)三层对应的框架
界面层——servlet——springmvc(框架)
业务逻辑层——service类——spring(框架)
数据访问层——dao类——mybatis(框架)
-
-
1.2框架是什么
-
1.2.1框架定义
-
-
1.3JDBC编程
-
1.3.2使用JDBC 的缺陷
-
-
1.4MyBatis框架概述
MyBatis SQL Mapper Framework for Java
1)sql mapper:sql映射
可以把数据库表中的一行数据映射为一个Java对象。操作这个对象就相当于操作表中的数据。
2)Data Access Objects(DAOs):数据访问,对数据库执行增删改查。mybatis提供能哪些功能:
1)提供能Connection、Statement、ResultSet的能力,不用开发人员创建这些对象。
2)提供执行sql语句的能力,不用开发人员执行sql。
3)提供了循环sql,把sql的结果转为Java对象、List集合的能力。
4)提供了关闭资源的能力,不用你关闭Connection、Statement、ResultSet。
即开发人员提供sql语句——mybatis处理sql——开发人员得到List集合或Java对象(表中的数据)
总结:mybatis是一个sql映射框架,提供数据库的操作能力。增强的JDBC,使用mybatis让开发人员集中精神写sql就可以了,不必关心Connection、Statement、ResultSet的创建、销毁、sql的执行。
第2章 MyBatis框架快速入门
- 2.1入门案例
2.1.1使用MyBatis准备
2.1.2搭建MyBatis开发环境
1)创建mysql数据库和表
//创建并进入数据库ssm
create database ssm;
use ssm;
//创建student表
create table student (
id int(11) primary key not null,
name varchar(255) default null,
email varchar(255) default null,
age int(11)default null
)charset=utf8;
2)创建maven工程
3)加入maven坐标、MySQL驱动坐标和maven插件
<!--mybatis依赖-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.1</version>
</dependency>
<!--mysql驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.23</version>
</dependency>
<!--加入maven插件,编译时扫描文件用到-->
<build>
<resources>
<resource>
<directory>src/main/java</directory><!--所在的目录-->
<includes><!--包括目录下的.properties、xml文件都会扫描到-->
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
</build>
4)创建实体类,如Student——保存表中的一行数据
5)创建持久层Dao接口,定义操作数据库的方法
要查询数据需要返回一个集合,List是Java中比较常用的集合类。这个集合里面应该放Student对象,因为表中的每一行数据都可以看成一个Student对象。
6)创建MyBatis使用的配置文件,叫sql映射文件
写sql语句的,一般一个表一个sql映射文件.xml
文件位置:接口所在的目录中
文件名称:与接口保持一致
//基于xml映射语句的示例
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.mybatis.example.BlogMapper">
<!--查询操作-->
<select id="selectBlog" resultType="Blog">
select * from Blog where id = #{id}
</select>
<!--插入操作-->
<insert id="insertStudents">
insert into student values (#{id},#{name},#{email},#{age})
</insert>
</mapper>
<!--
sql映射文件:写sql语句的,mybatis会执行这些sql
1.指定约束文件:<!DOCTYPE mapper/>,
mybatis-3-mapper.dtd是约束文件的名称,扩展名是dtd。
作用:检查在当前文件中出现的标签和属性必须符合mybatis的要求。
2.当前文件的跟标签:<mapper namespace></mapper>
namespace叫命名空间,唯一值的,可以自定义的字符串。
要求:使用dao接口的全限定名称。(包括包名、类名)
3.在当前文件中,可以使用特定的标签,表示数据库的特定操作
<select>:表示执行查询,放的是select语句
<update>:表示执行修改,放的是update语句
<insert>:表示执行添加,放的是insert语句
<delete>:表示执行删除,放的是delete语句
select表示查询操作
id:表示要执行的sql语法的唯一标识,
mybatis会使用这个id的值来找到要执行的sql语句
可以自定义,但是要求使用接口中的方法名称
resultType:表示结果类型
是sql语句执行后得到记录集,
遍历记录集得到Java对象的类型
值写的是类型的权限的名称
-->
7)创建mybatis的主配置文件:一个项目就一个主配置文件
主配置文件提供了数据库的连接信息和sql映射文件的位置信息
<?xml version="1.0" encoding="UTF-8" ?>
<!--mybatis的主配置文件:主要定义了数据库的配置信息和sql映射文件的位置-->
<!--指定约束文件-->
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<!--根标签-->
<configuration>
<!--环境配置:数据库的连接信息
default:必须和某个environments的id值一致,
告诉mybatis使用哪个数据库的连接信息。即访问哪个数据库
即选择不同环境使用的数据库
-->
<environments default="DbMybatis">
<!--environment:一个数据库信息的配置
id:一个唯一值,自定义,表示环境的名称
-->
<!--
开发环境
-->
<environment id="DbMybatis">
<!--transactionManager:mybatis的事务类型
type:
1)JDBC:表示使用jdbc中的Connection对象的commit,rollback做事务处理:
2)MANAGED:表示把mybatis的事务处理委托给其他容器(可以是服务器软件、框架(spring))
-->
<transactionManager type="JDBC"/>
<!--dataSource:表示数据源,连接数据库的
type表示数据源的类型
1)POOLED表示使用连接池,mybatis会创建PooledDataSource类
2)UPOOLED表示不使用连接池,每次执行sql语句,先创建连接,执行sql,再关闭连接。
mybatis会创建一个UnPooledDataSource,管理Connection对象的使用
3)JNDI:java命名和目录服务(widows的注册表)
-->
<dataSource type="POOLED">
<!--
driver、url、username、password是固定的不能自定义
-->
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/ssm"/>
<property name="username" value="root"/>
<property name="password" value="abc1234."/>
</dataSource>
</environment>
<!--
测试环境
-->
<environment id="">
<transactionManager type=""/>
<dataSource type="">
<property name="driver" value=""/>
<property name="url" value=""/>
<property name="username" value=""/>
<property name="password" value=""/>
</dataSource>
</environment>
<!--
准生产环境
-->
<environment id="">
<transactionManager type=""/>
<dataSource type="">
<property name="driver" value=""/>
<property name="url" value=""/>
<property name="username" value=""/>
<property name="password" value=""/>
</dataSource>
</environment>
<!--
生产环境
-->
<environment id="">
<transactionManager type=""/>
<dataSource type="">
<property name="driver" value=""/>
<property name="url" value=""/>
<property name="username" value=""/>
<property name="password" value=""/>
</dataSource>
</environment>
</environments>
<!--sql mapper(sql映射文件)的位置-->
<mappers>
<!--一个mapper标签指定一个sql映射文件的位置
从类路径开始的路径信息。 target/class(class后面开始的就是类路径)
-->
//第一种方式:指定多个mapper文件
<mapper resource="com\bjpowernode\dao\StudentDao.xml"/>
<mapper resource="com\bjpowernode\dao\OrderDao.xml"/>
//第二种方式:使用包名,name=mapper文件所在的包名。(这个包所有xml文件一次性加载给mybatis)
<!--mapper文件名称需和接口名称一样,区分大小写
mapper文件和dao接口在同一目录-->
<package name="com.bjpowernode.dao"/>
</mappers>
</configuration>
8)创建使用mybatis类(通过mybatis访问数据库)
①定义mybatis主配置文件名称
String config = "mybatis.xml";
②读取主配置文件
InputStream in=Resources.getResourceAsStream(config);
③创建SqlSessionFactoryBuilder对象
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
④创建SqlSessionFactory对象
SqlSessionFactory factory=builder.build(in);
⑤【重要】获取SqlSession对象,从SqlSessionFactory中获取SqlSession对象
SqlSession sqlSession=factory.openSession();
⑥【重要】指定要执行的sql语句的表示。sql映射文件中的namesapce+“.”+标签的id值
String sqlId="com\bjpowernode\dao\StudentDao.java"+"."+"selectStudents";//查询操作
String sqlId="com\\bjpowernode\\dao\\StudentDao.java.insertStudents";//插入操作
⑦执行sql语句,通过sqlId找到语句
List<Student> studentList = sqlSession.selectList(sqlId);//查询操作
//插入操作
Student student = new Student();
student.setId(1004);
student.setName("顾六");
student.setEmail("xinlang@192.com");
student.setAge(36);
int nums = sqlSession.insert(sqlId,student);
MyBatis默认不是自动提交事务,所以在执行sql后,需要手工提交事务
sqlSession.commit();
或者给openSession()方法传true值
⑧输出结果
studentList.forEach(stu -> System.out.println(stu) );
lambda(拉姆表达式)语法
包含三部分:
1、一个括号内用逗号分隔的形式参数,参数是函数式接口里面方法的参数
2、一个箭头符号:->
3、方法体,可以是表达式和代码块。
(parameters) -> expression 或者 (parameters) -> { statements; }
for (Student stu:studentList){
System.out.println("查询的学="+stu);
}
foreach也叫增强for循环,是for循环的一个特殊简化版。
语法:
for(元素类型 元素名称:遍历数组(集合)(或者能进行迭代的)){
语句
}
⑨关闭资源
sqlSession.close();
9)配置日志功能
在主配置文件的根标签下添加settings标签
<!--settings:控制mybatis全局行为的-->
<settings>
<!--设置mybatis输出日志-->
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
2.2MyBatis对象分析
1)Resources:mybatis中的一个类,负责读取主配置文件。
InputStream in= Resources.getResourceAsStream(配置文件地址);
2)SqlSessionFactoryBuilder:创建SqlSessionFactory对象。
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory=builder.build(in);
3)SqlSessionFactory:重量级对象,程序创建一个对象耗时比较长,使用资源比较多。在整个项目中有一个就够了。
SqlSessionFactory->接口,接口实现类->DefaultSqlSessionFactory
SqlSessionFactory作用:获取SqlSession 对象。
SqlSession sqlSession=factory.openSession();
openSession()方法说明:
①openSession():无参,获取的是非自动提交事务的SqlSession对象。
②openSession(boolean):
openSession(true)获取自动提交事务的SqlSession对象
openSession(false)获取非自动提交事务的SqlSession对象
4)SqlSession:是接口,定义了操作数据的方法。例如selectOne()、selectList()、insert()、update()、delete()、commit()......
SqlSession的实现类DefaultSqlSession
使用要求:SqlSession对象不是线程安全的,需要在方法内部使用,在执行sql语句之前要使用openSession()获取SqlSession对象。在执行完sql语句后,需要关闭它,执行SqlSession.close()。这样能保证它的使用是线程安全的。-
2.3MyBatis使用传统Dao开发
- 使用工具类
//工具类
public class MyBatisUtils {
/*因为静态块不能用,故需要在静态块外用变量factory保存SqlSessionFactory对象*/
private static SqlSessionFactory factory=null;
static {
//1.定义mybatis主配置文件名称,从类路径的根开始(target/class)
String config = "mybatis.xml";
InputStream in= null;
try {
//2.读取主配置文件
in = Resources.getResourceAsStream(config);
//3+4.使用SqlSessionFactoryBuilder创建SqlSessionFactory对象
factory = new SqlSessionFactoryBuilder().build(in);
} catch (IOException e) {
e.printStackTrace();
}
}
public static SqlSession getSqlSession(){
//5.获取SqlSession对象,从SqlSessionFactory中获取SqlSession对象
SqlSession sqlSession=null;
if (factory != null) {
sqlSession=factory.openSession();
}
return sqlSession;
}
}
//测试类
@Test
public void testMyBatisUtils(){
//5.从工具类获取SqlSession对象
SqlSession sqlSession= MyBatisUtils.getSqlSession();
//6.【重要】指定要执行的sql语句的表示。sql映射文件中的namesapce+“.”+标签的id值
String sqlId="com\\bjpowernode\\dao\\StudentDao.java.insertStudents";
//7.执行sql语句,通过sqlId找到语句
Student student = new Student();
student.setId(1005);
student.setName("唐七");
student.setEmail("Google@163.com");
student.setAge(99);
int nums = sqlSession.insert(sqlId,student);
//mybatis默认不是自动提交事务,所以在执行sql后,需要手工提交事务
sqlSession.commit();
//8.输出结果
System.out.println("成功插入" + nums + "条数据!");
//9.关闭资源
sqlSession.close();
}
- 使用传统Dao
//主配置文件—mybatis
<?xml version="1.0" encoding="UTF-8" ?>
<!--mybatis的主配置文件:主要定义了数据库的配置信息和sql映射文件的位置-->
<!--指定约束文件-->
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<!--根标签-->
<configuration>
<!--settings:控制mybatis全局行为的-->
<settings>
<!--设置mybatis输出日志-->
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
<!--环境配置:数据库的连接信息
default:必须和某个environments的id值一致,
告诉mybatis使用哪个数据库的连接信息。即访问哪个数据库
-->
<environments default="DbMybatis">
<!--environment:一个数据库信息的配置
id:一个唯一值,自定义,表示环境的名称
-->
<environment id="DbMybatis">
<!--transactionManager:mybatis的事务类型
type:JDBC(表示使用jdbc中的Connection对象的commit,rollback做事务处理)
-->
<transactionManager type="JDBC"/>
<!--dataSource:表示数据源,连接数据库的
type表示数据源的类型,POOLED表示使用连接池
-->
<dataSource type="POOLED">
<!--
driver、url、username、password是固定的不能自定义
-->
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/ssm"/>
<property name="username" value="root"/>
<property name="password" value="abc1234."/>
</dataSource>
</environment>
</environments>
<!--sql mapper(sql映射文件)的位置-->
<mappers>
<!--一个mapper标签指定一个sql映射文件的位置
从类路径开始的路径信息。 target/class(class后面开始的就是类路径)
-->
<mapper resource="com\bjpowernode\dao\StudentDao.xml"/>
</mappers>
</configuration>
//持久层Dao——sql映射文件StudentDao
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com\bjpowernode\dao\StudentDao.xml">
<!--查询操作-->
<select id="selectStudents" resultType="com.bjpowernode.domain.Student">
select id,name,email,age from student order by id;
</select>
</mapper>
//domain实体类——Student
package com.bjpowernode.domain;
public class Student {
private Integer id;
private String name;
private String email;
private Integer age;
@Override
public String toString() {
return "Student{" +
"id=" + id +
", name='" + name + '\'' +
", email='" + email + '\'' +
", age=" + age +
'}';
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
//持久层Dao——接口StudentDao
package com.bjpowernode.dao;
import com.bjpowernode.domain.Student;
import java.util.List;
public interface StudentDao {
List<Student> selectStudents();
}
//工具类utils—MyBatisUtils
package com.bjpowernode.utils;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.IOException;
import java.io.InputStream;
public class MyBatisUtils {
/*因为静态块不能用,故需要在静态块外用变量factory保存SqlSessionFactory对象*/
private static SqlSessionFactory factory=null;
static {
//1.定义mybatis主配置文件名称,从类路径的根开始(target/class)
String config = "mybatis.xml";
InputStream in= null;
try {
//2.读取主配置文件
in = Resources.getResourceAsStream(config);
//3+4.使用SqlSessionFactoryBuilder创建SqlSessionFactory对象
factory = new SqlSessionFactoryBuilder().build(in);
} catch (IOException e) {
e.printStackTrace();
}
}
public static SqlSession getSqlSession(){
//5.获取SqlSession对象,从SqlSessionFactory中获取SqlSession对象
SqlSession sqlSession=null;
if (factory != null) {
sqlSession=factory.openSession();
}
return sqlSession;
}
}
//持久层Dao——实现类StudentDaoImpl
package com.bjpowernode.dao.Impl;
import com.bjpowernode.dao.StudentDao;
import com.bjpowernode.domain.Student;
import com.bjpowernode.utils.MyBatisUtils;
import org.apache.ibatis.session.SqlSession;
import java.util.List;
public class StudentDaoImpl implements StudentDao {
@Override
public List<Student> selectStudents() {
//获取SqlSession对象
SqlSession sqlSession=MyBatisUtils.getSqlSession();
String sqlId="com\\bjpowernode\\dao\\StudentDao.xml.selectStudents";
//执行sql语句,使用SqlSession类的方法
List<Student>students=sqlSession.selectList(sqlId);
//关闭资源
sqlSession.close();
return students;
}
}
//测试类test—MyBatis
package com.bjpowernode;
import com.bjpowernode.dao.Impl.StudentDaoImpl;
import com.bjpowernode.dao.StudentDao;
import com.bjpowernode.domain.Student;
import org.junit.Test;
import java.util.List;
public class TestMyBatis {
@Test
public void testSelectStudent(){
StudentDao dao=new StudentDaoImpl();
List<Student>studentList=dao.selectStudents();
for (Student stu:studentList
) {
System.out.println(stu);
}
}
}
第3章 MyBatis框架Dao代理(核心)
List<Student> studentList = dao.selectStudent();调用
1.dao对象,类型是StudentDao,全限定名称是:com\bjpowernode\dao\StudentDao.java全限定名称和namespace是一样的。
2.方法名称,selectStudents,整个方法就是mapper文件中的id值,selectStudents
3.通过dao中方法的返回值也可以确定MyBatis要调用的sqlSession的方法
如果返回值是List,调用的是SqlSession.selectList()方法。
如果返回值是int,或者是非Lsit的,看mapper文件中的标签是<insert>、<update>就会调用SqlSession的insert、update等方法
mybatis的动态代理:mybatis根据dao方法调用,获取执行sql语句的信息。
mybatis根据你的dao接口,创建出一个dao接口的实现类,并创建这个类的对象。完成SqlSession调用方法,访问数据库。
@Test
public void testSelectStudent(){
//使用getSqlSession方法调用MyBatisUtils工具类获取SqlSession对象
SqlSession sqlSession = MyBatisUtils.getSqlSession();
/*
使用mybatis的动态代理机制,使用SqlSession.getMapper(dao接口)
getMapper能获取dao接口对应的实现类对象
*/
StudentDao dao = sqlSession.getMapper(StudentDao.class);
//调用dao的方法,执行数据库的操作
List<Student> students=dao.selectStudents();
for(Student stu:students){
System.out.println("学生="+stu);
}
}
3.1原理
1.动态代理:使用SqlSession.getMapper(dao接口.class)获取这个dao接口的对象。
2.传入参数:从Java代码中把数据传入到mapper文件的sql语句中。
3.2深入理解参数
3.21parameterType:
写在mapper文件中的一个属性,表示dao接口中方法的参数的数据类型。
例如StudentDao接口
public Student selectStudentById(Integer id)
属性parameterType它的值是java的数据类型全限定名称或者是mybatis定义的别名
例如: parameterType="java.lang.Integer"或 parameterType="int"
<select id="selectStudentById" parameterType="java.lang.Integer" resultType="com.bjpowernode.domain.Student">
select id,name,email,age from student where id=#{id};
</select>
不是必需的,因为mybatis通过反射机制能够找到接口参数的数据类型。
3.22传入一个简单参数:
简单类型:mybatis把java的基本数据类型和string都叫简单类型
在mapper文件获取简单类型的一个参数的值,使用语法:#{任意字符串}
//接口
public Student selectStudentById(Integer id)
//使用占位符
select id,name,email,age from student where id=#{id};
//传参
Student student = dao.selectStudentById(1005);
使用#{}后,mybatis执行sql是使用的jdbc中的PreparedStatement对象
由mybatis执行下面的代码
1.mybatis创建Connection、PreparedStatement对象
String sql="select id,name,email,age from student where id=?";
PreparedStatement pst=conn,preparedStatement(sql);
pst.setInt(1,1001);
2.执行slq封装为resultType="com.bjpowernod.domain.Student"这个对象
ResultSet rs=ps.executeQuery();
Student student = new Student();
while(rs.next()){
//从数据库取表的一行数据,存到一个Java对象属性中
student.setId(rs.getInt("id"));
student.setName(rs.getString("name"));
student.setEmail(rs.getString("email"));
student.setAge(rs.getInt("age"));
}
return student;//赋给了 dao方法调用的返回值
3.23多个参数-使用@Param(必须掌握):
接口:
public List<Student> selectMulitParam(String name,Integer age)
在参数名前面使用:
@Param("参数名") 参数类型 参数
位置:mapper文件中
<select>
select * from student where name=#{myname} or age=#{myage}
</select>
3.24多个参数-使用对象(必须掌握):
完整语法:#{实体类中属性名,javaType=类型名称,jdbcType=数据库类型}
javaType:指Java中属性数据类型
jdbcType:指数据库中的数据类型
例如:#{paramName,javaType=java.lang.String,jd
简化语法:#{实体类中属性名}
javaType、jdbcType的值mybatis能通过反射获取,不用提供
3.25多个参数-按位置(了解):
mybatis 3.4之前,使用#{0},#{1}
mybatis 3.4之后,使用#{arg0},#{arg1}
3.26多个参数-使用Map(了解):
3.27#和$:
'#'占位符:告诉mybatis使用实际的参数值替代。#{...}代替sql语句的“?”,这样更安全、迅速,能避免sql注入。
$ 字符串替换:告诉mybatis使用这个符号包含的“字符串”替换所在位置。主要用在替换表面、列名,不同列排序等操作。
# 与 $的区别:
- “#”使用?在sql语句中做占位,表示列的值。使用PreparedStatement执行sql,效率高、能避免sql注入更安全。
2."$"不适用占位符,是字符串连接方式,使用Statement对象执行sql,效率低、有sql注入的风险缺乏安全性。常用于替换表名或列名。
//#接口
public Student selectStudentById(Integer id);
//#映射文件
select id,name,email,age from student where id=#{id}
//#测试类
Student student = dao.selectStudentById(1005);
//#测试结果
select id,name,email,age from student where id=?
//$接口
public Student selectStudentById(@Param("id") Integer id);
//$映射文件
select id,name,email,age from student where id=${id}
//$测试类
Student student = dao.selectStudentById(1005);
//$测试结果
select id,name,email,age from student where id=1005
相当于
Strig sql="select id,name,email,age from student where id="+"1005 ";
3.3封装MyBatis输出结果(理解)
mybatis的输出结果:mybatis执行了sql语句,得到java对象。
resultType和resultMap二选一,不能同时用
3.3.1 resultType
resultType结果类型:指sql语句执行完毕后,数据转为指定的java对象类型。(java类型是任意的)
resultType结果类型的值:
1.类型的全限定名称。
2.类型的别名
1)定义自定义类型的别名:
第一种方式:
在主配置文件(mybatis.xml)中的根标签(<configuration>)下使用<typeAliases>标签
<typeAliases>
<!--
第一种方式:
可以指定一个类型一个自定义别名
type:自定义类的全限定名称
alias:别名
-->
<typeAlias type="com.bjpowernode.domain.Student" alias="stu"/>
</typeAliases>
第二种方式:
在主配置文件(mybatis.xml)中的根标签(<configuration>)下使用<typeAliases>标签
<typeAliases>
<!--
第二种方式:
可以指定一个类型一个自定义别名
name:包名,这个包中的所有类,类名就是别名(类型不区分大小写)
-->
<package name="com.bjpowernode.domain"/>
</typeAliases>
返回Map
1)列名是map的key,列值是map的value
2)最多只能返回一行记录,多一行是错误
//接口
Map<Object,Object> selectMap(int id);
//映射文件
<select id="selectMap" resultType="java.util.Map">
select id,name,email,age from student where id=#{id}
</select>
//测试
@Test
public void testSelectMap(){
//使用getSqlSession方法调用MyBatisUtils工具类获取SqlSession对象
SqlSession sqlSession = MyBatisUtils.getSqlSession();
/*
使用mybatis的动态代理机制,使用SqlSession.getMapper(dao接口)
getMapper能获取dao接口对应的实现类对象
*/
StudentDao dao = sqlSession.getMapper(StudentDao.class);
//调用dao的方法,执行数据库的操作
Map<Object,Object> map=dao.selectMap(1005);
System.out.println("map="+map);
}
处理方式:
1.mybatis执行sql语句,然后mybatis调用类的无参数构造方法,创建对象。
2.mybatis把ResultSet指定列值赋给同名的属性。
<select id="selectMulitParam" resultType="com.bjpowernode.domain.Student">
select id,name,email,age from student
</select>
//等价于jdbc
ResultSet rs=exeouteQuery("select id,name,email,age from student");
Student student=new Student();
while(rs.next()){
student.setId(rs.getInt("id"));
student.setName(rs.getString("name"));
}
3.3.2 resultMap
结果映射,指定列名和java对象的属性对应关系。
1.自定义列值赋给哪个属性
2.当列名和属性名不一样时,一定要使用resultMap
3.3.3实体类属性名和列名不同的处理方式
1.使用列别名和<resultType>
resultType的默认原则是:同名的列值赋值给同名的属性,使用列别名(java对象的属性名)
2.使用<resultMap>
3.4模糊like
第一种模糊查询,在java代码指定like的内容
//接口
/*第一种模糊查询,在java代码指定like的内容*/
List<Student> selectLikeOne(String name);
//映射文件
<select id="selectLikeOne" resultType="com.bjpowernode.domain.Student">
select id,name,email,age from student where name like #{}
</select>
//测试类
@Test
public void testSelectLikeOne(){
SqlSession sqlSession = MyBatisUtils.getSqlSession();
StudentDao dao = sqlSession.getMapper(StudentDao.class);
//准备号like的内容
String name="%李%";
List<Student> student=dao.selectLikeOne(name);
for (Student stu:student) {
System.out.println(student);
}
sqlSession.close();
}
第二种模糊查询,在mapper文件中拼接like的内容
//接口
/*name就是列值,在mapper中拼接like “%“李”%” */
List<Student> selectLikeTwo(String name);
//映射文件
<select id="selectLikeTwo" resultType="com.bjpowernode.domain.Student">
select id,name,email,age from student where name like “%” #{} “%”
</select>
//测试类
@Test
public void testSelectLikeTwo(){
SqlSession sqlSession = MyBatisUtils.getSqlSession();
StudentDao dao = sqlSession.getMapper(StudentDao.class);
//准备号like的内容
String name="李";
//调用dao的方法,执行数据库的操作
List<Student> student=dao.selectLikeTwo(name);
for (Student stu:student) {
System.out.println(student);
}
sqlSession.close();
}
第4章 MyBatis框架动态SQL(理解)
动态sql:sql的内容是变化的,可以根据条件获取到不同的sql语句,主要是where部分发生变化。
4.1环境准备
4.2动态sql之<if>
<if>条件判断语句
语法:
<if test="判断Java对象的属性值">
部分sql语句
</if>
接口
mapper文件
测试类
注意!:当name存在age不存在时,程序正常运行;当age存在name不存在时,程序报错。因为
where or age>1
中多了or,出现语法错误。解决方法:
4.3动态sql之<where>
<where>用来包含多个<if>的,当多个if有一个成立,<where>会自动增加一个where关键字,并去掉if中多余的and、or等从而 解决<if>因条件不足而产生的语法问题
4.4动态sql之<foreach>
<foreach>循环jave中的数组,List集合的。主要用在sql的in语句中。
collection:表示接口中的方法参数的类型,如果是数组使用array,如果是list集合使用list
item:自定义的,表示数组和集合成员的变量
open:循环开始的字符
close:循环结束的字符
separator:集合成员之间的分隔符
foreach使用1,List<Integer>
//接口
List<Student> selectStudentForeachOne(List<Integer> idlist);
//mapper文件
<select id="selectStudentForeachOne" resultType="com.bjpowernode.domain.Student">
select * from student where id in
<foreach collection="list" item="myid" open="(" close=")" separator=",">
#{myid}
</foreach>
</select>
//测试类
@Test
public void testSelectStudentForeachOne(){
SqlSession sqlSession= MybatisUtils.getSqlSession();
StudentDao dao=sqlSession.getMapper(StudentDao.class);
List<Integer> list=new ArrayList<>();
list.add(1001);
list.add(1002);
list.add(1003);
List<Student> students=dao.selectStudentForeachOne(list);
for(Student stu:students){
System.out.println("foreach-one==="+stu);
}
sqlSession.close();
}
foreach使用2,List<Student>
//接口
List<Student> selectStudentForeachTwo(List<Student> stulist);
//mapper文件
<select id="selectStudentForeachTwo" resultType="com.bjpowernode.domain.Student">
select * from student where id in
<foreach collection="list" item="stu" open="(" close=")" separator=",">
#{stu.id}
</foreach>
</select>
//测试类
@Test
public void testSelectStudentForeachTwo(){
SqlSession sqlSession= MybatisUtils.getSqlSession();
StudentDao dao=sqlSession.getMapper(StudentDao.class);
List<Student> stulist=new ArrayList<>();
Student s1=new Student();
s1.setId(1005);
stulist.add(s1);
s1=new Student();
s1.setId(1006);
stulist.add(s1);
List<Student> students=dao.selectStudentForeachTwo(stulist);
for(Student stu:students){
System.out.println("foreach-two==="+stu);
}
sqlSession.close();
}
4.5动态sql之代码片段
步骤:
1.先定义
<sql id="自定义名称(唯一)">
sql语句、表名、字段等
</sql>
2.再使用
<include refid="id的值" />
第5章 MyBatis配置文件(了解)
1.数据库的属性配置文件:
把数据库连接信息放到一个单独的文件中。和mybatis主配置文件分开。目的是便于修改、保存、处理多个数据库的信息。
1)在resources目录中定义一个属性配置文件,×××.properties,例如 jdbc.properties
在属性配置文件中,定义数据格式:key-value
key:一般使用,做多级目录的
例如 jdbc.mybatis.driver , jdbc.driver , mydriver
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/ssm
jdbc.username=root
jdbc.password=abc1234.
2)在mybatis的主配置文件,使用<property>指定文件的位置,在需要使用值的地方,${key}
2.mapper文件
1)使用<mapper>指定路径
2)使用<package>指定路径
<!--第一种方式:指定多个mapper文件-->
<mapper resource="com\bjpowernode\dao\StudentDao.xml"/>
<mapper resource="com\bjpowernode\dao\OrderDao.xml"/>
<!--
第二种方式:使用包名,name=mapper文件所在的包名。
(这个包所有xml文件一次性加载给mybatis)
要求:
mapper文件名称需和接口名称一样,区分大小写
mapper文件和dao接口在同一目录
-->
<package name="com.bjpowernode.dao"/>
第6章 扩展
PageHelpe 支持多种数据库:做数据分页的
1)加入maven依赖
<!--maven坐标-->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.1.10</version>
</dependency>
2)加入plugin配置在主配置文件
<!--加入plugin配置在主配置文件
的<environments>标签之前加入-->
<plugins>
<plugin interceptor="com.github.pagehelper.PageInterceptor"/>
</plugins>
@Test
public void testSelectPageHelpe(){
SqlSession sqlSession= MybatisUtils.getSqlSession();
StudentDao dao=sqlSession.getMapper(StudentDao.class);
/*加入PageHelpe的方法,分页
* pageNum:从第几页开始
* pageSize:一页中有多少行数据
* 会通过select count(*)得到有多少数据和可以分几页
* */
PageHelper.startPage(1,3);
List<Student>students=dao.selectPageHelpe();
for(Student stu:students){
System.out.println("PageHelpe=="+stu);
}
sqlSession.close();
}