SSM三大框架知识整理(一)
MyBatis
1. 什么是MyBatis?
MyBatis 是一款优秀的持久层[数据访问层]框架,对原始的JDBC技术的封装,可以帮助我们快速的链接和访问数据库。
2. 为什么要使用MyBatis?
MyBatis支持定制化SQL、存储过程以及高级映射。MyBatis几乎避免了所有的JDBC代码和手动获取参数以及获取结果集。
3. 什么是ORM?
ORM[对象关系映射]---我们在访问数据库的时候所编写的都是Java程序,Java程序只认识Java对象,而我们所访问的数据库大多数都是关系型数据库,那么这时Java程序要想访问关系型数据库,那么就需要将Java对象转换成关系型数据,才能被数据库认识。这时我们可以认为一个Java类就是关系型数据库中的一张数据表,Java类中的成员变量是数据库表中的一个列,Java类创建的Java对象就是数据库表中的一行记录。这时将Java对象对应成为数据库表记录的过程就是对象关系映射【ORM】。
ORM的优点:当我们使用Java程序控制Java对象的时候,数据库中的数据表记录会随之变化。
4. MyBatis的工作原理?
5. MyBatis的核心对象?
sqlSessionFactory
sqlSessionFactory使用来创建sqlSession,由于sqlSessionFactory是一个接口,所以不能new,需要子类sqlSessionFactoryBuilder。同时这个对象中保存着读取到的核心配置文件【mybatis-config.xml】中的信息【1.数据源 2.SQL映射文件】。
sqlSessionFactory sqlSessionFactory = new sqlSessionFactoryBuilder().build(inputStream);
sqlSession
sqlSession对象表示的是与数据库之间的一个连接(会话)。通过该对象可以对数据库进行CRUD操作。在使用的时候必须要指定需要执行的到底是哪个Mapper文件中的SQL。
sqlSession对象提供的常用方法:
1.insert(statement, parameter):添加数据的方法
参数1【String】:需要执行的sql映射文件中的sql语句【数据访问接口+抽象方法名称】
参数2【Object】:输入参数。
2.update(statement, parameter):修改数据的方法
参数1【String】:需要执行的sql映射文件中的sql语句【数据访问接口+抽象方法名称】
参数2【Object】:输入参数。
3.selectOne(statement, parameter):查询一个数据的方法
参数1【String】:需要执行的sql映射文件中的sql语句【数据访问接口+抽象方法名称】
参数2【Object】:输入参数。
4.session.selectList(statement):查询所有数据的方法
参数1【String】:需要执行的sql映射文件中的sql语句【数据访问接口+抽象方法名称】
5.delete(statement, parameter):删除数据的方法
参数1【String】:需要执行的sql映射文件中的sql语句【数据访问接口+抽象方法名称】
参数2【Object】:输入参数。
6.getMapper(class):得到数据访问接口对象
参数1【Class】:被获取的数据访问接口的反射对象
7.commit():提交执行
8.close():关闭sqlsession
public class MyTest2 {
/**
* 测试添加
*/
@Test
public void testInsertPerson(){
SqlSession session=null;
try{
//加载mybatis配置文件
InputStream inputStream=Resources.getResourceAsStream("mybatis-config.xml");
//创建SqlSessionFactory接口对象
SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream);
//创建SqlSession接口对象【有增删该查方法】
session=sqlSessionFactory.openSession();
Person person=new Person();
person.setPername("zhangsan");
person.setPerage(23);
person.setPeraddress("西安");
int temp=session.insert("com.click369.mybatis.mapper.PersonMapper.insertPerson", person);
System.out.println("temp="+temp);
//提交执行
session.commit();
}catch(Exception e){
e.printStackTrace();
}finally{
session.close();
}
}
/**
* 测试修改
*/
@Test
public void testUpdatePerson(){
SqlSession session=null;
try{
//加载mybatis配置文件
InputStream inputStream=Resources.getResourceAsStream("mybatis-config.xml");
//创建SqlSessionFactory接口对象
SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream);
//创建SqlSession接口对象【有增删该查方法】
session=sqlSessionFactory.openSession();
Person person=new Person();
person.setPerid(1);
person.setPername("lisi");
person.setPerage(23);
person.setPeraddress("西安");
int temp=session.update("com.click369.mybatis.mapper.PersonMapper.updatePerson", person);
System.out.println("temp="+temp);
//提交执行
session.commit();
}catch(Exception e){
e.printStackTrace();
}finally{
session.close();
}
}
/**
* 测试根据id查询
*/
@Test
public void testSelectPersonById(){
SqlSession session=null;
try{
//加载mybatis配置文件
InputStream inputStream=Resources.getResourceAsStream("mybatis-config.xml");
//创建SqlSessionFactory接口对象
SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream);
//创建SqlSession接口对象【有增删该查方法】
session=sqlSessionFactory.openSession();
Person person=session.selectOne("com.click369.mybatis.mapper.PersonMapper.selectPersonById", 1);
System.out.println("person.name="+person.getPername());
//提交执行
session.commit();
}catch(Exception e){
e.printStackTrace();
}finally{
session.close();
}
}
/**
* 测试查询所有
*/
@Test
public void testSelectPerson(){
SqlSession session=null;
try{
//加载mybatis配置文件
InputStream inputStream=Resources.getResourceAsStream("mybatis-config.xml");
//创建SqlSessionFactory接口对象
SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream);
//创建SqlSession接口对象【有增删该查方法】
session=sqlSessionFactory.openSession();
List<Person> personList=session.selectList("com.click369.mybatis.mapper.PersonMapper.selectPerson");
System.out.println("personList.size="+personList.size());
//提交执行
session.commit();
}catch(Exception e){
e.printStackTrace();
}finally{
session.close();
}
}
/**
* 测试根据id删除
*/
@Test
public void testDeletePersonById(){
SqlSession session=null;
try{
//加载mybatis配置文件
InputStream inputStream=Resources.getResourceAsStream("mybatis-config.xml");
//创建SqlSessionFactory接口对象
SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream);
//创建SqlSession接口对象【有增删该查方法】
session=sqlSessionFactory.openSession();
int temp=session.delete("com.click369.mybatis.mapper.PersonMapper.deletePersonById", 1);
System.out.println("temp="+temp);
//提交执行
session.commit();
}catch(Exception e){
e.printStackTrace();
}finally{
session.close();
}
}
}
6. MyBatis相关的配置文件
MyBatis核心配置文件
通常情况下核心配置文件的文件名是mybatis-config.xml,也可以自己起名字。
文件存放位置:
1.普通的Eclipse创建的java工程,一般都保存在src目录下。
2.普通的Eclipse创建的javaWeb工程,一般都保存在src目录下,也可以保存在WEB-INF目录下
3.普通的Eclipse创建的Maven的java工程,一般都保存在src/main/resources目录下。
4.普通的Eclipse创建的Maven的javaWeb工程,一般都保存在src/main/resources目录下,也可以保存在WEB-INF目录下。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- 配置引入数据库链接字符串的资源文件 -->
<properties resource="myjdbc.properties"></properties>
<!-- 配置mybatis默认的连接数据库的环境 -->
<environments default="development">
<environment id="development">
<!-- 配置事物管理器 -->
<transactionManager type="JDBC"></transactionManager>
<!-- 配置数据源 -->
<dataSource type="POOLED">
<property name="driver" value="${mydriver}"/>
<property name="url" value="${myurl}"/>
<property name="username" value="${myusername}"/>
<property name="password" value="${mypassword}"/>
</dataSource>
</environment>
</environments>
<!-- 配置MyBatis数据访问接口的SQL映射文件路径 -->
<mappers>
<!-- 如果SQL映射文件在数据访问接口包中 -->
<!-- <package name="com/click369/mybatis/mapper/PersonMapper.xml"/> -->
<!-- 如果SQL映射文件在src/main/resources中 -->
<mapper resource="PersonMapper.xml"/>
</mappers>
</configuration>
核心配置文件中元素:
1.<configuration>根元素
2.<properties>元素-----配置引入其他的资源文件【.properties】,通过提供的resource属性引入
例如:资源文件【.properties】与本配置在同一个文件夹中【resource=”xxxx.properties”】
资源文件【.properties】与本配置不在同一个文件夹中 【resource=”xxxx/xxxx.properties”】
<properties resource="dbconfig.properties"></properties>
<properties resource="config/dbconfig.properties"></properties>
3.<environments>元素-----配置mybatis默认的连接数据库的环境
default属性:默认值是development
4.<environment>元素-----配置具体的某一个数据库环境,它是<environments>元素的子元素
id属性:默认值是development
5.<transactionManager>元素-----配置默认的事务管理器
type属性:配置事物管理器类型
JDBC – 这个配置就是直接使用了 JDBC 的提交和回滚设置,它依赖于从数据源得到的连接来管理事务作用域。
MANAGED – 这个配置几乎没做什么。它从来不提交或回滚一个连接,而是让容器来管理事务的整个生命周期(比如 JEE 应用服务器的上下文)。 默认情况下它会关闭连接,然而一些容器并不希望这样,因此需要将 closeConnection 属性设置为 false 来阻止它默认的关闭行为。
6.<dataSource>元素-----配置具体数据库链接的元素,是<environment>元素的子元素
type属性:数据源类型[配置是否使用数据连接池机制管理数据库链接]
UNPOOLED– 这个数据源的实现只是每次被请求时打开和关闭连接。虽然一点慢,它对在及时可用连接方面没有性能要求的简单应用程序是一个很好的选择。 不同的数据库在这方面表现也是不一样的,所以对某些数据库来说使用连接池并不重要,这个配置也是理想的。
POOLED– 这种数据源的实现利用“池”的概念将 JDBC 连接对象组织起来,避免了创建新的连接实例时所必需的初始化和认证时间。 这是一种使得并发 Web 应用快速响应请求的流行处理方式。
JNDI– 这个数据源的实现是为了能在如 EJB 或应用服务器这类容器中使用,容器可以集中或在外部配置数据源,然后放置一个 JNDI 上下文的引用。
7.<property>元素-----配置数据源
name属性:数据源属性名称
value属性:数据源属性名称对应的取值
8.<mappers>元素-----配置Mapper文件的路径
<!-- 如果SQL映射文件在数据访问接口包中 -->
<mapper resource="com/click369/mybatis/mapper/PersonMapper.xml"/>
<!-- 如果SQL映射文件在src/main/resources中 -->
<mapper resource="PersonMapper.xml"/>
Sql映射文件【Mapper文件】
Sql映射文件,这个文件是用来配置MyBatis执行数据库操作时所需要的sql语言。
Sql映射文件的名称不是随便给的,与数据访问接口的名称相同,以“.xml”结尾。有多少个数据访问接口,那么到时候就要创建多少个Sql映射文件。
Sql映射文件的位置,一般都是放在与数据访问接口相同的包中。需要注意的是在MyBatis核心配置文件中配置Sql映射文件的访问路径是要注意路径的指出。
<mapper resource="com/click369/mybatis/mapper/PersonMapper.xml"/>
<package name="com.click369.mapper"/> 表示“com.click369.mapper”包中的所有映射文件全部被加载。
<?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.click369.mybatis.mapper.PersonMapper">
<!-- 配置添加数据的sql语句 -->
<insert id="insertPerson" parameterType="com.click369.mybatis.javabean.Person">
insert into t_person values(null,#{pername},#{perage},#{peraddress})
</insert>
<!-- 配置修改数据的sql语句 -->
<update id="updatePerson" parameterType="com.click369.mybatis.javabean.Person">
update t_person set per_name=#{pername},
per_age=#{perage},
per_address=#{peraddress}
where per_id=#{perid}
</update>
<!-- 配置查询的返回值resultMap -->
<resultMap type="com.click369.mybatis.javabean.Person" id="personMap">
<id column="per_id" property="perid"/>
<result column="per_name" property="pername"/>
<result column="per_age" property="perage"/>
<result column="per_address" property="peraddress"/>
</resultMap>
<!-- 配置根据id查询数据的sql语句 -->
<select id="selectPersonById" parameterType="int" resultMap="personMap">
select * from t_person where per_id=#{perid}
</select>
<!-- 配置查询所有数据的sql语句 -->
<select id="selectPerson" resultMap="personMap">
select * from t_person
</select>
<!-- 配置删除数据的sql语句 -->
<delete id="deletePersonById" parameterType="int">
delete from t_person where per_id=#{perid}
</delete>
</mapper>
Sql映射文件中的元素:
1.<mapper>根元素
namespace属性:配置数据访问接口的包名+接口名
2.<insert>元素-----配置添加的sql语句
id属性:配置数据访问接口中的用来添加数据的方法名称。
3.<update>元素-----配置修改的sql语句
id属性:配置数据访问接口中的用来修改数据的方法名称。
4.<delete>元素-----配置删除的sql语句
id属性:配置数据访问接口中的用来修改数据的方法名称。
5.<select>元素-----配置查询的sql语句
id属性:配置数据访问接口中的用来修改数据的方法名称。
parameterType属性:配置添加参数的类型
resultMap属性:配置查询的结果类型。【数据库表中的列名称与实体类中的成员变量的名称不同】
resultType属性:配置查询的结果类型。【数据库表中的列名称与实体类中的成员变量的名称相同】
6.<resultMap>元素-----配置查询的结果类型的元素【把数据库表中的列名称与实体类中的成员变量的名称映射起来】
id属性:查询的结果类型的名称。
type属性:配置需要映射的java实体类的类名
7.<id>元素-----配置的是主键列的映射关系
column属性:配置数据库表的列名。
property属性:配置实体类的成员变量名称。
8.<result>元素-----配置除主键之外的其他列
column属性:配置数据库表的列名。
property属性:配置实体类的成员变量名称。
注意:<insert>元素、<update>元素、<delete>元素、<select>元素的id属性是不能重复,意味着数据访问接口中不能出现方法重载的现象。
7. MyBatis核心配置文件中typeAliases元素有什么作用?如何配置?如何使用?
typeAliases元素出现在MyBatis的核心配置文件【MyBatis-config.xml】中。typeAliases元素用来设置实体类的别名【短名称】。方便在sql映射文件中使用这个短名称。
设置方式1:一个类一个别名
<typeAliases>
<typeAlias alias="Author" type="domain.blog.Author"/>
<typeAlias alias="Blog" type="domain.blog.Blog"/>
<typeAlias alias="Comment" type="domain.blog.Comment"/>
<typeAlias alias="Post" type="domain.blog.Post"/>
<typeAlias alias="Section" type="domain.blog.Section"/>
<typeAlias alias="Tag" type="domain.blog.Tag"/>
</typeAliases>
设置方式2:设置一个包名,MyBatis 会在包名下面搜索需要的 Java Bean,会使用 Bean 的非限定类名来作为它的别名。
<typeAliases>
<package name="domain.blog"/>
</typeAliases>
8. sql映射文件中select元素resultType和resultMap属性有什么区别?
resultType/resultMap都是查询语句执行之后的返回结果的类型表示属性,会在sql映射文件中select元素中使用
resultType表示的执行完数据库操作之后,返回的结果数据类型。结果可以用三种数据类型来处理:
简单类型。例如:string、long、integer、double等
pojo类型。例如:Person,User等
HashMap类型。
数据库表中的列名称与实体类中的成员变量的名称相同时,一般设置resultType指定返回的结果数据类型。
/**
* 保存学生信息的java实体类
* @author Administrator
*
*/
@SuppressWarnings("serial")
public class Student implements Serializable{
private int stuid;
private String stuname;
private int stuage;
private String stuaddress;
public int getStuid() {
return stuid;
}
public void setStuid(int stuid) {
this.stuid = stuid;
}
public String getStuname() {
return stuname;
}
public void setStuname(String stuname) {
this.stuname = stuname;
}
public int getStuage() {
return stuage;
}
public void setStuage(int stuage) {
this.stuage = stuage;
}
public String getStuaddress() {
return stuaddress;
}
public void setStuaddress(String stuaddress) {
this.stuaddress = stuaddress;
}
}
/**
* Student信息的数据访问接口
* 注意:数据库操作方法是不能有重载,后面配置MyBatisSQL映射文件的时候需要使用这个方法名称
* @author Administrator
*
*/
public interface StudentMapper {
boolean insertStudent(Student student);
List<Student> selectStudent();
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- 配置引入数据库链接字符串的资源文件 -->
<properties resource="testconfig/myjdbc.properties"></properties>
<typeAliases>
<package name="com.click369.mybatis.javabean"/>
</typeAliases>
<!-- 配置mybatis默认的连接数据库的环境 -->
<environments default="development">
<environment id="development">
<!-- 配置事物管理器 -->
<transactionManager type="JDBC"></transactionManager>
<!-- 配置数据源 -->
<dataSource type="POOLED">
<property name="driver" value="${mydriver}"/>
<property name="url" value="${myurl}"/>
<property name="username" value="${myusername}"/>
<property name="password" value="${mypassword}"/>
</dataSource>
</environment>
</environments>
<!-- 配置MyBatis数据访问接口的SQL映射文件路径 -->
<mappers>
<mapper resource="com/click369/mybatis/mapper/PersonMapper.xml"/>
<mapper resource="com/click369/mybatis/mapper/StudentMapper.xml"/>
</mappers>
</configuration>
<?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.click369.mybatis.mapper.StudentMapper">
<!-- 配置添加信息的SQL语句 -->
<insert id="insertStudent" parameterType="Student">
insert into t_student values(null,#{stuname},#{stuage},#{stuaddress})
</insert>
<!-- 配置根据id查询数据的sql语句 -->
<select id="selectStudent" resultType="Student">
select * from t_student
</select>
</mapper>
resultMap表示的执行完数据库操作之后,返回的结果数据类型。
resultMap是mybatis中最重要最强大的元素,使用resultmap可以解决2个问题:
1.JavaBean的属性名和表字段名不一致的问题
Java代码
/**
* 保存个人信息的java实体类
* @author Administrator
*
*/
@SuppressWarnings("serial")
public class Person implements Serializable{
private int perid;
private String pername;
private int perage;
private String peraddress;
public int getPerid() {
return perid;
}
public void setPerid(int perid) {
this.perid = perid;
}
public String getPername() {
return pername;
}
public void setPername(String pername) {
this.pername = pername;
}
public int getPerage() {
return perage;
}
public void setPerage(int perage) {
this.perage = perage;
}
public String getPeraddress() {
return peraddress;
}
public void setPeraddress(String peraddress) {
this.peraddress = peraddress;
}
}
/**
* Person信息的数据访问接口
* 注意:数据库操作方法是不能有重载,后面配置MyBatisSQL映射文件的时候需要使用这个方法名称
* @author Administrator
*
*/
public interface PersonMapper {
/**
* 添加数据
* @param person
* @return
*/
boolean insertPerson(Person person);
/**
* 修改数据
* @param person
* @return
*/
boolean updatePerson(Person person);
/**
* 删除数据
* @param person
* @return
*/
boolean deletePersonById(int perid);
/**
* 根据id查询数据
* @param person
* @return
*/
Person selectPersonById(int perid);
/**
* 查询所有数据
* @param person
* @return
*/
List<Person> selectPerson();
}
核心配置文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- 配置引入数据库链接字符串的资源文件 -->
<properties resource="testconfig/myjdbc.properties"></properties>
<!-- 配置mybatis默认的连接数据库的环境 -->
<environments default="development">
<environment id="development">
<!-- 配置事物管理器 -->
<transactionManager type="JDBC"></transactionManager>
<!-- 配置数据源 -->
<dataSource type="POOLED">
<property name="driver" value="${mydriver}"/>
<property name="url" value="${myurl}"/>
<property name="username" value="${myusername}"/>
<property name="password" value="${mypassword}"/>
</dataSource>
</environment>
</environments>
<!-- 配置MyBatis数据访问接口的SQL映射文件路径 -->
<mappers>
<!-- 如果SQL映射文件在数据访问接口包中 -->
<!-- <package name="com/click369/mybatis/mapper/PersonMapper.xml"/> -->
<package name="com/click369/mybatis/mapper"/>
<!-- 如果SQL映射文件在src/main/resources中 -->
<!-- <mapper resource="PersonMapper.xml"/>-->
<!-- <mapper resource="com/click369/mybatis/mapper/PersonMapper.xml"/>-->
</mappers>
</configuration>
sql映射文件
<?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.click369.mybatis.mapper.PersonMapper">
<!-- 配置添加数据的sql语句 -->
<insert id="insertPerson" parameterType="com.click369.mybatis.javabean.Person">
insert into t_person values(null,#{pername},#{perage},#{peraddress})
</insert>
<!-- 配置修改数据的sql语句 -->
<update id="updatePerson" parameterType="com.click369.mybatis.javabean.Person">
update t_person set per_name=#{pername},
per_age=#{perage},
per_address=#{peraddress}
where per_id=#{perid}
</update>
<!-- 配置查询的返回值resultMap -->
<resultMap type="com.click369.mybatis.javabean.Person" id="personMap">
<id column="per_id" property="perid" />
<result column="per_name" property="pername"/>
<result column="per_age" property="perage"/>
<result column="per_address" property="peraddress"/>
</resultMap>
<!-- 配置根据id查询数据的sql语句 -->
<select id="selectPersonById" parameterType="int" resultMap="personMap">
select * from t_person where per_id=#{perid}
</select>
<!-- 配置查询所有数据的sql语句 -->
<select id="selectPerson" resultType="" resultMap="personMap">
select * from t_person
</select>
<!-- 配置删除数据的sql语句 -->
<delete id="deletePersonById" parameterType="int">
delete from t_person where per_id=#{perid}
</delete>
</mapper>
2.完成高级查询。例如:一对一、一对多、多对多。
9. sql映射文件中的parameterType属性传入参数怎么使用?
parameterType主要用于传递输入的参数
传入参数有三种方式:
简单数据类型。例如:string、long、integer、double等
pojo(JavaBean)类型。例如:Person、User等
HashMap类型。
测试传入pojo(JavaBean)型参数
import com.click369.mybatis.javabean.User;
public interface UserMapper {
boolean insertUser(User student);
}
<!-- 配置添加信息的SQL语句 -->
<insert id="insertUser" parameterType="user">
insert into t_user values(null,#{username},#{userpass},#{userage},#{useraddress})
</insert>
@Test
public void testInsertUser(){
SqlSession session=null;
try{
//加载mybatis配置文件
InputStream inputStream=Resources.getResourceAsStream("mybatis-config.xml");
//创建SqlSessionFactory接口对象
SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream);
//创建SqlSession接口对象【有增删该查方法】
session=sqlSessionFactory.openSession();
//通过SqlSession接口对象得到数据访问接口对象
UserMapper userMapper =session.getMapper(UserMapper.class);
for(int i=1;i<=10;i++){
User user=new User();
user.setUsername("zhangsan_"+i);
user.setUserpass("password_"+i);
user.setUserage(20+i);
user.setUseraddress("address_"+i);
boolean flag=userMapper.insertUser(user);
}
//提交执行
session.commit();
}catch(Exception e){
e.printStackTrace();
}finally{
session.close();
}
}
测试传入基本数据类型参数
public interface UserMapper {
User selectUserById(int usreid);
}
<!-- 配置resultMap映射 -->
<resultMap type="User" id="usermap">
<id column="user_id" property="userid"/>
<result column="user_name" property="username"/>
<result column="user_pass" property="userpass"/>
<result column="user_age" property="userage"/>
<result column="user_address" property="useraddress"/>
</resultMap>
<!-- 配置根据id查询数据的sql语句 -->
<select id="selectUserById" parameterType="int" resultMap="usermap">
select * from t_user where user_id=#{userid}
</select>
@Test
public void testSelectUserById(){
SqlSession session=null;
try{
//加载mybatis配置文件
InputStream inputStream=Resources.getResourceAsStream("mybatis-config.xml");
//创建SqlSessionFactory接口对象
SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream);
//创建SqlSession接口对象【有增删该查方法】
session=sqlSessionFactory.openSession();
//通过SqlSession接口对象得到数据访问接口对象
UserMapper userMapper =session.getMapper(UserMapper.class);
User user=userMapper.selectUserById(5);
System.out.println(user.getUserid()+" "+user.getUsername()+" "+user.getUserpass());
//提交执行
session.commit();
}catch(Exception e){
e.printStackTrace();
}finally{
session.close();
}
}
测试传入HashMap类型参数
public interface UserMapper {
List<User> selectUserByWhere(Map parameter);
}
<!-- 配置resultMap映射 -->
<resultMap type="User" id="usermap">
<id column="user_id" property="userid"/>
<result column="user_name" property="username"/>
<result column="user_pass" property="userpass"/>
<result column="user_age" property="userage"/>
<result column="user_address" property="useraddress"/>
</resultMap>
<!-- 配置根据条件查询数据的sql语句 -->
<select id="selectUserByWhere" parameterType="hashMap" resultMap="usermap">
select * from t_user where user_name=#{name} and user_pass=#{pass} and user_age=#{age}
</select>
@Test
public void testSelectUserByWhere(){
SqlSession session=null;
try{
//加载mybatis配置文件
InputStream inputStream=Resources.getResourceAsStream("mybatis-config.xml");
//创建SqlSessionFactory接口对象
SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream);
//创建SqlSession接口对象【有增删该查方法】
session=sqlSessionFactory.openSession();
//通过SqlSession接口对象得到数据访问接口对象
UserMapper userMapper =session.getMapper(UserMapper.class);
Map<String,Object> parameter=new HashMap<String,Object>();
parameter.put("name", "zhangsan_2");
parameter.put("pass", "password_2");
parameter.put("age", 22);
List<User> userlist=userMapper.selectUserByWhere(parameter);
for(User user:userlist){
System.out.println(user.getUserid()+" "+user.getUsername()+" "+user.getUserpass());
}
//提交执行
session.commit();
}catch(Exception e){
e.printStackTrace();
}finally{
session.close();
}
}
10. #{}和${}的用法
在mybatis的mapper文件[sql映射文件]中,参数传递有2种方式。一种是#{},另一种是${},两者有较大的区别:
#{} 实现的是sql语句的预处理,之后执行的sql中用?号代替。使用时不需要关注参数的数据类型。mybatis会自动实现数据类型转换,并且可以防止sql注入。
${}实现sql语句的拼接操作,不做数据类型转换,需要自行判断数据类型,不能防止sql注入。
总结:#{}占位符,用于参数传递。${}用于sql拼接
11. 什么是动态SQL?为什么使用动态SQL?有哪些动态SQL?如何使用?
MyBatis 的强大特性之一便是它的动态 SQL。通常使用动态 SQL 不可能是独立的一部分,MyBatis 当然使用一种强大的动态 SQL 语言来改进这种情形,这种语言可以被用在任意的 SQL 映射语句中。动态 SQL 元素和使用 JSTL 或其他类似基于 XML 的文本处理器相似。MyBatis 采用功能强大的基于 OGNL 的表达式来消除其他元素。常见的动态SQL:
if
choose (when, otherwise)
trim (where, set)
forEach
动态SQL-----if元素
<select id="selectPersonTestIf" resultType="PersonBean">
select * from t_person where 1=1
<if test="name != null and name !=''">
and per_name like #{name}
</if>
</select>
动态SQL-----where元素
<select id="selectPersonTestWhere1" parameterType="PersonBean" resultType="PersonBean">
select * from t_person
<where>
<if test="per_name != null and per_name !=''">
and per_name like #{per_name}
</if>
<if test="per_age != null and per_age != 0">
and per_age = #{per_age}
</if>
</where>
</select>
动态SQL-----set元素
<update id="updateTestSet1" parameterType="PersonBean" >
update t_person
<set>
<if test="per_name !=null and per_name !=''">
per_name = #{per_name},
</if>
<if test="per_age !=null and per_age !=0">
per_age = #{per_age},
</if>
<if test="per_address !=null and per_address !=''">
per_address = #{per_address},
</if>
</set>
<where>per_id = #{per_id}</where>
</update>
动态SQL-----foreach 元素
<!-- 批量删除 -->
<delete id="deleteTestForeach" parameterType="java.util.List">
delete from t_person where per_id in
<foreach collection="list" item="personid" open="(" close=")" separator=",">
#{personid}
</foreach>
</delete>
<!-- 批量添加-->
<insert id="insertTestForeach" parameterType="java.util.List">
insert into t_person values
<foreach collection="list" item="person" separator=",">
(null,#{person.per_name},#{person.per_age},#{person.per_address})
</foreach>
</insert>
12. MyBatis的缓存处理?
MyBatis框架本身也提供相关的缓存机制,并分为两种:一级缓存、二级缓存
一级缓存
MyBatis默认是开启一级缓存。当使用openSession方法之后,获取到SqlSession对象,只要使用当前这个SqlSession对象进行数据库的操作,那么执行的是相同的sql(相同的语句和参数),mybatis不进行sql的执行,而是从缓存中找到对应的数据返回。mybatis的一级缓存:属于SqlSession级别的(会话级别的)。当使用mybatis执行查询时,mybatis会先到一级缓存中找有没有需要查询的数据,如果有就返回,而不会执行sql去数据库中查询。
强制不缓存-----openSession(true);【每次去数据库查询数据】
二级缓存
MyBatis的二级缓存是当前这个Mapper文件的namespace范围。也就是同一个namespace下的所有查询语句可以共享二级缓存中的数据。二级缓存是可以跨越多个session的。只要它们是同一个mapper下的namespace即可。要开启二级缓存,你需要在你的 SQL 映射(Mapper)文件中添加一行:<cache/>。
二级缓存是在session关闭之前将数据写入到缓存区域,并且要求数据对象必须可序列化。
13. MyBatis的高级查询中的一对一查询方式有几种,如何配置?
针对一对一查询提供了两种方式:
Java实体类创建
/**
* 保存用户基本信息java实体类
* 由于当我们在查询用户基本信息的时候需要连同用户身份证信息一起得到,
* 所以我们就需要在保存用户基本信息的java实体类中新增一个成员变量,用来保存用户身份证信息。
* @author Administrator
*
*/
@SuppressWarnings("serial")
public class UserBean implements Serializable{
private int userid;
private String username;
private int userage;
private String useraddress;
//用来保存用户身份证信息成员变量
private CardBean cardBean;
public int getUserid() {
return userid;
}
public void setUserid(int userid) {
this.userid = userid;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public int getUserage() {
return userage;
}
public void setUserage(int userage) {
this.userage = userage;
}
public String getUseraddress() {
return useraddress;
}
public void setUseraddress(String useraddress) {
this.useraddress = useraddress;
}
public CardBean getCardBean() {
return cardBean;
}
public void setCardBean(CardBean cardBean) {
this.cardBean = cardBean;
}
}
/**
* 保存用户身份证信息的java实体类
* 由于当我们在查询用户身份证信息的时候需要连同用户基本信息一起得到,
* 所以我们就需要在保存用户身份证信息的java实体类中新增一个成员变量,用来保存用户基本信息。
* @author Administrator
*
*/
@SuppressWarnings("serial")
public class CardBean implements Serializable{
private int cardid;
private int useridfk;
private String cardcode;
private int cardyear;
private UserBean userBean;
public int getCardid() {
return cardid;
}
public void setCardid(int cardid) {
this.cardid = cardid;
}
public int getUseridfk() {
return useridfk;
}
public void setUseridfk(int useridfk) {
this.useridfk = useridfk;
}
public String getCardcode() {
return cardcode;
}
public void setCardcode(String cardcode) {
this.cardcode = cardcode;
}
public int getCardyear() {
return cardyear;
}
public void setCardyear(int cardyear) {
this.cardyear = cardyear;
}
public UserBean getUserBean() {
return userBean;
}
public void setUserBean(UserBean userBean) {
this.userBean = userBean;
}
}
嵌套resultMap
<?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.click369.mapper.UserBeanMapper">
<!-- 嵌套resultMap 方式1 -->
<resultMap type="userBean" id="userMap">
<id property="userid" column="user_id"/>
<result property="username" column="user_name"/>
<result property="userage" column="user_age"/>
<result property="useraddress" column="user_address"/>
<!-- association 元素配置CardBean对应的 resultMap-->
<association property="cardBean" javaType="cardBean" resultMap="cardMap"></association>
</resultMap>
<resultMap type="cardBean" id="cardMap">
<id property="cardid" column="card_id"/>
<result property="useridfk" column="user_id_fk"/>
<result property="cardcode" column="card_code"/>
<result property="cardyear" column="card_year"/>
</resultMap>
<select id="selectUserCardByUserId" parameterType="int" resultMap="userMap">
select u.user_id,u.user_name,u.user_age,u.user_address,
c.card_id,c.user_id_fk,c.card_code,c.card_year
from t_user as u inner join t_card as c
on u.user_id=c.user_id_fk
where u.user_id=#{userid}
</select>
</mapper>
<!--以下为嵌套resultMap的第二种方式-->
<!-- 嵌套resultMap 方式2 -->
<resultMap type="userBean" id="userMap1">
<id property="userid" column="user_id"/>
<result property="username" column="user_name"/>
<result property="userage" column="user_age"/>
<result property="useraddress" column="user_address"/>
<!-- association 元素配置CardBean对应的 resultMap-->
<association property="cardBean" javaType="cardBean">
<id property="cardid" column="card_id"/>
<result property="useridfk" column="user_id_fk"/>
<result property="cardcode" column="card_code"/>
<result property="cardyear" column="card_year"/>
</association>
</resultMap>
<select id="selectUserCardByUserId1" parameterType="int" resultMap="userMap1">
select u.user_id,u.user_name,u.user_age,u.user_address,
c.card_id,c.user_id_fk,c.card_code,c.card_year
from t_user as u inner join t_card as c
on u.user_id=c.user_id_fk
where u.user_id=#{userid}
</select>
嵌套select
<?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.click369.mapper.CardBeanMapper">
<!-- 嵌套select -->
<resultMap type="cardBean" id="cardMap">
<id property="cardid" column="card_id"/>
<result property="useridfk" column="user_id_fk"/>
<result property="cardcode" column="card_code"/>
<result property="cardyear" column="card_year"/>
<!-- association配置查询用户基本信息的sql -->
<association property="userBean" column="user_id_fk" javaType="userBean" select="getUserByUseridFk"></association>
</resultMap>
<select id="selectCardUserByCardId" parameterType="int" resultMap="cardMap">
select * from t_card where card_id=#{cardid};
</select>
<resultMap type="userBean" id="userMap">
<id property="userid" column="user_id"/>
<result property="username" column="user_name"/>
<result property="userage" column="user_age"/>
<result property="useraddress" column="user_address"/>
</resultMap>
<select id="getUserByUseridFk" parameterType="int" resultMap="userMap">
select * from t_user where user_id=#{useridfk};
</select>
</mapper>
14. MyBatis的高级查询中的一对多查询方式有几种,如何配置?
针对一对多查询提供了两种方式:
Java实体类创建
/**
* 保存班级信息的java实体类
* 当我们查询班级信息的时候需要连同这个班级中的所有学生信息一起得到,
* 所以我们需要在保存班级信息的java实体类中新增一个集合类型的成员变量,用来保存这个班级的所有学生信息
* @author Administrator
*
*/
@SuppressWarnings("serial")
public class ClassBean implements Serializable{
private int classid;
private String classcode;
private String classname;
private List<StudentBean> studentList;
public int getClassid() {
return classid;
}
public void setClassid(int classid) {
this.classid = classid;
}
public String getClasscode() {
return classcode;
}
public void setClasscode(String classcode) {
this.classcode = classcode;
}
public String getClassname() {
return classname;
}
public void setClassname(String classname) {
this.classname = classname;
}
public List<StudentBean> getStudentList() {
return studentList;
}
public void setStudentList(List<StudentBean> studentList) {
this.studentList = studentList;
}
}
/**
* 保存学生信息的java实体类
* 当我们查询学生信息的时候需要连同这个学生所在班级的信息一起得到,
* 所以我们需要在保存学生信息的java实体类中新增一个成员变量,用来班级信息
* @author Administrator
*
*/
@SuppressWarnings("serial")
public class StudentBean implements Serializable{
private int stuid;
private int classidfk;
private String stuname;
private int stuage;
private String stuaddress;
private ClassBean classBean;
public int getStuid() {
return stuid;
}
public void setStuid(int stuid) {
this.stuid = stuid;
}
public int getClassidfk() {
return classidfk;
}
public void setClassidfk(int classidfk) {
this.classidfk = classidfk;
}
public String getStuname() {
return stuname;
}
public void setStuname(String stuname) {
this.stuname = stuname;
}
public int getStuage() {
return stuage;
}
public void setStuage(int stuage) {
this.stuage = stuage;
}
public String getStuaddress() {
return stuaddress;
}
public void setStuaddress(String stuaddress) {
this.stuaddress = stuaddress;
}
public ClassBean getClassBean() {
return classBean;
}
public void setClassBean(ClassBean classBean) {
this.classBean = classBean;
}
}
嵌套resultMap
<?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.click369.mapper.ClassBeanMapper">
<!-- 嵌套resultMap 方式1 -->
<resultMap type="classBean" id="classMap">
<id property="classid" column="class_id"/>
<result property="classcode" column="class_code"/>
<result property="classname" column="class_name"/>
<!-- collection元素配置一对多 -->
<collection property="studentList" ofType="studentBean" resultMap="studentMap"></collection>
</resultMap>
<resultMap type="studentBean" id="studentMap">
<id property="stuid" column="stu_id"/>
<result property="classidfk" column="class_id_fk"/>
<result property="stuname" column="stu_name"/>
<result property="stuage" column="stu_age"/>
<result property="stuaddress" column="stu_address"/>
</resultMap>
<select id="selectClassStudentByClassId" parameterType="java.lang.String" resultMap="classMap">
select c.class_id,c.class_code,c.class_name,
s.stu_id,s.class_id_fk,s.stu_name,s.stu_age,s.stu_address
from t_class as c left outer join t_student as s
on c.class_code=#{classcode};
</select>
</mapper>
<!-- 嵌套resultMap 方式2 -->
<resultMap type="classBean" id="classMap2">
<id property="classid" column="class_id"/>
<result property="classcode" column="class_code"/>
<result property="classname" column="class_name"/>
<!-- collection元素配置一对多 -->
<collection property="studentList" ofType="studentBean" >
<id property="stuid" column="stu_id"/>
<result property="classidfk" column="class_id_fk"/>
<result property="stuname" column="stu_name"/>
<result property="stuage" column="stu_age"/>
<result property="stuaddress" column="stu_address"/>
</collection>
</resultMap>
<select id="selectClassStudentByClassId2" parameterType="java.lang.String" resultMap="classMap2">
select c.class_id,c.class_code,c.class_name,
s.stu_id,s.class_id_fk,s.stu_name,s.stu_age,s.stu_address
from t_class as c left outer join t_student as s
on c.class_code=#{classcode};
</select>
嵌套select
<!-- 嵌套select -->
<resultMap type="classBean" id="classMap3">
<id property="classid" column="class_id"/>
<result property="classcode" column="class_code"/>
<result property="classname" column="class_name"/>
<collection property="studentList" column="class_id" ofType="studentBean" select="getStudentInfo"></collection>
</resultMap>
<select id="selectClassStudentByClassId3" parameterType="java.lang.String" resultMap="classMap3">
select * from t_class where class_code=#{classcode}
</select>
<resultMap type="studentBean" id="studentMap3">
<id property="stuid" column="stu_id"/>
<result property="classidfk" column="class_id_fk"/>
<result property="stuname" column="stu_name"/>
<result property="stuage" column="stu_age"/>
<result property="stuaddress" column="stu_address"/>
</resultMap>
<select id="getStudentInfo" parameterType="int" resultMap="studentMap3">
select * from t_student where class_id_fk=#{classid}
</select>
15. MyBatis的高级查询中的多对多查询如何配置?
创建Java实体类
/**
* 保存角色信息的java实体类
* 由于我们在查询角色信息的时候需要得到角色所属的信息,
* 因此我们需要在保存角色信息的java类中创建一个集合类型成员变量,
* 用来保存角色所属组信息
* @author Administrator
*
*/
@SuppressWarnings("serial")
public class RoleBean implements Serializable{
private int roleid;
private String rolename;
private String roleinfo;
private List<GroupBean> grouplist;
public int getRoleid() {
return roleid;
}
public void setRoleid(int roleid) {
this.roleid = roleid;
}
public String getRolename() {
return rolename;
}
public void setRolename(String rolename) {
this.rolename = rolename;
}
public String getRoleinfo() {
return roleinfo;
}
public void setRoleinfo(String roleinfo) {
this.roleinfo = roleinfo;
}
public List<GroupBean> getGrouplist() {
return grouplist;
}
public void setGrouplist(List<GroupBean> grouplist) {
this.grouplist = grouplist;
}
}
/**
* 保存角色所属组信息的java实体类
* 由于我们在查询角色所属组信息的时候需要得到角色的基本信息,
* 所以我们需要在保存角色所属组信息的java实体类中,创建一个集合类型的成员变量,
* 用来保存这个组中的角色信息
* @author Administrator
*
*/
@SuppressWarnings("serial")
public class GroupBean implements Serializable{
private int groupid;
private String groupname;
private String groupinfo;
private List<RoleBean> rolelist;
public int getGroupid() {
return groupid;
}
public void setGroupid(int groupid) {
this.groupid = groupid;
}
public String getGroupname() {
return groupname;
}
public void setGroupname(String groupname) {
this.groupname = groupname;
}
public String getGroupinfo() {
return groupinfo;
}
public void setGroupinfo(String groupinfo) {
this.groupinfo = groupinfo;
}
public List<RoleBean> getRolelist() {
return rolelist;
}
public void setRolelist(List<RoleBean> rolelist) {
this.rolelist = rolelist;
}
}
<?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.click369.mapper.RoleBeanMapper">
<resultMap type="roleBean" id="roleMap">
<id property="roleid" column="role_id"/>
<result property="rolename" column="role_name"/>
<result property="roleinfo" column="role_info"/>
<collection property="grouplist" ofType="groupBean" resultMap="groupMap"></collection>
</resultMap>
<resultMap type="groupBean" id="groupMap">
<id property="groupid" column="group_id"/>
<result property="groupname" column="group_name"/>
<result property="groupinfo" column="group_info"/>
</resultMap>
<select id="selectRoleAndGroupByRoleid" parameterType="int" resultMap="roleMap">
select r.role_id,r.role_name,r.role_info,
g.group_id,g.group_name,g.group_info
from t_role as r inner join t_role_group as rg
on r.role_id = rg.role_id_fk
inner join t_group as g
on g.group_id = rg.group_id_fk
where r.role_id=#{roleid}
</select>
</mapper>
16. MyBatis提供的分页查询的原理?
1.在xml映射文件中编写SQL 语句的时候利用limit关键字分页
select * from student limit #{currIndex} , #{pageSize}
2.使用拦截器分页【利用PageHelper分页插件】--- 物理分页
分页插件的原理是利用拦截器去拦截指定的查询操作,然后在拦截到的查询操作中添加相关的分页逻辑,完成分页。
怎么做的:
1.创建拦截器,拦截mybatis接口中指定的查询方法
2.在mybatis的核心配置文件中,利用<plugins>标签,配置自己的拦截器
3.RowBounds分页--逻辑分页----内存溢出错误
Mybatis使用RowBounds对象进行分页,它是针对ResultSet结果集执行的内存分页,而非物理分页,可以在sql内直接书写带有物理分页的参数来完成物理分页功能,也可以使用分页插件来完成物理分页。
推荐阅读
-
SSM框架整合(一)
-
基于ssm(Spring+SpringMVC+MybatisPlus)框架整合Security(一)
-
框架修炼之ssm-Mybatis学习笔记一
-
Python的Django框架中URLconf相关的一些技巧整理
-
使用eclipse + maven一步步搭建SSM框架教程详解
-
Python的Django框架中URLconf相关的一些技巧整理
-
一步步教你整合SSM框架(Spring MVC+Spring+MyBatis)详细教程
-
Laravel框架基础语法与知识点整理【模板变量、输出、include引入子视图等】
-
Python的Django框架中URLconf相关的一些技巧整理
-
mysql基础知识整理(一)