在JAVA中Mybatis的使用
1 配置依赖项
依赖包:
通过网盘分享的文件:mybatis
链接: https://pan.baidu.com/s/1sNp-R8wcfr3YbjenvOFeJQ?pwd=vy28 提取码: vy28
略
2 准备所需要的文件,放在src目录底下
<?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><!-- 和spring整合后 environments配置将废除 --><environments default="development"><environment id="development"><!-- 使用jdbc事务管理 --><transactionManager type="JDBC" /><!-- 数据库连接池 --><dataSource type="POOLED"><property name="driver" value="com.mysql.cj.jdbc.Driver" /><property name="url"value="jdbc:mysql://localhost:3306/haha?serverTimezone=UTC" /><property name="username" value="root" /><property name="password" value="123456" /></dataSource></environment></environments><!-- 注册sqlMapper--><mappers><mapper resource="com/apesource/mybatisStudy/mapper/StudentMapper.xml"></mapper></mappers>
</configuration>
3 准备包,这里博主准备了以下几个包,大家可以根据自己的需求进行准备
4 dao层内容(这也是第一步需要做的事)
public class DaoUtil {protected static SqlSessionFactory factory;static {//1.读取配置文件InputStream inputStream= null;try {inputStream = Resources.getResourceAsStream("mybatis-config.xml");} catch (IOException e) {throw new RuntimeException(e);}//2.创建工厂factory=new SqlSessionFactoryBuilder().build(inputStream);}protected static SqlSession getSqlSession() {return factory.openSession();}protected static void close(SqlSession sqlSession){if(sqlSession!=null){sqlSession.close();}}
}
在mybatis中,根目录是src目录,所以大家不用写文件地址,直接写文件名称即可
准备接口
public interface IStudentDao {//新增int addStudent(Student student);//修改int updateStudent(Student student);//删除int deleteStudent(int sid);//查询//根据学生编号查询Student getStudentBySid(int sid);//全查List<Student> getAllStudents();}
接口实现(这里我写在了impl包底下)
public class StudentDaoImpl extends DaoUtil implements IStudentDao {private static SqlSession sqlSession;@Overridepublic int addStudent(Student student) {sqlSession=getSqlSession();int res;res= sqlSession.insert("registerStudent",student);if(res>0){sqlSession.commit();}return res;}@Overridepublic int updateStudent(Student student) {sqlSession=getSqlSession();int res;res=sqlSession.update("updateStudentBySid",student);if(res>0){sqlSession.commit();}return res;}@Overridepublic int deleteStudent(int sid) {sqlSession=getSqlSession();int res;res=sqlSession.delete("deleteStudentBySid",sid);if(res>0){sqlSession.commit();}return res;}@Overridepublic Student getStudentBySid(int sid) {sqlSession=getSqlSession();Student student;student=sqlSession.selectOne("selectStudentBySid",sid);sqlSession.close();return student;}@Overridepublic List<Student> getAllStudents() {sqlSession=getSqlSession();List<Student> studentList=sqlSession.selectList("selectAllStudent");close(sqlSession);return studentList;}
}
因为mybatis的底层是JDBC,所以需要准备sqlsession对象,并且执行sql语句都有自己所对应的方法,这里就需要大家记住喽,其中,查询一条语句与查询多条语句的方法是不同的。
在这里本来要写方法所对应的地址,但由于我在mybatis.xml文件中已经配置过了,所以这里可以直接写方法名
5 mapper层(该层是mybatis的核心)
在该层中,需要进行sql语句的映射,这时就需要进行编写.xml文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="test">
<!-- 查询--><select id="selectAllStudent" resultType="com.apesource.mybatisStudy.bean.Student">select * from student</select><select id="selectStudentBySid" parameterType="int" resultType="com.apesource.mybatisStudy.bean.Student">select * from student where sid=#{id}</select><!-- 删除--><delete id="deleteStudentBySid" parameterType="int">delete from student where sid=#{id}</delete><!-- 新增--><insert id="registerStudent" parameterType="com.apesource.mybatisStudy.bean.Student">insert into student(sname,birthday,ssex,classid) values (#{sname},#{birthday},#{ssex},#{classid})</insert><!-- 修改--><update id="updateStudentBySid" parameterType="com.apesource.mybatisStudy.bean.Student">update student set sname=#{sname},birthday=#{birthday},ssex=#{ssex},classid=#{classid} where sid=#{sid}</update></mapper>
以上写法大家会发现写起来很麻烦,那可以简化一下吗?有的兄弟,有的
我们可以删除impl包底下的所有文件,并将mapper包底下的xml文件中的mapper标签中的namespace属性进行传参,在里面写mapper接口,并将mapper接口也放在mapper包底下,并把他们的名称修改相同。
6 对数据库信息进行加密
大家会发现,我们的所有数据库信息都是明文的,这对于程序来说是绝对不允许的,那我们应该如何加密呢?
<properties>元素配置外部文件
在这里,我们可以使用<properties>标签去配置数据库信息,具体来说,就是将数据库信息放入.properties文件中,并在.xml文件中进行配置
jdbc.properties文件
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/haha?serverTimezone=GMT
jdbc.username=root
jdbc.password=123456
mybatis-config.xml文件
7 select标签
id属性,唯一标识,调用sql语句也是根据这个属性进行调用的
resultType属性,结果的类型,可以填写实体类或八大数据类型
parameterType属性,传入参数的类型,也可以写实体类
resultMap属性,结果集映射,用来处理多表查询或者实体类属性与字段名不一致的问题
id属性:唯一标识
id与result标签:id标识该字段是主键,如果字段名与实体类属性不一致,则将每一个对应不上的字段进行编写,column属性写字段名,property写实体类属性,这样就可以一一对应了
association:用来处理一对一关系,涉及到多表查询,select属性表示要通过那个sqlMapper映射语句去查询
collection:用来处理一对多的关系,与association标签一样,都有select属性。
<resultMap id="class_stu_map" type="banji"><id column="classid" property="classid"/><result column="classname" property="classname"/><!--处理1 : N关系--><collection property="stuList" ofType="student"><id column="sid" property="sid"/><result column="sname" property="sname"/><result column="birthday" property="birthday"/><result column="ssex" property="ssex"/><result column="classid" property="classid"/></collection></resultMap><select id="selectBanjis" resultMap="class_stu_map">select * from class left join student on student.classid=class.classid</select>
8 insert标签
useGeneratedKeys :开启主键回填(默认为false)
keyProperty : 入参的属性名
<insert id="addStudent" parameterType="student" useGeneratedKeys="true" keyProperty="sid" >insert into student(sname,birthday,ssex,classid) values (#{sname},#{birthday},#{ssex},#{classid})</insert>
由于Mybatis的底层是JDBC,所以在修改表之后需要进行事务的提交(默认回滚),而主键回填在提交事务之前就可以获取到主键了
9 多参传递
9.1 使用map集合传参
<select id="getStudentByPage" parameterType="map" resultType="student">select * from student limit #{curpage} , #{pagesize}</select>
在里面写key就可以映射到对应的value值
9.2 使用param传参
<select id="getStudentBySexPage" resultType="student">select * from student where ssex=#{param1} limit #{param2},#{param3}</select>
param后有编号 从1开始 param1,param2,...paramn
9.3 使用arg传参
<select id="getStudentByClassidPage" resultType="student">select * from student where classid=#{arg0} limit #{arg1},#{arg2}</select>
arg 后有编号 从0开始 arg0,arg1,arg2,...argn 一般不推荐这种写法
10 动态SQl
如果sql语句需要我们一条一条的编写,那么毫无疑问,这是个巨大的工作量,因此我们可以使用动态sql简化我们的工作量
这里的所有内容都是对sql语句的拼接
10.1 if标签
<select id="getAllStudents" resultType="student" parameterType="student">select * from student<if test="ssex != null">ssex=#{ssex} and</if><if test="classid != 0">classid=#{classid} and</if>1=1
</select>
test属性里面写布尔表达式,相当于JAVA中的if语句
10.2 where标签
<select id="getAllStudents" resultType="student" parameterType="student">select<include refid="stuSql"></include>from student<where><if test="ssex != null">and ssex=#{ssex}</if><if test="classid != 0">and classid=#{classid}</if></where></select>
1.当where标签中有内容时,添加一个where关键词
当where标签中没有内容时,不添加一个where关键词
2.去除紧跟在where关键字后面的and或or这样的连接符
这个标签可以防止sql注入以及sql语句错误问题
10.3 set标签
<update id="updateStudent" parameterType="student">update student<set><if test="sname!=null">sname=#{sname} ,</if><if test="birthday!=null">birthday=#{birthday} ,</if><if test="ssex!=null">ssex=#{ssex} ,</if><if test="classid!=0">classid=#{classid} ,</if></set>where sid=#{sid}</update>
set 标签会自动添加一个set关键词,并将最后一个','去掉
10.4 trim标签
<select id="getStudentTrim" parameterType="student" resultType="student">select <include refid="stuSql"></include> from student<trim prefix=" where " prefixOverrides="and"><if test="ssex != null">and ssex=#{ssex}</if><if test="classid != 0">and classid=#{classid}</if></trim></select>
trim 万能标签
prefix 开始之前添加一个什么
prefixOverrides 开始之前去掉一个什么
suffix 结束之前添加一个什么
suffixOverrides 结束之前去掉一个什么
10.5 foreach标签
<select id="getStudentByArr" resultType="student">select * from student<where>sid in<foreach collection="Array" item="x" open="(" separator="," close=")">#{x}</foreach></where></select>
改标签是一个循环遍历标签,其中item表示接收遍历元素的值,open表示以什么开始,separator表示以什么分割,close表示以什么结束