目前正在学习mybatis,学习mybatis最好的帮手就是他的官方网站https://mybatis.org/mybatis-3/zh,以及查看mybatis的官方源码,看源码能够很详细的了解mybatis到底是如何用于消除jdbc的连接代码,以及jdbc设置获取数据库中具体字段的值,返回的具体结果集都封装好了,我们只需要在全局映射文件中设置,当然全局映射文件的头部最好去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">
<?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="jdbc.props"></properties> <settings> <setting name="logImpl" value="LOG4J"/> <!-- <setting name="lazyLoadingEnabled" value="true"/> --> </settings> <typeAliases> <package name="org.lanqiao.mybatis01.entity"/> </typeAliases> <environments default="dev"> <environment id="dev"> <transactionManager type="JDBC"></transactionManager> <dataSource type="POOLED"> <property name="driver" value="${jdbc_driverClass}"/> <property name="url" value="${jdbc_url}"/> <property name="username" value="${jdbc_username}"/> <property name="password" value="${jdbc_password}"/> </dataSource> </environment> <environment id="test"> <transactionManager type="JDBC"></transactionManager> <dataSource type="POOLED"> <property name="driver" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://112.18.0.1:3306/test?useUnicode=true&characterEncoding=UTF-8"/> <property name="username" value="root"/> <property name="password" value="123"/> </dataSource> </environment> <environment id="pro"> <transactionManager type="JDBC"></transactionManager> <dataSource type="POOLED"> <property name="driver" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://112.181.10.51:3306/mybatis?useUnicode=true&characterEncoding=UTF-8"/> <property name="username" value="root"/> <property name="password" value="123"/> </dataSource> </environment> </environments> <mappers> <mapper resource="org/lanqiao/mapper/StudentMapper.xml"/> <mapper resource="org/lanqiao/mapper/SgroupMapper.xml"/> <mapper resource="org/lanqiao/mapper/CouresMapper.xml"/> </mappers> </configuration>
基本上就是一个dao层接口写一个mapper.xml映射文件,目前就体现出接口的用处了,在前一个电信资费实战项目中,一直以为接口没什么大的用处呢,原本在接口的实现类中的sql语句都写在它对应的映射文件中,下面就是上图中StudentMapper.xml中具体写的内容,主要还是对sql语句的书写,因此在开发之中一定要把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="org.lanqiao.mybatis01.dao.StudentDao"> <resultMap type="Student" id="studentResultMap"> <id property="sid" column="sid"/> <result property="sname" column="sname"/> <result property="sage" column="sage"/> <association property="sgroup" column="gid" select="org.lanqiao.mybatis01.dao.SgroupDao.selectSgroupByGid"></association> <collection property="lc" column="sid" select="org.lanqiao.mybatis01.dao.CouresDao.selectCouresBySid"></collection> </resultMap> <sql id="selectAllStudent">sid,sname,sage,gid</sql> <insert id="insertStudent"> insert into student values(null,#{sname},#{sage}) </insert> <delete id="deleteStudent"> delete from student where sid = #{sid} </delete> <select id="selectAllStudent" resultMap="studentResultMap"> select * from student </select> <select id="selectStudentByCount" resultType="Student" > select <include refid="selectAllStudent"/> from student <where> <if test="student.sid!=null"> and sid=#{student.sid} </if> <if test="student.sname!=''and student.sname!=null"> and sname like concat('%',concat(#{student.sname},'%')) </if> <if test="student.sage!=null"> and sage=#{student.sage} </if> </where> </select> <select id="selectStudentBySname" parameterType="string" resultType="Student"> select * from student group by ${fiel} desc </select> <select id="selectStudentBySids" resultType="Student"> select * from student where sid in <foreach collection="list" item="student" open="(" close=")" separator="," > #{student.sid} </foreach> </select> <insert id="insertStudents"> insert into student(sid,sname,sage) values <foreach collection="list" item="student" separator=","> (null,#{student.sname},#{student.sage}) </foreach> </insert> <delete id="deleteStudents"> delete from student where sid in <foreach collection="list" item="student" open="(" close=")" separator=","> #{student.sid} </foreach> </delete> <select id="selectStudentsBySid" resultMap="studentResultMap"> select <include refid="selectAllStudent"></include> from student where sid = #{sid} </select> <update id="updateStudentBySid"> update student set sname = #{student.sname} where sid = #{student.sid} </update> </mapper>
我对于${},#{}的理解是:前者取的是括号中的内容,会直接拼接到sql语句中,使用它可能会导致sql注入的问题,后者取的就是@Param(" ")中的名字推荐在接口中将需要的参数直接定义一个名字,这个问题在csdn有些文章讲得很详细,我受益非浅,我上班了一定要给csdn充一个会员才是,哈哈哈,随后学习了sql的动态拼接,一般传入的参数类型是集合才在sql语句中使用foreach标签,其实foreach标签用的也少,用的多的就是<where>,<if test="">,<chose><when>,随后学习了mybatis的缓存机制,mybatis有一级和二级缓存机制。
用通俗的话来讲,缓存就是,将从数据库中查询到的记录保存到内存之中然后下次查询相同的内容时直接将读取缓存中的数据,而不是去数据库中查询
mybatis中的一级缓存是默认开启的,他的使用范围是同一个sqlsession,可以通过三种方法来关闭mybatis的缓存,缓存可以通过创建两个sqlsession对象来模拟出效果,
二级缓存是通过在全局配置文件中设置<settings>开启,不过我查看mybatis的官方文档,发现他也是默认开启的,不过要想使用它,需要去具体的mapper.xml中使用<cache/>作用于一整个namespace的所有select语句之中,二级缓存使用的算法有两种一种是LUR算法(最近最少使用,将缓存中查到的数据放置链表的最后,如果缓存中的容量满了,就将最新插入的放置最后并且删除掉链表最前面的数据)另一种是FIFO算法,后续还学习了之前项目中非常麻烦的问题,即添加信息之后需要再查询一遍获取它自增ID的值的问题,只需要设置<insert>标签中的属性,id是指接口名,keyProperty是指主键名称,useGeneratedKeys是返回主键的信息
<insert id="insertStudent" keyProperty="sid" useGeneratedKeys="true">
static InputStream is; static SqlSession sqlSession; static SqlSession sqlSession2; static StudentDao studentDao; static StudentDao studentDao2; @BeforeClass public static void init() throws IOException { //第一步、把全局配置文件mybatis-config.xml读入流中 is = Resources.getResourceAsStream("mybatis01-conf.xml"); //第二步、通过流(全局配置文件)创建一个sqlsession的工厂构建器 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is); //第三步、通过sqlsession工厂,创建sqlsession对象 sqlSession = sqlSessionFactory.openSession(); sqlSession2 = sqlSessionFactory.openSession(); //第四步、通过sqlsession获取StudentDao的对象 studentDao = sqlSession.getMapper(StudentDao.class); studentDao2 = sqlSession2.getMapper(StudentDao.class); }
随后学习了用注解替换xml文件的方式直接在接口中使用注解,第一条学习结束,水了这么久第一天发scdn!!!!