欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 科技 > 能源 > JAVA后端框架--【Mybatis】

JAVA后端框架--【Mybatis】

2024/10/24 19:15:36 来源:https://blog.csdn.net/2302_77125952/article/details/141534425  浏览:    关键词:JAVA后端框架--【Mybatis】

框架

框架就是对技术的封装,将基础的技术进行封装,让程序员快速使用,提高开发效率

java后端框架

mybatis

对jdbc进行封装

背景介绍

mybatis是apache下面的一个开源项目,名为ibatis,2010年开发团队转移到谷歌旗下,更名为mybatis

mybatis是一个优秀的数据持久性框架(dao层 数据访问层 数据持久性)

对jdbc进行封装,避免了jdbc中手动设置参数,手动映射结果的操作

mybatis将jdbc中接口进行封装,提供了它自己的类和接口实现。

mybatis可以使用xml配置和注解的方式,将数据库中记录自动映射到java对象中,

是一种orm实现(对象关系映射)将可以自动映射到对象中的这种框架,也称为orm框架

mybatis还提供了动态sql和数据缓存功能

mybatis搭建
1.创建mven项目

2.导入mybatis依赖的jar
 <dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.4.2</version></dependency>
3.创建一个全局的mybatis配置文件,配置数据库进行链接

<?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><settings><setting name="logImpl" value="STDOUT_LOGGING"/></settings><!--为类配置别名--><typeAliases><package name="com.wph.mybatis.model"/></typeAliases><environments default="development"><environment id="development"><transactionManager type="JDBC"/><dataSource type="POOLED"><property name="driver" value="com.mysql.cj.jdbc.Driver" /><property name="url" value="jdbc:mysql://127.0.0.1:3306/ssmdb?serverTimezone=Asia/Shanghai" /><property name="username" value="root" /><property name="password" value="root"/></dataSource></environment></environments><!--注册映射文件--><mappers><mapper resource="Mappers/AdminMapper.xml"></mapper></mappers>
</configuration>
4.创建数据库,创建表

create database ssmdbcreate table admin(
id int primary key auto_increment,
account varchar(10),
password varchar(10),
gender varchar(10)
)

5.创建一个访问接口,定义方法
package com.wph.mybatis.dao;import com.wph.mybatis.model.Admin;
import org.apache.ibatis.annotations.Param;public interface AdminDao {Admin findAdminbyid(int id);Admin findAdminbyAccount(String account);Admin login(@Param("acc") String account,@Param("pwd") String password);Admin login1(Admin admin);void deleteadmin(int id);void insert(Admin admin);void update(Admin admin);
}
6.创建接口对应映射文件
<?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.wph.mybatis.dao.AdminDao"><update id="update" parameterType="Admin">update admin set account=#{account},password=#{password},gender=#{gender} where id=#{id}</update><select id="findAdminbyid" parameterType="int" resultType="Admin">select * from admin where id = #{id}</select><select id="findAdminbyAccount" parameterType="String" resultType="Admin">select * from admin where account = #{account}</select><select id="login" resultType="Admin">select * from admin where account=#{acc} and password =#{pwd}</select><select id="login1" resultType="Admin">select * from admin where account=#{account} and password =#{password}</select><delete id="deleteadmin" parameterType="int">delete from admin where id=#{id}</delete><!--useGeneratedKeys="true" keyProperty="id" keyColumn="id"--><insert id="insert" parameterType="Admin" >insert into admin(account,password,gender) values (#{account},#{password},#{gender})</insert>
</mapper>
7.测试 MyBatis

读取配置文件 Reader reader = Resources.getResourceAsReader("mybatis-config.xml"); 创建 SqlSessionFactory SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(reader);

创建 SqlSession SqlSession sqlSession = sessionFactory.openSession();

获得接口代理对象 sqlSession.getMapper(接口.class); sqlSession .close();

package com.wph.mybatis.Test;import com.wph.mybatis.dao.AdminDao;
import com.wph.mybatis.model.Admin;
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.Reader;public class test {public static void main(String[] args) throws IOException {//1.mybatis读取配置文件Reader reader= Resources.getResourceAsReader("mabiatis.xml");//2.创建SqlSeaaionFactory ,负责创建SqlSession对象SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(reader);//3.创建SqlSession对象SqlSession sqlSession=sqlSessionFactory.openSession();//创建接口的代理对象AdminDao adminDao =sqlSession.getMapper(AdminDao.class);Admin admin=adminDao.findAdminbyid(1);//让代理对象帮我们调用映射文件与此接口中相同名称的方法System.out.println(admin);sqlSession.close();//关闭会话对象}
}

关闭 API 接口说明 SqlSessionFactory 接口 使用 SqlSessionFactory 来创建 SqlSession,一旦创建 SqlSessionFactory 就 会在整个应用过程中始终存在。由于创建开销较大,所以没有理由去销毁再创建 它,一个应用运行中也不建议多次创建 SqlSessionFactory。 SqlSession 接口 Sqlsession 意味着创建与数据库链接会话,该接口中封装了对数据库操作的方 法,与数据库会话完成后关闭会话。

package com.wph.mybatis.Test;import com.wph.mybatis.dao.AdminDao;
import com.wph.mybatis.model.Admin;
import com.wph.mybatis.util.MyBatisUtil;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;public class test3 {/*单元测试,程序员使用的测试方法,以方法为单位测试使用junit组件实现单元测试*/@Testpublic  void  insert(){Admin admin=new Admin();admin.setAccount("aaa");admin.setPassword("123");admin.setGender("男");SqlSession sqlSession= MyBatisUtil.getSqlsession();AdminDao adminDao=sqlSession.getMapper(AdminDao.class);adminDao.insert(admin);sqlSession.commit();//提交数据库事务,当我们的程序代码执行没有任何问题时,再向数据库发送提交事务操作,数据库真正执行//sql,出现异常则不提交,新增,修改,删除完毕后,都需要手动提交事务sqlSession.close();/** 数据库事务:是数据库的一个管理机制,是对一次链接数据库过程的管理,*           保证一次操作中,执行的多条sql,要么都成功执行,要么都不执行* 转账: 链接到数据库*   1.先从A账户捡钱sql11*   其他代码逻辑(可能出现异常)* 2.再向B账户加钱 sql2* 提交事务  数据库才会真正的在数据库执行这一次操作中多条sql* */}@Testpublic void delete(){SqlSession sqlSession= MyBatisUtil.getSqlsession();AdminDao adminDao=sqlSession.getMapper(AdminDao.class);adminDao.deleteadmin(1);sqlSession.commit();sqlSession.close();}@Testpublic void update(){Admin admin=new Admin();admin.setAccount("ddd");admin.setPassword("666");admin.setGender("女");admin.setId(1);SqlSession sqlSession= MyBatisUtil.getSqlsession();AdminDao adminDao=sqlSession.getMapper(AdminDao.class);adminDao.update(admin);}
}

 

数据库连接池

链接数据库每次访问数据库时候,创建一个Cinnection,用完关闭,但是访问量大了后,每次都要创建新的连接对象,用完关闭,比较耗时

使用数据库连接池,在池(集合)中事先创建一些链接对象,用完不销毁,还回到池中这样就减小频繁创建销毁链接对象。

package com.wph.mybatis.Test;import com.wph.mybatis.dao.AdminDao;
import com.wph.mybatis.model.Admin;
import com.wph.mybatis.util.MyBatisUtil;
import org.apache.ibatis.session.SqlSession;public class test2 {public static void main(String[] args) {//SqlSession是每次与数据库链接会话对象,用完关闭SqlSession sqlSession= MyBatisUtil.getSqlsession();AdminDao adminDao=sqlSession.getMapper(AdminDao.class);adminDao.findAdminbyid(1);Admin admin=adminDao.findAdminbyAccount("admin");System.out.println(admin);//Admin admin=adminDao.login("admin", "111");//System.out.println(admin);/*Admin admin1=new Admin();admin1.setAccount("admin");admin1.setPassword("111");Admin admin2=adminDao.login1(admin1);*/sqlSession.close();//关闭链接对象,如果使用数据库连接功能,本质上没有关闭,回到池中}
}
 增删改查

唯一标识" useGeneratedKeys="把新增加的主键赋值到自己定义的 keyProperty " keyProperty=“ 接收主键的属性 parameterType="参数类型">

insert into admin(account,password)values(#{account},#{password})

<!--useGeneratedKeys="true" keyProperty="id" keyColumn="id"--><insert id="insert" parameterType="Admin" >insert into admin(account,password,gender) values (#{account},#{password},#{gender})</insert>

修改 "唯一标识" parameterType=“参数类型">

 <update id="update" parameterType="Admin">update admin set account=#{account},password=#{password},gender=#{gender} where id=#{id}</update>

update admin set account= #{account},password= #{password} where id= #{id}

删除 "唯一标识" parameterType="参数类型"> delete from admin where id= #{id}

 <delete id="deleteadmin" parameterType="int">delete from admin where id=#{id}</delete>

查询 唯一标识" resultType="返回结果集类型"> select * from admin where id= #{id}

 <resultMap id="adminMap" type="Admin"><id column="adminid" property="id"></id><result column="account" property="account"></result></resultMap><select id="findadmin" resultMap="adminMap">select id adminid ,account from admin</select>
#{} 和${}区别

#{} 占位符,是经过预编译的,编译好 SQL 语句再取值,#方式能够防止 sql 注入

#{}:delete from admin where id=#{id}

结果: delete from admin where id = ?

${}会将将值以字符串形式拼接到 sql 语句,

${ }方式无法防止 Sql 注入 ${}: delete from admin where id=’${id}’

结果: delete from admin where id=’1’ 一般是#{ } 向 sql 传值使用, 而使用${ }向 sql 传列名

 <select id="login1" resultType="Admin">select * from admin where account=#{account} and password =#{password}</select><select id="findbyid" parameterType="java.lang.String" resultType="java.lang.Integer">select id from admin where account = ${account}</select>
#{}  是占位符,是采用预编译方式向sql中传值,可以防止sql注入,如果我们往sql中传值,使用#{}${} 是将内容直接拼接到sql语句中,一般不用于向sql中传值,一般用于向sql动态传递列名区别:底层实现不同#{} 采用预编译方式,防止sql注入更加安全${} 采用字符串拼接,直接将值拼接到sql中使用场景不同#{}一般用于向sql中列传值${}一般用于向sql动态传递列 例如 排序时 order by 后面的列名是可以改变的
特殊处理定义 resultMap

(1). resutlMap 的 id 属性是 resutlMap 的唯一标识,本例中定义为 “adminResultMap”

(2). resutlMap 的 type 属性是映射的 POJO 类型

(3). id 标签映射主键,result 标签映射非主键

(4). property 设置对象属性名称,column 映射查询结果的列名称 

 多表关联处理结果集

resultMap 元素中 association , collection 元素. Collection 关联元素处理一对多关联

 

public class Student {private int id;private String name;private int num;private  String gender;private int majorid;private  Major major;
}
--------------------------------------
public class Major {private  int id;private String name;private List<Student> students;
}
-------------------------------------<resultMap id="studentMap" type="Student"><id column="id" property="id"></id><result column="num" property="num"></result><result column="name" property="name"></result><result column="gender" property="gender"></result><!--映射关联数据 专业名称--><association property="major" javaType="Major"><result column="mname" property="name"></result></association></resultMap><select id="findStudentbyid" resultMap="studentMap">select s.id,s.num,s.name,s.gender,m.name mnamefrom student s inner join major m on s.majorid=m.id where s.id =#{id}</select><select id="findStudents" resultMap="studentMap">select s.id,s.num,s.name,s.gender,m.name mnamefrom student s inner join major m on s.majorid=m.id </select>
<resultMap id="majorMap" type="Major"><id column="id" property="id"></id><result column="name" property="name"></result><collection property="students" javaType="list" ofType="Student"><result column="num" property="num"></result><result column="sname" property="name"></result></collection>
</resultMap><select id="findmajorbyid" parameterType="int" resultMap="majorMap">select m.id,m.name,s.num,s.name snamefrom major m inner join student s on m.id =s.majorid where m.id=#{id}</select><select id="findmajorall" parameterType="int" resultMap="majorMap">select m.id,m.name,s.num,s.name snamefrom major m inner join student s on m.id =s.majorid</select>
嵌套查询

将一个多表关联查询拆分为多次查询,先查询主表数据,然后查询关联表数据.

(1). select:指定关联查询对象的 Mapper Statement ID 为 findDeptByID

(2). column="dept_id":关联查询时将 dept_id 列的值传入 findDeptByID, 并将 findDeptByID 查询的结果映射到 Emp 的 dept 属性中

(3).collection 和 association 都需要配置 select 和 column 属性,两者配置方法 相同 

 <!--=============================================================关联查询方式2:嵌套查询  先查询主表(学生表)--><resultMap id="studentMap1" type="Student"><id column="id" property="id"></id><result column="num" property="num"></result><result column="name" property="name"></result><result column="gender" property="gender"></result><association property="major" javaType="Major" select="findmajorid" column="majorid"></association></resultMap><select id="findbuid" resultMap="studentMap1">select id,num,name,gender,majorid from student where id=#{id} ;</select><!--嵌套查询学生关联专业--><select id="findmajorid" resultType="Major">select name from major where  id=#{majorid}</select>

 

  <resultMap id="majorMap1" type="Major"><id column="id" property="id"></id><result column="name" property="name"></result><collection property="students" javaType="list" ofType="Student" select="findStudents" column="id"></collection></resultMap><select id="findmajor" resultMap="majorMap1">select id,name from major</select><select id="findStudents" resultType="Student">select num,name from student where majorid =#{id}</select>
Mybatis 动态 SQL

MyBatis 的一个强大的特性之一通常是它的动态 SQL 能力。

如果你有使用 JDBC 或其他 相似框架的经验,你就明白条件地串联 SQL 字符串在一起是多么 的痛苦,确保不能忘了空格或在列表的最后省略逗号。

动态 SQL 可以彻底处理 这种痛苦。

MyBatis 中用于实现动态 SQL 的元素主要有:

If wheretrim set choose (when, otherwise) foreach 

<?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.wph.mybatis.dao.TeacherDao"><!--动态sql中添加逻辑判断可以在sql中添加逻辑判断if  test 属性条件成立 执行if 标签体,不成立就不执行where 标签 当where标签 if 语句有条件成立时,就会动态添加where关键字,还可以删除where后面紧跟着的关键字--><!--  <select id="teachers" resultType="Teacher">select * from teacher<where><if test="num!=null">num = #{num}</if><if test="name!=null">and name=#{name}</if><if test="gender!=null">and gender=#{gender}</if></where></select>--><select id="teachers" resultType="Teacher">select * from teacher<trim prefix="where" prefixOverrides="and|or"><choose><when test="name!=null">name =#{name}</when><otherwise>name='王老师'</otherwise></choose></trim></select><select id="findTeacher" resultType="Teacher">select<foreach item="col" collection="list" separator=",">${col}</foreach>from teacher</select><update id="updateTeacher" parameterType="Teacher">update teacher<set><if test="num!=null">num=#{num},</if><if test="name!=null">name=#{name},</if><if test="gender!=null">gender =#{gender}</if></set>where id=#{id}</update><delete id="deleteTeacher">delete from teacher where id in<foreach item="id" collection="array" open="(" separator="," close=")">${col}</foreach>from teacher</delete></mapper>

If 元素

if 标签可以对传入的条件进行判断

<where>元素会进行判断,如果它包含的标签中有返回值的话,它就插入一个 ‘where’。

此外,如果标签返回的内容是以 AND 或 OR 开头,它会剔除掉 AND 或 OR。

trim 元素 where 标签,其实用 trim 也可以表示,当 WHERE 后紧随 AND 或则 OR 的时候,就去除 AND 或者 OR。prefix 前缀,prefixOverrides 覆盖首部指定 内容

Set 元素可以把最后一个逗号去掉

• foreach 元素

主要用在构建 in 条件中,它可以在 SQL 语句中进行迭代一个集合。foreach 元素的属性主要有 item,index,collection,open,separator,close。

item 表示集合中每一个元素进行迭代时的别名,index 指定一个名字,用于 表示在迭代过程中,每次迭代到的位置,open 表示该语句以什么开始, separator 表示在每次进行迭代之间以什么符号作为分隔符,close 表示以什 么结束,在使用 foreach 的时候最关键的也是最容易出错的就是 collection 属性,该属性是必须指定的,但是在不同情况下,该属性的值是不一样的。 – 如果传入的是单参数且参数类型是一个 List 的时候,collection 属 性值为 list – 如果传入的是单参数且参数类型是一个 array 数组的时候, collection 的属性值为 array

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com