Mybatis笔记

第三阶段框架部分:

1.持久层框架: mybatis(半自动 一般适用于大型项目), hibernate(全自动,适用于小型,简单项目) ,spring Data JPA,spring jdbcTemplate(不建议使用)

2.视图层框架: springMVC ,(strust2 淘汰了)

3.整合框架: spring ,springboot(分布式结构中的)

Mybatis框架:

1.什么是mybatis?

MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis 。2013年11月迁移到Github。MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Ordinary Java Object,普通的 Java对象)映射成数据库中的记录;

2.mybatis也有 优点 和 缺点:

优点: mybatis几乎避免了所有的 jdbc代码,能自动映射,让程序员把经历放在sql语句上;

​ 属于半自动的持久层框架,支持定制sql, 可以根据需求编写sql语句,也可以自动生成;

缺点: sql语句多,还是有缺陷;

3.mybatis开发有三种模式:

3.1 : Dao + DaoImpl (不常用)

3.1.2 : mybatis-config.xml
<?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>
    <!--  配置读取db.properteis的标签   -->
    <properties resource="db.properties"></properties>
    <!-- 开发环境  -->
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"></transactionManager>
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driver}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>
    </environments>
    <!-- 扫描映射器    -->
    <mappers>
        <mapper resource="com/oracle/pojo/User.xml"></mapper>
    </mappers>
</configuration>
3.1.3 : User.xml
<?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="haha">
    <select id="getUser" parameterType="string" resultType="com.oracle.pojo.User">
        select * from `user` where username = #{username} and `password` = #{password};
    </select>
    <select id="getOne" parameterType="java.lang.Integer" resultType="com.oracle.pojo.User">
        select * from `user` where uid = #{uid}
    </select>
</mapper>
3.1.4 : UserDao
public interface UserDao {
    //登录
    public User getUserByUsernameAndPassword(String username, String password)throws  Exception;

    public User getUserbyUid(Integer uid)throws  Exception;
}
3.1.5 : UserDaoImpl
public class UserDaoImpl  implements UserDao{
    @Override
  public User getUserByUsernameAndPassword(String username, String password) throws Exception{

        SqlSession sqlSession = SqlSessionUtil.getSqlSession();

        User user = new User();
        user.setUsername(username);
        user.setPassword(password);

        Object obj = sqlSession.selectOne("haha.getUser", user);

        //关闭资源
        SqlSessionUtil.close(sqlSession);

        return (User)obj;
    }

    @Override
    public User getUserbyUid(Integer uid) throws Exception {

        SqlSession sqlSession = SqlSessionUtil.getSqlSession();

        Object obj = sqlSession.selectOne("haha.getOne", uid);

        SqlSessionUtil.close(sqlSession);

        return (User)obj;
    }
}
3.1.6 : Test
public class TestMybatis {
    @Test
    public void test2() throws Exception {

        UserDao userDao = new UserDaoImpl();

        User user = userDao.getUserbyUid(2);

        System.out.println(user);
    }

    @Test
    public void test1() throws Exception {

        UserDao userDao = new UserDaoImpl();

        User user = userDao.getUserByUsernameAndPassword("张三", "123");

        System.out.println(user);
    }

}
3.1.7 : SqlSessionFactory封装
public class SqlSessionUtil {
	//初始化属性	
    private static SqlSession sqlSession = null;
    private static SqlSessionFactory sqlSessionFactory = null;

    //私有构造器
    private SqlSessionUtil(){}
	//静态块儿加载
    static{
        try {
            InputStream ips = Resources.getResourceAsStream("mybatis-config.xml");
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(ips);
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
	//静态方法获取sqlSession会话
    public static SqlSession getSqlSession(){
        if(sqlSession == null){
             sqlSession =   sqlSessionFactory.openSession();
        }
        return sqlSession;
    }
	//关闭资源
    public static void close(SqlSession sqlSession){
        if(sqlSession != null){
            sqlSession.close();
        }
    }
}
3.2.1 : 增删改查操作
3.2.1.1 添加
 UserDao:
 public int insertUser(User user)throws  Exception;

 UserDaoImpl:
 @Override
    public int insertUser(User user) throws Exception {
        SqlSession sqlSession = SqlSessionUtil.getSqlSession();
        int a = sqlSession.insert("user.insertUser", user);
        //手动提交
        sqlSession.commit();
        //关闭资源
        SqlSessionUtil.close(sqlSession);
        return a;
    }
<insert id="insertUser">
        insert into `user`(uid,username,password,address)
             values(null,#{username},#{password},#{address})
</insert>
3.2.1.2 修改
UserDao:
public int updateUserById(User user)throws Exception;

UserDaoImpl:
@Override
public int updateUserById(User user) throws Exception {
  SqlSession sqlSession = SqlSessionUtil.getSqlSession();

  int a = sqlSession.update("user.updateUserByUid", user);
  //手动提交
  sqlSession.commit();

  SqlSessionUtil.close(sqlSession);

  return a;
}
<update id="updateUserByUid">
        update `user` set 
  		    username = #{username} , `password` = #{password} , address = #{address}
                where uid = #{uid}
</update>
3.2.1.3 删除
UserDao:
public int deleteUserById(Integer id)throws Exception;

UserDaoImpl:
@Override
public int deleteUserById(Integer id) throws Exception {
  SqlSession sqlSession = SqlSessionUtil.getSqlSession();

  int a = sqlSession.delete("user.deleteUserByUid", id);
  //手动提交
  sqlSession.commit();

  SqlSessionUtil.close(sqlSession);

  return a;
}
<delete id="deleteUserByUid">
        delete from `user` where uid = #{uid}
</delete>
3.2.1.4 分页查询
UserDao:
public List<User> getUserByLimit(Map<String,Integer> map)throws  Exception;

UserDaoImpl:
@Override
public List<User> getUserByLimit(Map<String,Integer> map) throws Exception {

 SqlSession sqlSession = SqlSessionUtil.getSqlSession();

 List<User> list = sqlSession.selectList("user.getUserByLimit", map);

 return list;
}
<select id="getUserByLimit" resultType="user">

        select * from `user` limit #{startRow},#{pageSize}

</select>

测试类:

@Test
public void test7() throws Exception {
  Map<String,Integer> map = new HashMap<>();
  Integer pageNo = 2;
  Integer pageSize = 5;
  //map集合的key 是 #{名} value是具体值
  map.put("startRow",(pageNo-1)*pageSize);
  map.put("pageSize",pageSize);
  List<User> list = userDao.getUserByLimit(map);
  for (User user : list) {
    System.out.println(user);
  }
}

3.2 : mapper动态代理开发 (重点)

什么是代理模式?

用大白话解释就是 我们不自己干活了(编写DaoImpl实现类),让mybatis帮我们干活就行; 那么mybatis就是一个代理商,帮我们完成具体实现,体现在代码上就是以后没有 daoImpl实现类,只有Dao存在

但是使用代理模式必须满足4个条件:

1.Dao中的方法名 必须 和 select标签,update,delete,insert标签的 id 一致;

2.mapper标签的namespace的值必须是 接口的 全路径名

<mapper namespace="com.oracle.mapper.UserMapper"></mapper>

3.dao方法中的入参的类型必须和 select ,update,delete,insert标签的 parameterType类型一致

4.dao方法中的返回值类型,必须和 select 标签的resultType类型一致

3.2.1: 代码案例:
public interface UserMapper {
    //模糊查询带分页
  public List<User> getUserByLikeWithLimit(@Param("like") String like ,
                                             @Param("startRow") Integer startRow,
                                             @Param("pageSize") Integer pageSize);
    //模拟登录
    public User getUserByUserNameAndPassword(@Param("username") String username,
                                             @Param("password") String password);
    //根据id查询
    public User getUserByUid(Integer uid)throws  Exception;
    ;
    //根据id删除
    public int deleteUserByUid(Integer uid)throws Exception;

    //根据id修改
    public int updateUserByUid(User user)throws Exception;
    
    //插入
    public int insertUser(User user)throws Exception;

    //模糊查询
    public List<User> getUserByLike(String like)throws Exception;

}
<?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">
 <!--  namespace命名空间一定是 与 接口全路径名一致 -->
<mapper namespace="com.oracle.mapper.UserMapper">
  	<!-- id属性的值 一定与 接口中的方法名一致 -->
    <select id="getUserByUserNameAndPassword" resultType="user">
        select * from `user` where username = #{username} and `password` = #{password}
    </select>

    <delete id="deleteUserByUid">
         delete from `user` where uid = #{uid}
    </delete>

    <select id="getUserByLike" resultType="user">
        select * from `user` where username like concat('%',#{like},'%')
    </select>

    <select id="getUserByLikeWithLimit" resultType="user">
        select * from `user` where username like concat('%',#{like},'%')
             limit #{startRow},#{pageSize}
    </select>
</mapper>
public class TestUserMapper {
    /**
     * 模糊查询带分页  单元测试
     * @throws Exception
     */
    @Test
    public void test5() throws Exception {
        SqlSession sqlSession = SqlSessionUtil.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        //调用自己的方法
        int startRow = (2-1)*2;
        List<User> list = mapper.getUserByLikeWithLimit("张",startRow,2);
        for (User user : list) {
            System.out.println(user);
        }
        sqlSession.close();
    }
}	
3.2.2 : 动态sql
查询案例: sql的字段片段
<sql id="userColumns">
        uid,username,`password`,address
</sql>
修改:
 <update id="updateUserByUid">
        update `user`
          <set>
              <if test=" username != null and username != ''">
                  username = #{username},
              </if>
              <if test=" password != null and password != ''">
                  `password` = #{password},
              </if>
              <if test=" address != null and address != ''">
                  address = #{address}
              </if>
          </set>
          <where>
              uid =#{uid}
          </where>
    </update>
查询语句的动态sql:
 <select id="getUserByLikeWithLimit" resultType="user">
        select
        <include refid="userColumns"></include>
         from `user`
            <where>
                <if test=" like != null and like != '' ">
                    username like concat('%',#{like},'%')
                </if>
            </where>
            <if test="startRow !=null">
                limit #{startRow},#{pageSize}
            </if>
 </select>
3.2.3 : 批量删除
 //批量删除
 public int deletesByUids(int[] ids)throws Exception;
<!--批量删除-->
<delete id="deletesByUids">
  delete from `user`
    <where>
      uid in
      <foreach item="a" collection="array" open="(" close=")" separator=",">
        #{a}
      </foreach>
    </where>
</delete>
3.2.4 : 主键回填
<insert id="insertUser" useGeneratedKeys="true" keyProperty="uid" >
  <!--
    主键回填技术 这个只适用于 mysql ,如果是oracle数据库就使用
			(useGeneratedKeys="true" keyProperty="uid")
        <selectKey keyProperty="uid" order="AFTER" resultType="int">
            select LAST_INSERT_ID();
        </selectKey>
        -->

        insert into `user`(uid,username,`password`,address) values(null,#{username},#{password},#{address})

    </insert>
@Test
public void test8() throws Exception {
  SqlSession sqlSession = SqlSessionUtil.getSqlSession();
  UserMapper mapper = sqlSession.getMapper(UserMapper.class);

  User user = new User();
  user.setUsername("呵呵");
  user.setPassword("123123");
  user.setAddress("上海");

  mapper.insertUser(user);
  //在插入成功后 获取 对象的 uid值  这里体现了 主键回填技术
  System.out.println(user.getUid());

  sqlSession.commit();

  sqlSession.close();
}
3.3.1 : ResultMap标签
作用1:如果数据库表的字段名和 java实体属性名 不一致 就需要通过resultMap标签来手动映射
<resultMap id="userResultMap" type="user">
         <!--代表了当前表的 主键
             column:代表的数据库表的字段名
             property: 代表的是java类中的属性名
             javaType: 是java类型的全路径名
             jdbcType: 数据库的数据类型 ,必须大写字母
          -->
         <id column="uid" property="id" javaType="java.lang.Integer" jdbcType="INTEGER"></id>
         <!--其他字段-->
         <result column="username" property="name"></result>
         <result column="password" property="pwd"></result>
</resultMap>
<select id="getUserByUserNameAndPassword" resultMap="userResultMap">
        select
        <include refid="userColumns"></include>
        from `user`
        <where>
            <if test="username != null and username != ''">
                and username =#{username}
            </if>
            <if test="password != null and password != ''">
                and password = #{password}
            </if>
        </where>
 </select>
作用2: 级联查询(表关联查询)
一对一查询:

mapper接口:

public interface CardMapper {

    public Card getUserByCode(String code)throws  Exception;

}

CardMapper.xml:

<resultMap id="cardResultMap" type="card">
        <id column="cid" property="cid"></id>
        <result column="number" property="number"></result>
        <result column="uid" property="uid"></result>
        <!--user 跟car但是 一对一
                 property属性代表   Card实体类中的 user属性名
                 column代表card表的 外键字段
                 select 去另一个空间做另一个表的查询操作,好处解耦
         -->
        <association property="user" column="uid" 
                     select="com.oracle.mapper.UserMapper.getUserByUid">
        </association>
</resultMap>

<!--如果你不会写多表查询的时候 -->
<select id="getUserByCode" resultMap="cardResultMap">
  select cid,number,uid from card where number = #{number}
</select>

UserMapper.xml:

<mapper namespace="com.oracle.mapper.UserMapper">
  <!--这个标签 是为了 级联查询的 -->
  <select id="getUserByUid" resultMap="userResultMap">
    select * from `user` where uid = #{uid}
  </select>
</mapper>

单元测试:

@Test
public void test() throws Exception {

  SqlSession sqlSession = SqlSessionUtil.getSqlSession();

  CardMapper mapper = sqlSession.getMapper(CardMapper.class);

  Card card = mapper.getUserByCode("110");

  System.out.println(card);

  User user = card.getUser();

  System.out.println(user);

}
一对多级联查询:

UserMapper:

 //根据用户id 查询订单
public User getOrdersByUid(Integer uid)throws Exception;

UserMapper.xml

<mapper namespace="com.oracle.mapper.UserMapper">
<resultMap id="userResultMap" type="user">
         <!--代表了当前表的 主键
             column:代表的数据库表的字段名
             property: 代表的是java类中的属性名
             javaType: 是java类型的全路径名
             jdbcType: 数据库的数据类型 ,必须大写字母
          -->
         <id column="uid" property="id" javaType="java.lang.Integer" jdbcType="INTEGER"></id>
         <!--其他字段-->
         <result column="username" property="name"></result>
         <result column="password" property="pwd"></result>

         <!--多方 orders
            propertyL: user实体类中的 orders 属性名
            column: 当前uid主键 是 order表的外键
            ofType: User实体类中集合的泛型 order类型

         -->
         <collection property="orders" column="uid" ofType="order"
                        select="com.oracle.mapper.OrderMapper.getOrdersByUid">

         </collection>
 </resultMap>

    <!-- 根据 用户 uid 查询所有 订单  -->
    <select id="getOrdersByUid" resultMap="userResultMap">
        select * from `user` where uid = #{uid}
    </select>
</mapper>

OrderMapper.xml

<select id="getOrdersByUid" resultType="order">
  	select * from `order` where uid = #{uid}
</select>

测试类:

 @Test
public void test9() throws Exception {
  SqlSession sqlSession = SqlSessionUtil.getSqlSession();
  UserMapper mapper = sqlSession.getMapper(UserMapper.class);

  User user = mapper.getOrdersByUid(14);

  List<Order> orders = user.getOrders();

  for (Order order : orders) {
    System.out.println(order);
  }
}
根据订单编号找人:

OrderMapper接口:

public interface OrderMapper {
    //根据订单找人
    public Order getUserByCode(String code)throws  Exception;

}

OrderMapper.xml

<mapper namespace="com.oracle.mapper.OrderMapper">
    <resultMap id="orderResultMap" type="order">
        <!--user 的 一方-->
        <association property="user" column="uid"
                     select="com.oracle.mapper.UserMapper.getUserByUid">
        </association>
    </resultMap>
    <select id="getOrdersByUid" resultType="order">
        select * from `order` where uid = #{uid}
    </select>
</mapper>

UserMapper.xml

<mapper namespace="com.oracle.mapper.UserMapper">
	<!--这个标签 是为了 级联查询的 -->
    <select id="getUserByUid" resultMap="userResultMap">
          select * from `user` where uid = #{uid}
    </select>
</mapper>

测试类:

@Test
public void test1() throws Exception {
1
  SqlSession sqlSession = SqlSessionUtil.getSqlSession();

  OrderMapper orderMapper = sqlSession.getMapper(OrderMapper.class);

  Order order = orderMapper.getUserByCode("DFJ23");

  User user = order.getUser();

  System.out.println(user);

}

3.3 : 注解开发(不太推荐)

public interface UserMapper {

@Select("select * from `user` where username =#{username} and password = #{password}")
  public User getUserByUserNameAndPassword(@Param("username") String username,
                                           @Param("password") String password)throws Exception;

@Insert("insert into user(uid,username,password,address) values(null,#{username},#{password},#{address})")
  @SelectKey(statement = "select LAST_INSERT_ID()",keyProperty="nameId", before=true, resultType=int.class)
  public void insertUser(User user)throws Exception;
   
}

3.4 : 日志

mybatis的日志有两种形式: 输出mybatis的执行过程,包括sql语句的执行;

1.使用mybatis默认的日志框架: 不需要导入jar包的(简单)

<!-- 运行参数 -->
    <settings>
        <!-- mybatis 默认的日志  -->
        <setting name="logImpl" value="STDOUT_LOGGING"/>
    </settings>

2.使用LOG4J 日志框架,需要导入jar包 和 log4j.properties日志文件

<!-- 运行参数 -->
<settings>
  <!-- mybatis 默认的日志  -->
  <setting name="logImpl" value="LOG4J"/>
</settings>

log4j文件, 放在src目录下:

#将等级为DEBUG的日志信息输出到console和file这两个目的地,console和file的定义在下面的代码
log4j.rootLogger=DEBUG,console,file

#控制台输出的相关设置
log4j.appender.console = org.apache.log4j.ConsoleAppender
log4j.appender.console.Target = System.out
log4j.appender.console.Threshold=DEBUG
log4j.appender.console.layout = org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=[%c]-%m%n

#文件输出的相关设置
log4j.appender.file = org.apache.log4j.RollingFileAppender
log4j.appender.file.File=./log/shun.log
log4j.appender.file.MaxFileSize=10mb
log4j.appender.file.Threshold=DEBUG
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=[%p][%d{yy-MM-dd}][%c]%m%n

#日志输出级别
log4j.logger.org.mybatis=DEBUG
log4j.logger.java.sql=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.ResultSet=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG

3.5 延迟加载(按需加载)

<settings>
        <!-- mybatis 默认的日志  -->
        <setting name="logImpl" value="LOG4J"/>
        <!-- 设置延迟加载吗  设置 true-->
        <setting name="lazyLoadingEnabled" value="true"/>
        <!-- 积极加载吗  不滴-->
        <setting name="aggressiveLazyLoading" value="false"/>
        <setting name="lazyLoadTriggerMethods" value=","/>
 </settings>
<collection property="orders" column="uid" ofType="order" fetchType="eager"
            select="com.oracle.mapper.OrderMapper.getOrdersByUid">
</collection>

3.6 mybatis的分页插件:

mybatis采用分页插件时,你的sql语句不需要写limit分页了,但是需要导入jar

1.pagehelper-5.1.1.jar

2.jsqlparser-1.0.jar

<?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>
  <!--插件 -->
  <plugins>
    <plugin interceptor="com.github.pagehelper.PageInterceptor">
      <!-- 指定数据库版本名 是什么 -->
      <property name="helpDialect" value="mysql"/>
      <!-- 合理化 true:  如果pageNum < 1 ,他给你返回第一页 ,如果pageNum > totalPage 返回最后一页
           合理化 false: 如果pageNum < 1 ,返回 空 ,如果pageNum> totalPage 返回 空
       -->
      <property name="seasonable" value="true"/>
    </plugin>
  </plugins>
</configuration>
@Test
public void test10() throws Exception {
    SqlSession sqlSession = SqlSessionUtil.getSqlSession();
    UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    //分页插件对象
    Integer pageNum = 1;
    Integer pageSize = 5;
    PageHelper.startPage(pageNum,pageSize);
    List<User> list = mapper.getAll(); //sql 语句中 没有 limit 关键字
    PageInfo  pageInfo = new PageInfo<>(list);
    System.out.println("当前页: "+pageInfo.getPageNum());
    System.out.println("页大小: "+pageInfo.getPageSize());
    System.out.println("总记录数: "+pageInfo.getTotal());
    System.out.println("总页数: "+pageInfo.getPages());
    //从PageInfo对象中获取的数据
    List users = pageInfo.getList();
    for (Object user : users) {
      System.out.println(user);
    }
}

3.7 mybatis的缓存

一级缓存:mybatis默认的就是一级缓存,默认开启的,是sqlSession会话级别的缓存,所有sqlSession共享;

在执行同一个sql语句时,如果缓存区没有数据,那么就回去数据库查询,第二次来,发现缓存区有数据

就直接从一级缓存中获取数据的,也就是说执行了一次sql语句,出现了两次结果;

如何执行 insert into, update, delete 会清空一级缓存,避免脏读;

[org.apache.ibatis.transaction.jdbc.JdbcTransaction]-Opening JDBC Connection
[org.apache.ibatis.datasource.pooled.PooledDataSource]-Created connection 1426329391.
[com.oracle.mapper.UserMapper.getOrdersByUid]-==>  Preparing: select * from `user` where uid = ?
[com.oracle.mapper.UserMapper.getOrdersByUid]-==> Parameters: 14(Integer)
[com.oracle.mapper.UserMapper.getOrdersByUid]-<==      Total: 1
User{uid=14, name='kakakaka', pwd='123123', address='12312312312'}
User{uid=14, name='kakakaka', pwd='123123', address='12312312312'}  执行一次sql语句,出现两次结果

二级缓存:

二级缓存是namespace级别的 也就是mapper级别的缓存,多个mapper级别的缓存不共享,但是可以使用

,我们在开启 二级缓存时,需要在全局配置文件中添加

<settings>
  <!-- 开启二级缓存的全局开关 -->
  <setting name="cacheEnabled" value="true"/>
  <settings>
<cache
  eviction="FIFO"
  flushInterval="60000"
  size="512"
  readOnly="true"/>

测试结果:

[org.apache.ibatis.transaction.jdbc.JdbcTransaction]-Opening JDBC Connection
[org.apache.ibatis.datasource.pooled.PooledDataSource]-Created connection 1256440269.
[com.oracle.mapper.UserMapper.getOrdersByUid]-==>  Preparing: select * from `user` where uid = ?
[com.oracle.mapper.UserMapper.getOrdersByUid]-==> Parameters: 14(Integer)
[com.oracle.mapper.UserMapper.getOrdersByUid]-<==      Total: 1
User{uid=14, name='kakakaka', pwd='123123', address='12312312312'}
[com.oracle.mapper.UserMapper]-Cache Hit Ratio [com.oracle.mapper.UserMapper]: 0.0
User{uid=14, name='kakakaka', pwd='123123', address='12312312312'}

总结: mybatis的缓存加载顺序时 二级缓存优先加载,如果没有,在加载一级缓存,mybatis的缓存在分布式架构中不可用; 使用redis最好;

Mybatis的逆向工程:

<generatorConfiguration>
	<context id="testTables" targetRuntime="MyBatis3">
	
		<!-- JavaBean 实现 序列化 接口 -->
		<plugin type="org.mybatis.generator.plugins.SerializablePlugin">
		</plugin>
		<!-- genenat entity时,生成toString -->
        <plugin type="org.mybatis.generator.plugins.ToStringPlugin" />
        <!-- 自定义物理分页  可生成支持Mysql数据的limit  不支持Oracle -->
        <plugin type="org.mybatis.generator.plugins.page.PaginationPlugin" />
        <!-- 自定义查询指定字段  -->
        <plugin type="org.mybatis.generator.plugins.field.FieldsPlugin" />	
		<!-- 此处是将Example改名为Criteria 当然 想改成什么都行~    -->      
        <plugin type="org.mybatis.generator.plugins.RenameExampleClassPlugin">  
	        <property name="searchString" value="Example$" />
	        <!-- 替换后
	        <property name="replaceString" value="Criteria" />  
	         -->
	        <property name="replaceString" value="Query" />
        </plugin>  
		<!-- 此处是将UserMapper.xml改名为UserDao.xml 当然 想改成什么都行~ -->        
        <plugin type="org.mybatis.generator.plugins.rename.RenameSqlMapperPlugin">  
	        <property name="searchString" value="Mapper" />
	        <property name="replaceString" value="Mapper" />
        </plugin>  
         
		<!-- 此处是将UserMapper改名为UserDao 接口 当然 想改成什么都行~  -->        
        <plugin type="org.mybatis.generator.plugins.rename.RenameJavaMapperPlugin">  
	        <property name="searchString" value="Mapper$" />
	        <property name="replaceString" value="Mapper" />
        </plugin>  
		<commentGenerator type="org.mybatis.generator.plugins.comment.MyCommentGenerator">
			<!-- 是否去除自动生成的注释 true:是 : false:否 
			<property name="suppressAllComments" value="true" />
			-->
		</commentGenerator>
		<!--数据库连接的信息:驱动类、连接地址、用户名、密码 -->
		<jdbcConnection driverClass="com.mysql.jdbc.Driver"
			connectionURL="jdbc:mysql://localhost:3306/mybatis" userId="root"
			password="root">
		</jdbcConnection>
		<!-- <jdbcConnection driverClass="oracle.jdbc.OracleDriver"
			connectionURL="jdbc:oracle:thin:@127.0.0.1:1521:yycg" 
			userId="yycg"
			password="yycg">
		</jdbcConnection> -->

		<!-- 默认false,把JDBC DECIMAL 和 NUMERIC 类型解析为 Integer,为 true时把JDBC DECIMAL 和 
			NUMERIC 类型解析为java.math.BigDecimal -->
		<javaTypeResolver>
			<property name="forceBigDecimals" value="false" />
		</javaTypeResolver>
		<!-- targetProject:生成POJO类的位置 -->
		<javaModelGenerator targetPackage="com.oracle.pojo"
			targetProject=".\src">
			<!-- enableSubPackages:是否让schema作为包的后缀 -->
			<property name="enableSubPackages" value="false" />
			<!-- 从数据库返回的值被清理前后的空格 -->
			<property name="trimStrings" value="true" />
		</javaModelGenerator>

        <!-- targetProject:mapper映射文件生成的位置 -->
		<sqlMapGenerator targetPackage="com.oracle.mapper" 
			targetProject=".\src">
			<!-- enableSubPackages:是否让schema作为包的后缀 -->
			<property name="enableSubPackages" value="false" />
		</sqlMapGenerator>
		<!-- targetPackage:mapper接口生成的位置 -->
		<javaClientGenerator type="XMLMAPPER"
			targetPackage="com.oracle.mapper" 
			targetProject=".\src">
			<!-- enableSubPackages:是否让schema作为包的后缀 -->
			<property name="enableSubPackages" value="true" />
		</javaClientGenerator>
		
		<!-- 指定数据库表 -->
		<!-- 用户模块表  -->
		<table schema="" tableName="user" domainObjectName="User">
		</table>
		<table schema="" tableName="card" domainObjectName="Card"/>
		<table schema="" tableName="order" domainObjectName="Order"/>
		<table schema="" tableName="product" domainObjectName="Product"/>
	</context>
</generatorConfiguration>

service层:

public interface UserService {
	
	public User login(String username,String password);

	public void insertUser(User user);
	
	public void deleteUserById(Integer uid);
	
	public void deletesUsersByUid(int[] ids);
	
	public void updateUserByUid(User user);
	
	public List<User> getAll();
	
	public List<User> getUserByLikeWithLimit(String like ,Integer paegNo,Integer pageSize);
	
}

serviceImpl实现类:

public class UserServiceImpl implements UserService {

	@Override
	public User login(String username, String password) {
		SqlSession sqlSession = SqlSessionUtil.getSqlSession();
		UserMapper mapper = sqlSession.getMapper(UserMapper.class);
		UserQuery example = new UserQuery();
		//参数赋值
		Criteria c = example.createCriteria();
		c.andUsernameEqualTo(username);
		c.andPasswordEqualTo(password);
		List<User> list = mapper.selectByExample(example);
		return list.get(0);
	}

	@Override
	public void insertUser(User user) {
		SqlSession sqlSession = SqlSessionUtil.getSqlSession();
		UserMapper mapper = sqlSession.getMapper(UserMapper.class);
		int a = mapper.insertSelective(user);
		sqlSession.commit();
		sqlSession.close();
		
	}

	@Override
	public void deleteUserById(Integer uid) {
		SqlSession sqlSession = SqlSessionUtil.getSqlSession();
		UserMapper mapper = sqlSession.getMapper(UserMapper.class);
		int a = mapper.deleteByPrimaryKey(uid);
	}

	@Override
	public void deletesUsersByUid(int[] ids) {


	}

	@Override
	public void updateUserByUid(User user) {
		SqlSession sqlSession = SqlSessionUtil.getSqlSession();
		UserMapper mapper = sqlSession.getMapper(UserMapper.class);
		mapper.updateByPrimaryKeySelective(user);
	}

	@Override
	public List<User> getAll() {
		SqlSession sqlSession = SqlSessionUtil.getSqlSession();
		UserMapper mapper = sqlSession.getMapper(UserMapper.class);
		UserQuery example = new UserQuery();
		List<User> list = mapper.selectByExample(example);
		return list;
	}

	@Override
	public List<User> getUserByLikeWithLimit(String like, Integer pageNo, Integer pageSize) {
		SqlSession sqlSession = SqlSessionUtil.getSqlSession();
		UserMapper mapper = sqlSession.getMapper(UserMapper.class);
		UserQuery example = new UserQuery();
		//赋值页码 和  页大小即可
		example.setPageNo(pageNo);
		example.setPageSize(pageSize);
			//设置条件
		Criteria c = example.createCriteria();
		c.andUsernameLike("%" + like +"%");
		List<User> list = mapper.selectByExample(example);
		return list;
	}
}

单元测试:

public class TestUser {
	 
	UserService userService = new UserServiceImpl();
	
	@Test
	public void test7(){
		String like = "呵";
		Integer pageNo = 1;
		Integer pageSize = 5;
		List<User> list = userService.getUserByLikeWithLimit(like, pageNo, pageSize);
		for (User user : list) {
			System.out.println(user);
		}
	}
	
	
	@Test
	public void test6(){
		List<User> list = userService.getAll();
		for (User user : list) {
			System.out.println(user);
		}
	}
	
	@Test
	public void test5(){
		User user =new User();
		user.setUid(102);
		user.setAddress("小草屋");
		userService.updateUserByUid(user);
	}
	
	
	@Test
	public void test4(){
		userService.deleteUserById(15);
	}
	
	@Test
	public void test2(){
		User user = new User();
		user.setUsername("诸葛亮");
		user.setPassword("111");
		userService.insertUser(user);
	}
	
	@Test
	public void test1(){
		User user = userService.login("关羽", "123");
		System.out.println(user);
	}
	
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值