美文网首页
Mybatis提高

Mybatis提高

作者: iDevOps | 来源:发表于2019-10-08 13:13 被阅读0次
数据库连接池
  • 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>
    <!--配置mybatis环境-->
    <properties resource="db.properties"></properties>
    <environments default="mysql">
        <!--配置mysql环境-->
        <environment id="mysql">
            <!--配置事务的类型-->
            <transactionManager type="JDBC" />
            <!--
            配置数据源
                type:
                    UNPOOLED: 不使用连接池的数据源,Mybatis会创建UNPooledDataSource实例
                    POOLED: 使用连接池的数据源,Mybatis会创建PooledDataSource实例
                    JNDI: 使用JNDI实现的数据源,Mybatis会从JNDI服务上查找DataSource实例,然后返回
            -->
            <dataSource type="POOLED">
                <property name="driver" value="${db.driver}" />
                <property name="url" value="${db.url}" />
                <property name="username" value="${db.username}" />
                <property name="password" value="${db.password}" />
            </dataSource>
        </environment>
    </environments>
</configuration>
  • Mybatis中获取DataSource
    MyBatis通过DataSourceFactory中的getDataSource()方法来创建数据源DataSource对象(工厂模式)
public interface DataSourceFactory {
    void setProperties(Properties var1);

    DataSource getDataSource();
}
  • Mybatis中存放DataSource
    MyBatis 创建了 DataSource 实例后,会将其放到 Configuration 对象内的 Environment 对象中, 供以后使用
XMLConfigBuilder.class

省略....
public Configuration parse() {
    if (this.parsed) {
        throw new BuilderException("Each XMLConfigBuilder can only be used once.");
    } else {
        this.parsed = true;
        this.parseConfiguration(this.parser.evalNode("/configuration"));
        return this.configuration;
    }
}
省略....
public class Configuration {
    protected Environment environment;
    省略....
}
public final class Environment {
    private final String id;
    private final TransactionFactory transactionFactory;
    private final DataSource dataSource;

    public Environment(String id, TransactionFactory transactionFactory, DataSource dataSource) {
        if (id == null) {
            throw new IllegalArgumentException("Parameter 'id' must not be null");
        } else if (transactionFactory == null) {
            throw new IllegalArgumentException("Parameter 'transactionFactory' must not be null");
        } else {
            this.id = id;
            if (dataSource == null) {
                throw new IllegalArgumentException("Parameter 'dataSource' must not be null");
            } else {
                this.transactionFactory = transactionFactory;
                this.dataSource = dataSource;
            }
        }
    }

    public String getId() {
        return this.id;
    }

    public TransactionFactory getTransactionFactory() {
        return this.transactionFactory;
    }

    public DataSource getDataSource() {
        return this.dataSource;
    }

    public static class Builder {
        private String id;
        private TransactionFactory transactionFactory;
        private DataSource dataSource;

        public Builder(String id) {
            this.id = id;
        }

        public Environment.Builder transactionFactory(TransactionFactory transactionFactory) {
            this.transactionFactory = transactionFactory;
            return this;
        }

        public Environment.Builder dataSource(DataSource dataSource) {
            this.dataSource = dataSource;
            return this;
        }

        public String id() {
            return this.id;
        }

        public Environment build() {
            return new Environment(this.id, this.transactionFactory, this.dataSource);
        }
    }
}
  • Mybatis中连接的获取过程分析
Stream in = Resources.getResourceAsStream("SqlMapConfig.xml");
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(in);
SqlSession sqlSession = factory.openSession();
IUserDao mapper = sqlSession.getMapper(IUserDao.class);
//这个时候才会触发 MyBatis 在底层执行下面这个方法来创建 java.sql.Connection 对象(可以通过断点调试)
List<User> users = mapper.findAll();
事务控制

Mybatis 中事务的提交方式,本质上就是调用 JDBC 的 setAutoCommit()来实现事务控制
为什么必须使用 sqlSession.commit()提交事务?
主要原因就是在连接池中取出的连接,都会将调用 connection.setAutoCommit(false)方法,这样我们就必须使用 sqlSession.commit()方法,相当于使用了 JDBC 中的 connection.commit()方法实现事务提交。

Stream in = Resources.getResourceAsStream("SqlMapConfig.xml");
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(in);
//设置事务自动提交
SqlSession sqlSession = factory.openSession(true);
动态SQL语句

有些时候业务逻辑复杂时,我们的 SQL 是动态变化的,此时在前面的学习中我们的 SQL 就不能满足要求了

  • if
<?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.sn511.mybatis.dao.IUserDao">
    <select id="findByUser" resultType="com.sn511.mybatis.domain.User" parameterType="com.sn511.mybatis.domain.User">
        select * from user where 1=1
        <if test="name!=null and name != '' ">
            and name like #{name}
        </if>
        <if test="age != null">
            and age = #{age}
        </if>
    </select>
</mapper>
@Test
public void test(){
    User user = new User();
    user.setName("%王%");
    user.setAge(10);
    IUserDao mapper = sqlSession.getMapper(IUserDao.class);
    List<User> users = mapper.findByUser(user);
    System.out.println(users);
}
  • where
<?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.sn511.mybatis.dao.IUserDao">
    <select id="findByUser" resultType="com.sn511.mybatis.domain.User" parameterType="com.sn511.mybatis.domain.User">
        select * from user
        <where>
            <if test="name!=null and name != '' ">
                and name like #{name}
            </if>
            <if test="age != null">
                and age = #{age}
            </if>
        </where>
    </select>
</mapper>
  • 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.sn511.mybatis.dao.IUserDao">
    <select id="findByUser" resultType="com.sn511.mybatis.domain.User" parameterType="com.sn511.mybatis.domain.User">
        <!--
            select * from user where id in (1,2,3)
            collection:代表要遍历的集合元素,注意编写时不要写#{}
            open:代表语句的开始部分
            close:代表结束部分
            item:代表遍历集合的每个元素,生成的变量名
            sperator:代表分隔符
        -->
        select * from user
        <where>
            <if test="ids != null and ids.size() > 0">
                <foreach collection="ids" open="id in ( " close=")" item="id" separator=",">
                    #{id}
                </foreach>
            </if>
        </where>
    </select>
</mapper>
  • 简化sql
    Sql 中可将重复的 sql 提取出来,使用时用 include 引用即可,最终达到 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="com.sn511.mybatis.dao.IUserDao">
    <sql id="defaultSql">
        select * from user
    </sql>
    <select id="findByUser" resultType="com.sn511.mybatis.domain.User" parameterType="com.sn511.mybatis.domain.User">
        <include refid="defaultSql"></include>
        <where>
            <if test="ids != null and ids.size() > 0">
                <foreach collection="ids" open="id in ( " close=")" item="id" separator=",">
                    #{id}
                </foreach>
            </if>
        </where>
    </select>
</mapper>
多表查询
  • 一对一
# 实体类
# 用户
public class User {
    private Integer id;
    private String name;
    private Integer age;
    省略getter、setter、toString方法
}

# 账户, 一个用户有多个账户
public class Account {
    private Integer id;
    private Integer uid;
    private Double money;
    省略getter、setter、toString方法
}

# 为了能够封装查询结果, 定义一个新的实体类包含用户和账户的字段
public class AccountUser extends Account implements Serializable {
    private String name;
    private Integer age;
    省略getter、setter方法
    @Override
    public String toString() {
        return super.toString() + "AccountUser{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
# dao
public interface IAccountDao {
    List<AccountUser> findAll();
}
# resources/com/sn511/mybatis/dao/IAccountDdao.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="com.sn511.mybatis.dao.IAccountDao">
    <select id="findAll" resultType="com.sn511.mybatis.domain.AccountUser">
        select a.*,u.name,u.age from account a,user u where a.uid =u.id
    </select>
</mapper>
# 测试
@Test
public void test1(){
    IAccountDao mapper = sqlSession.getMapper(IAccountDao.class);
    List<AccountUser> all = mapper.findAll();
    for (AccountUser accountUser : all){
        System.out.println(accountUser.toString());
    }
}
  • 一对多
public class User {
    private Integer id;
    private String name;
    private Integer age;
    List<Account> accounts;
    省略getter、setter、toString方法
}
public interface IUserDao {
    List<User> findAll();
}

<?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.sn511.mybatis.dao.IUserDao">
    <!--
        collection: 部分定义了用户关联的账户信息。表示关联查询结果集
        ofType: 指定关联查询的结果集中的对象类型即List中的对象类型。此处可以使用别名,也可以使用全限定名
    -->
    <resultMap id="userMap" type="com.sn511.mybatis.domain.User">
        <id column="id" property="id"></id>
        <result column="name" property="name"></result>
        <result column="age" property="age"></result>
        <collection property="accounts" ofType="com.sn511.mybatis.domain.Account">
            <id column="aid" property="id"></id>
            <result column="uid" property="uid"></result>
            <result column="money" property="money"></result>
        </collection>
    </resultMap>
    <select id="findAll" resultMap="userMap">
        select u.*,a.id as aid, a.uid, a.money from user u left join account a on u.id = a.uid
    </select>
</mapper>
@Test
public void test1(){
    IUserDao mapper = sqlSession.getMapper(IUserDao.class);
    List<User> all = mapper.findAll();
    System.out.println(all.toString());
}
  • 多对多
延迟加载策略

实际开发过程中很多时候我们并不需要总是在加载用户信息时就一定要加载他的账户信息。此时就是我们所说的延迟加载。
延迟加载: 在需要用到数据时才进行加载,不需要用到数据时就不加载数据。延迟加载也称懒加载
好处:先从单表查询,需要时再从关联表去关联查询,大大提高数据库性能,因为查询单表要比关联查询多张表速度要快
坏处:因为只有当需要用到数据时,才会进行数据库查询,这样在大批量数据查询时,因为查询工作也要消耗时间,所以可能造成用户等待时间变长,造成用户体验下降

Mybatis缓存

像大多数的持久化框架一样,Mybatis 也提供了缓存策略,通过缓存策略来减少数据库的查询次数,从而提高性能。Mybatis 中缓存分为一级缓存,二级缓存。

  • 一级缓存
    一级缓存是SqlSession级别的缓存,只要SqlSession没有flush或close,它就存在。
public interface IUserDao {
    User findById(Integer id);
}
<?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.sn511.mybatis.dao.IUserDao">
    <select id="findById" parameterType="int" resultType="com.sn511.mybatis.domain.User">
        select * from user where id = #{id}
    </select>
</mapper>
@Test
public void test(){
    IUserDao mapper = sqlSession.getMapper(IUserDao.class);
    User user1 = mapper.findById(1);
    User user2 = mapper.findById(1);
    System.out.println(user1);  // com.sn511.mybatis.domain.User@186a70
    System.out.println(user2);  // com.sn511.mybatis.domain.User@186a70
    System.out.println(user1 == user2); // true
}

分析:
1.第一次查询,先去缓存中查找,没有才去数据库查询,然后将查询的用户信息存到一级缓存中。
2.第二次查询,先去缓存中查找,有,就没有再进行数据库查询操作。
注: 如果sqlSession执行了commit操作,就会清空sqlSession中的一级缓存,这样就目的是为了让缓存中存在最新的信息,避免脏读。

  • 二级缓存
    二级缓存是 mapper 映射级别的缓存,多个 SqlSession 去操作同一个 Mapper 映射的 sql 语句,多个SqlSession 可以共用二级缓存,二级缓存是跨 SqlSession 的。

1.开启和关闭二级缓存

# SqlMapConfig.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>

    <!--配置mybatis环境-->
    <properties resource="db.properties"></properties>

    <settings>
        <!--
            开启二级缓存的支持
            默认为true, true代表开启二级缓存, false代表关闭二级缓存
        -->
        <setting name="cacheEnabled" value="true"/>
        <!-- 打印查询语句 -->
        <setting name="logImpl" value="STDOUT_LOGGING" />
    </settings>


    <environments default="mysql">
        <!--配置mysql环境-->
        <environment id="mysql">
            <!--配置事务的类型-->
            <transactionManager type="JDBC" />
            <!--
            配置数据源
                type:
                    UNPOOLED: 不使用连接池的数据源,Mybatis会创建UNPooledDataSource实例
                    POOLED: 使用连接池的数据源,Mybatis会创建PooledDataSource实例
                    JNDI: 使用JNDI实现的数据源,Mybatis会从JNDI服务上查找DataSource实例,然后返回
            -->
            <dataSource type="POOLED">
                <property name="driver" value="${db.driver}" />
                <property name="url" value="${db.url}" />
                <property name="username" value="${db.username}" />
                <property name="password" value="${db.password}" />
            </dataSource>
        </environment>
    </environments>


    <!--mybatis映射配置的位置-->
    <mappers>
        <mapper resource="com/sn511/mybatis/dao/IUserDao.xml" />
    </mappers>
</configuration>
# IUserDao.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="com.sn511.mybatis.dao.IUserDao">
    <!-- 开启二级缓存的支持, 区分的标准就看 mapper的namespace值 -->
    <cache></cache>
    <!--
        设置 useCache=”true”代表当前这个 statement 要使用二级缓存,如果不使用二级缓存可以设置为 false
    -->
    <select id="findById" parameterType="int" resultType="com.sn511.mybatis.domain.User" useCache="true">
        select * from user where id = #{id}
    </select>
</mapper>
# 测试
@Test
public void test(){
    SqlSession sqlSession1 = factory.openSession();
    IUserDao mapper1 = sqlSession1.getMapper(IUserDao.class);
    User user1 = mapper1.findById(1);
    System.out.println("user1:" + user1);
    sqlSession1.close();//一级缓存消失

    SqlSession sqlSession2 = factory.openSession();
    IUserDao mapper2 = sqlSession2.getMapper(IUserDao.class);
    User user2 = mapper2.findById(1);
    System.out.println("user2:" + user2);
    sqlSession2.close();
}

# 输出
Logging initialized using 'class org.apache.ibatis.logging.stdout.StdOutImpl' adapter.
PooledDataSource forcefully closed/removed all connections.
PooledDataSource forcefully closed/removed all connections.
PooledDataSource forcefully closed/removed all connections.
PooledDataSource forcefully closed/removed all connections.
Cache Hit Ratio [com.sn511.mybatis.dao.IUserDao]: 0.0
Opening JDBC Connection
Created connection 1709567.
Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@1a15ff]
==>  Preparing: select * from user where id = ? 
==> Parameters: 1(Integer)
<==    Columns: id, name, age
<==        Row: 1, 张三, 11
<==      Total: 1
user1:com.sn511.mybatis.domain.User@1ca2dfa
Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@1a15ff]
Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@1a15ff]
Returned connection 1709567 to pool.
Cache Hit Ratio [com.sn511.mybatis.dao.IUserDao]: 0.5
user2:com.sn511.mybatis.domain.User@171c76a

结论:
第一次有数据库查询
第二次没有数据库查询,说明数据来自于二级缓存

# 注
使用二级缓存实体类一定要实现java.io.Serializable 接口
注解开发
  • 基本的增删改查
# SqlMapConfig.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>

    <!-- 配置 properties 文件的位置-->
    <properties resource="db.properties"></properties>

    <!-- 配置别名的注册   -->
    <typeAliases>
        <package name="com.sn511.mybatis.domain"/>
    </typeAliases>

    <!-- mysql环境 -->
    <environments default="mysql">
        <!--配置mysql环境-->
        <environment id="mysql">
            <!--配置事务的类型-->
            <transactionManager type="JDBC" />
            <!--
            配置数据源
                type:
                    UNPOOLED: 不使用连接池的数据源,Mybatis会创建UNPooledDataSource实例
                    POOLED: 使用连接池的数据源,Mybatis会创建PooledDataSource实例
                    JNDI: 使用JNDI实现的数据源,Mybatis会从JNDI服务上查找DataSource实例,然后返回
            -->
            <dataSource type="POOLED">
                <property name="driver" value="${db.driver}" />
                <property name="url" value="${db.url}" />
                <property name="username" value="${db.username}" />
                <property name="password" value="${db.password}" />
            </dataSource>
        </environment>
    </environments>

    <!--配置映射信息-->
    <mappers>
        <!--
            配置dao接口的位置
            方式1: mapper标签配置class属性
            方式2: package标签指定dao接口的包位置
        -->
        <package name="com.sn511.mybatis.dao"/>
    </mappers>
</configuration>
public interface IUserDao {

    /**
     * 查询所有用户信息
     */
    @Select("select * from user")
    List<User> findAll();

    /**
     * 根据id查询用户信息
     */
    @Select("select * from user where id = #{id}")
    User fingById(Integer id);

    /**
     * 查询用户数量
     */
    @Select("select count(*) from user")
    int findTotal();

    /**
     * 根据姓名模糊查询用户信息
     */
    @Select("select * from user where name like #{name} ")
    List<User> findByName(String name);

    /**
     * 保存用户信息
     */
    @Insert("insert into user (name, age) values (#{name}, #{age})")
    int saveUser(User user);

    /**
     * 保存用户信息并返回用户信息id, 用户id在user中保存
     */
    @Insert("insert into user (name, age) values (#{name}, #{age})")
    @SelectKey(keyColumn = "id", keyProperty = "id", resultType = Integer.class, before = false, statement = {"select last_insert_id()"})
    int saveUserGetId(User user);

    /**
     * 更新用户信息
     */
    @Update("update user set name=#{name}, age=#{age} where id = #{id}")
    int updateUser(User user);

    /**
     * 根据id删除用户信息
     */
    @Delete("delete from user where id = #{id}")
    int deleteUser(Integer id);

}
# 测试
public class TestUser {

    InputStream in;
    SqlSessionFactoryBuilder builder;
    SqlSessionFactory factory;
    SqlSession sqlSession;

    @Before
    public void init() throws Exception{
        //读取配置文件
        in = Resources.getResourceAsStream("SqlMapConfig.xml");
        //构建者
        builder = new SqlSessionFactoryBuilder();
        //SqlSession工厂
        factory = builder.build(in);
        sqlSession = factory.openSession();
    }

    @After
    public void destroy() throws Exception{
        sqlSession.commit();
        sqlSession.close();
        in.close();
    }


    @Test
    public void testFindAll(){
        IUserDao mapper = sqlSession.getMapper(IUserDao.class);
        List<User> all = mapper.findAll();
        for(User user:all){
            System.out.println(user.toString());
        }
    }

    @Test
    public void testFindById(){
        IUserDao mapper = sqlSession.getMapper(IUserDao.class);
        User user = mapper.fingById(1);
        System.out.println(user.toString());
    }

    @Test
    public void testSaveUser(){
        IUserDao mapper = sqlSession.getMapper(IUserDao.class);
        User user = new User();
        user.setName("李四");
        user.setAge(15);
        int i = mapper.saveUser(user);
        System.out.println(i);
    }

    @Test
    public void testSaveUserGetId(){
        IUserDao mapper = sqlSession.getMapper(IUserDao.class);
        User user = new User();
        user.setName("王五");
        user.setAge(16);
        int i = mapper.saveUserGetId(user);
        System.out.println(i);
        System.out.println(user.getId()); //返回插入记录的主键ID
    }

    @Test
    public void testUpdateUser(){
        IUserDao mapper = sqlSession.getMapper(IUserDao.class);
        User user = new User();
        user.setId(9);
        user.setName("王小五");
        user.setAge(17);
        int i = mapper.updateUser(user);
        System.out.println(i);
    }

    @Test
    public void testDeleteUser(){
        IUserDao mapper = sqlSession.getMapper(IUserDao.class);
        int i = mapper.deleteUser(9);
        System.out.println(i);
    }

    @Test
    public void testTotal(){
        IUserDao mapper = sqlSession.getMapper(IUserDao.class);
        int i = mapper.findTotal();
        System.out.println(i);
    }

    @Test
    public void testFindByName(){
        IUserDao mapper = sqlSession.getMapper(IUserDao.class);
        List<User> users = mapper.findByName("%五%");
        System.out.println(users);
    }

}
  • 使用注解实现复杂关系映射开发

@Results 注解
代替的是标签<resultMap>
该注解中可以使用单个@Result 注解,也可以使用@Result 集合
@Results({@Result(),@Result()})
@Results(@Result())

@Resutl 注解
代替了 <id>标签和<result>标签
@Result 中 属性介绍:
id 是否是主键字段
column 数据库的列名
property 需要装配的属性名
one 需要使用的@One 注解(@Result(one=@One)()))
many 需要使用的@Many 注解(@Result(many=@many)()))

@One 注解(一对一)
代替了<assocation>标签,是多表查询的关键,在注解中用来指定子查询返回单一对象。
@One 注解属性介绍:
select 指定用来多表查询的 sqlmapper
fetchType 会覆盖全局的配置参数 lazyLoadingEnabled。。
使用格式:
@Result(column=" ",property="",one=@One(select=""))

@Many 注解(多对一)
代替了<Collection>标签,是是多表查询的关键,在注解中用来指定子查询返回对象集合。
注意:聚集元素用来处理“一对多”的关系。需要指定映射的 Java 实体类的属性,属性的 javaType
(一般为 ArrayList)但是注解中可以不定义;
使用格式:
@Result(property="",column="",many=@Many(select=""))

  • 一对一
public class User implements Serializable {
    private Integer id;
    private String name;
    private Integer age;
}

public class Account implements Serializable {
    private Integer id;
    private Integer uid;
    private Double money;
    private User user;
}
public interface IAccountDao {
    @Select("select * from account")
    @Results(id = "accountMap",
             value = {
                @Result(id = true, column = "id", property = "id"),
                @Result(column = "id", property = "id"),
                @Result(column = "uid", property = "uid"),
                @Result(column = "money", property = "money"),
                @Result(column = "uid", property = "user",
                        one = @One(select = "com.sn511.mybatis.dao.IUserDao.findById", fetchType = FetchType.LAZY))
             })
    List<Account> findAll();
}
public interface IUserDao {
    /**
     * 根据id查询用户信息
     */
    @Select("select * from user where id = #{uid}")
    User fingById(Integer id);
}
# 测试
@Test
public void testFindByName1(){
    IAccountDao mapper = sqlSession.getMapper(IAccountDao.class);
    List<Account> all = mapper.findAll();
    System.out.println(all);
}
  • 一对多
public class User implements Serializable {
    private Integer id;
    private String name;
    private Integer age;
    private List<Account> accounts;
}
public class Account {
    private Integer id;
    private Integer uid;
    private Double money;
}
public interface IAccountDao {
   @Select("select * from account where uid = #{uid}")
   List<Account> findByUid(Integer id);
}
public interface IUserDao {

    /**
     * 查询所有用户信息
     */
    @Select("select * from user")
    @Results(id = "userMap",
             value = {
                @Result(id = true, column = "id", property = "id"),
                @Result(column = "name", property = "name"),
                @Result(column = "age", property = "age"),
                @Result(column = "id", property = "accounts",
                        many = @Many(
                                select = "com.sn511.mybatis.dao.IAccountDao.findByUid",
                                fetchType = FetchType.LAZY
                        ))
             })
    List<User> findAll();
}
# 测试
@Test
public void test(){
    IUserDao mapper = sqlSession.getMapper(IUserDao.class);
    List<User> all = mapper.findAll();
    System.out.println(all);
}
  • 基于注解方式的二级缓存
@CacheNamespace(blocking = true)
public interface IUserDao {
}

相关文章

  • MyBatis 逆向工程生产源码(po、mapper)

    什么是mybatis的逆向工程mybatis官方为了提高开发效率,提高自动对单表生成sql,包括 :mapper....

  • mybatis缓存机制

    mybatis缓存机制 简介: mybatis提供查询缓存,用于减轻数据库压力,提高数据库性能 mybatis提供...

  • MyBatis Plus 国产的开源框架,基于 MyBatis 核心功能就是简化 MyBatis 的开发,提高效率...

  • Mybatis-plus

    MyBatis Plus 国产的开源框架,基于 MyBatis 核心功能就是简化 MyBatis 的开发,提高效率...

  • Mybatis提高

    数据库连接池 Mybatis中数据源的配置 Mybatis中获取DataSourceMyBatis通过DataSo...

  • Mybatis缓存机制详解2019-06-13

    mybatis缓存机制详解 mybatis提供了缓存机制减轻数据库压力,提高数据库性能 mybatis的缓存分为两...

  • Mybatis分页插件

    Mybatis插件介绍 为了提高Mybatis的可扩展能力,Mybatis引入的插件机制,允许开发人员通过责任链编...

  • 6. MyBatis缓存

    6.1 MyBatis缓存介绍 mybatis提供查询缓存,用于减轻数据压力,提高数据库性能。mybaits提供...

  • Mybatis-Plus基本使用

    Mybatis-Plus是一个Mybatis的增强工具,在Mybatis的基础上只做增强不做改变,为简化开发、提高效率。

  • springMVC+mybatis+ehcache详细配置

    一、 Mybatis+Ehcache配置 为了提高MyBatis的性能,有时候我们需要加入缓存支持,目前用的比较多...

网友评论

      本文标题:Mybatis提高

      本文链接:https://www.haomeiwen.com/subject/knpupctx.html