框架:软件开发中的一套解决方案,不一样的框架解决不一样的问题。java
框架的好处:框架封装了不少的细节,使开发者可使用极简的方式实现功能,提升开发的效率mysql
三层架构:程序员
一、表现层:用于展现数据sql
二、业务层:用于处理业务需求数据库
三、持久层:用于和数据库交互缓存
持久层技术解决方案:tomcat
一、JDBC技术:Connection;PreparedStatement;ResultSet,三个对象服务器
二、Spring的JdbcTemplate:对jdbc的简单封装session
三、Apache的DBUtils:对jdbc的简单封装mybatis
缺点:操做繁琐
Mybatis概述:Mybatis是一个优秀的基于java的持久层框架,它内部封装了jdbc,使开发者只须要关注sql语句自己,而不须要花费精力去处理加载驱动,建立链接,建立statement等繁杂的过程。
Mybatis的入门:
一、mybatis的环境搭建:
一、建立maven工程并导入jar包
若是使用maven建立工程,能够导入下面坐标:
<dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>x.x.x</version> </dependency>
二、建立实体类和dao接口
三、建立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"> <!-- mybatis的主配置文件--> <configuration> <!-- 配置环境--> <environments default="mysql"> <!--配置mysql的环境--> <environment id="mysql"> <!--配置事务的类型--> <transactionManager type="JDBC"></transactionManager> <!--配置数据源(链接池)--> <dataSource type="POOLED"> <!--配置链接数据的4个基本信息--> <property name="driver" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/eesy"/> <property name="username" value="root"/> <property name="password" value="111111"/> </dataSource> </environment> </environments> <!--指定映射配置文件的位置,映射配置文件指的是每一个dao独立的配置文件--> <mappers> <mapper resource="lianbang/wu/IUserDao.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 ="lianbang.wu.dao.IUserDao"> <!--配置查询全部--> <select id="findAll"> select * from user; </select> </mapper>
注意:映射配置文件和对应的接口包结构要相同;
使用步骤:
public class MybatisTest { public static void main(String[] args) throws IOException { //一、读取配置文件 InputStream in = Resources.getResourceAsStream("sqlMapConfig.xml"); //二、建立sqlSessionFactory工厂 SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder(); SqlSessionFactory factory = builder.build(in); //三、使用工厂生产sqlSession对象 SqlSession session = factory.openSession(); //四、使用sqlSession建立dao接口的代理对象 IUserDao userDao = session.getMapper(IUserDao.class); //五、使用代理对象执行方法 List<User> users = userDao.findAll(); for (User user : users){ System.out.println(user); } //六、释放资源 session.close(); in.close(); } }
Mybatis基于注解的使用:
删除映射xml文件,直接在dao接口的方法上使用@Select注解,而且指定SQL语句,同时须要在主配置文件中的mapper配置时,使用class属性指定dao接口的全限定类名。
<mappers> <mapper class="lianbang.wu.dao.IUserDao"/> </mappers>
注意:当实体类和数据库列名不一致时,须要在映射文件中进行对象映射
<resultMap id="userResultMap" type="User"> <id property="id" column="user_id" /> <result property="username" column="username"/> <result property="password" column="password"/> </resultMap>
Mybatis的CURD:
一、保存数据
映射文件:
<!--保存用户--> <insert id="saveUser" parameterType="lianbang.wu.domain.User"> insert into user (username,address,sex,birthday) value (#{username},#{address},#{sex},#{birthday}) </insert>
测试代码:
public void testSave() throws IOException { User user = new User(); user.setUsername("mybatis"); user.setAddress("杭州西湖"); user.setSex("男"); user.setBirthday(new Date()); //一、读取配置文件 InputStream in = Resources.getResourceAsStream("sqlMapConfig.xml"); //二、建立sqlSessionFactory工厂 SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder(); SqlSessionFactory factory = builder.build(in); //三、使用工厂生产sqlSession对象 SqlSession session = factory.openSession(); //四、使用sqlSession建立dao接口的代理对象 IUserDao userDao = session.getMapper(IUserDao.class); //五、使用代理对象执行方法 userDao.saveUser(user); session.commit(); //六、释放资源 session.close(); in.close(); }
二、修改数据
映射文件:
<!--更新用户--> <update id="updateUser" parameterType="lianbang.wu.domain.User"> update user set username=#{username},address=#{address},sex=#{sex},birthday=#{birthday} where id=#{id}; </update>
测试代码:
public void testUpdate() throws IOException { User user = new User(); user.setId(51); user.setUsername("mybatis_update"); user.setAddress("杭州西湖"); user.setSex("男"); user.setBirthday(new Date()); //一、读取配置文件 InputStream in = Resources.getResourceAsStream("sqlMapConfig.xml"); //二、建立sqlSessionFactory工厂 SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder(); SqlSessionFactory factory = builder.build(in); //三、使用工厂生产sqlSession对象 SqlSession session = factory.openSession(); //四、使用sqlSession建立dao接口的代理对象 IUserDao userDao = session.getMapper(IUserDao.class); //五、使用代理对象执行方法 userDao.updateUser(user); session.commit(); //六、释放资源 session.close(); in.close(); }
三、删除数据
映射文件:
<!--删除用户--> <delete id="deleteUser" parameterType="Integer"> delete from user where id=#{userid}; </delete>
测试代码:
public void testDelete() throws IOException { Integer uid = 51; //一、读取配置文件 InputStream in = Resources.getResourceAsStream("sqlMapConfig.xml"); //二、建立sqlSessionFactory工厂 SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder(); SqlSessionFactory factory = builder.build(in); //三、使用工厂生产sqlSession对象 SqlSession session = factory.openSession(); //四、使用sqlSession建立dao接口的代理对象 IUserDao userDao = session.getMapper(IUserDao.class); //五、使用代理对象执行方法 userDao.deleteUser(uid); session.commit(); //六、释放资源 session.close(); in.close(); }
Mybatis中的链接池:
Mybatis链接池提供了3种方式的配置:
主配置文件SqlMapConfig.xml中的dataSource标签,type属性就是表示采用何种链接池方式
type属性的取值:POOLED,采用传统的javax.sql.DataSource规范中的链接池,Mybatis中有针对规范的实现
UNPOOLED,采用传统的获取链接的方式,虽然也实现了实现了javax.sql.DataSource接口,可是并无使用池的思想
JNDI,采用服务器提供的JNDI技术实现,来获取DataSource对象,不一样的服务器所能拿到的DataSource是不同的
若是不是Web或者Maven的war工程,是不能使用的
使用tomcat服务器,采用的链接池就是dbcp链接池。
mybaits中的事务:
sqlsession的commit和rollback;
session.commit();
session.rollback();
mybaits中的动态sql语句:
if标签:
<select id="findByCondition" resultType="lianbang.wu.domain.User" parameterType="lianbang.wu.domain.User"> select * from user where 1=1 <if test="userName != null"> and username = #{userName} </if> </select>
where标签:
<select id="findByCondition" resultType="lianbang.wu.domain.User" parameterType="lianbang.wu.domain.User"> select * from user <where> <if test="userName != null"> and username = #{userName} </if> </where> </select>
foreach标签:
<select id="findByRange" parameterType="queryvo" resultType="lianbang.wu.domain.User"> select * from user <where> <if test="id!=null and ids.size()>0"> <foreach collection="ids" open="and id in (" close=")" item="id" separator=","> #{id} </foreach> </if> </where> </select>
sql标签:
<sql id="defauleUser"> select * from user </sql> <select id="findAll" resultType="lianbang.wu.domain.User"> <include refid="defaule"> </include>i </select>
trim标签
set标签
chose标签
Mybatis的多表查询
一对一的查询:
方法一:新建一个包含两个对象全部成员变量的实现类,将查询结果封装到里面
方法二:在其中一个对象中,添加另外一个对象到成员变量中。在映射文件中,对变量进行以下映射
<resultMap id="accountUserMap" type="lianbang.wu.domain.Account"> <id property="id" column="aid"></id> <result property="uid" column="uid"></result> <result property="money" column="money"></result> <association property="user" column="uid" javaType="lianbang.wu.domain.User"> <id property="id" column="id"></id> <result property="username" column="username"></result> <result property="address" column="address"></result> <result property="sex" column="sex"></result> <result property="birthday" column="birthday"></result> </association> </resultMap>
再将查询结果封装到对应的对象中。
一对多的查询:
<resultMap id="accountUserMap" type="lianbang.wu.domain.Account"> <id property="id" column="aid"></id> <result property="uid" column="uid"></result> <result property="money" column="money"></result> <collection property="emplist" ofType="lianbang.wu.domain.emp"> <id column="eid" property="id"></id> <result column="ename" property="name"></result> </collection> </resultMap>
多对多查询:
等同一对多
延迟加载:
概念:在真正使用数据的时才发起查询,不用的时候不查询,按需加载(懒加载),一般在一对多查询或多对多查询使用
当即加载:
概念:无论用不用,只要一调用方法,立刻发起查询,一般在一对对或多对多查询使用
实现步骤:
一、开启延迟加载:主配置文件中设置
<settings> <setting name="lazyLoadingEnable" value="true"/> <setting name="aggressiveLazyLoading" value="false"/> </settings>
二、设置延迟加载的ResultMap
<resultMap id="accountUserMaplazyLoad" type="lianbang.wu.domain.Account"> <id property="id" column="aid"></id> <result property="uid" column="uid"></result> <result property="money" column="money"></result> <collection property="emplist" ofType="lianbang.wu.domain.emp"> <id column="eid" property="id"></id> <result column="ename" property="name"></result> </collection> </resultMap>
三、延迟加载的mapper文件:
<select id="accountUserMapLazy" resultMap="accountUserMapLazyLoad"> select * from account </select> <select id ="findUser" parameterType="id" resultType="User"> select * from user where id = #{value} </select>
缓存:
概念:存在于内存中的临时数据
做用:减小和数据库的交互次数,提升执行效率
适用于:常常查询而且不常常改变的,数据的正确与否对最终结果影响不大的
不适用于:常常改变的数据,数据的正确与否对最终的结果影响很大的,例如:商品的库存,银行的汇率,股市的牌价
mybatis中的一级缓存:它指的是Mybatis中sqlSession对象的缓存,当咱们执行查询以后,查询的结果会同时存入到sqlSession为咱们提供的一块区域中,该区域的结构是一个Map,当咱们再次查询一样的数据,mybatis会先去sqlSession中查询是否有,有的话直接拿出来用,当sqlSession对象消失,mybatis的一级缓存也就消失了。
注意:当sqlSession执行修改,添加,删除,commit,close等方法时,就会清空一级缓存。
mybatis中的二级缓存:它指的是mybatis中的sqlSessionFactory对象的缓存。由同一个SqlSessionFactory对象建立的sqlSession共享其缓存。
二级缓存的使用步骤:
第一步:让mybatis框架支持二级缓存,在主配置文件中配置
<setting name ="cacheEnabled" value="true"/>
第二步:让当前的映射文件支持二级缓存
<cache></cache>
第三步:让当前的操做支持二级缓存
建立多个session对象。注意被实体类要实现序列化接口。
注解开发:
在mybatis中,针对CRUD一共有四种注解:@Select ,@Insert,@Update,@Delete
@Select("select * from user") @Results({ @Result(id = true,column ="id",property = "id"), @Result(column = "name", property = "name")}) List<User> findAll();
多表查询
一对一
@Select("select * from user") @Results({ @Result(id = true,column ="id",property = "id"), @Result(column = "name", property = "name"), @Result(column = "deptid",property = "dept",one=@One(select = "lianbang.wu.dao.IDeptDao.selectdetpBydi")) }) List<User> findAll();
一对多:
@Select("select * from user") @Results({ @Result(id = true,column ="id",property = "id"), @Result(column = "name", property = "name"), @Result(column = "deptid",property = "dept",many=@Many(select = "lianbang.wu.dao.IDeptDao.selectdetpBydi")) }) List<User> findAll();
二级缓存
@CacheNamespace(blocking = true)
补充:
#{}:表示一个占位符,向占位符输入参数,mybatis自动进行Java类型和jdbc类型转换。程序员不须要考虑参数的类型,好比:传入字符串,mybatis最终拼接好的sql就是参数两边加单引号,接受pojo数据,可使用OGNL解析出pojo的属性中
${}:表示sql拼接,将参数的内容不加任何修饰拼接到sql中,也能够接收pojo数据,使用OGNL解析出pojo的属性值,缺点不能防止sql注入