zoukankan      html  css  js  c++  java
  • 原生mybaits学习笔记

    简介

    操作数据库

    maven引入

    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.4.5</version>
    </dependency>
    

    核心配置文件

    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>
        <!--resource:加载外部配置文件,外部配置会替换内部配置-->
        <properties resource="db.properties">
            <!--配置内部属性-->
            <property name="driver" value="com.mysql.jdbc.Driver"/>
            <property name="jdbc.username" value="root"/>
        </properties>
        
        <!--配置类型别名-->
        <typeAliases>
            <package name="com.XXX.pojo"/>
        </typeAliases>
    
        <environments default="development">
            <environment id="development">
                <transactionManager type="JDBC" />
                <dataSource type="POOLED">
                    <!--数据库配置-->
                    <property name="driver" value="${driver}" />
                    <property name="url" value="jdbc:mysql://127.0.0.1:3306/mybatisdb?characterEncoding=utf8" />
                    <property name="username" value="root" />
                    <property name="password" value="root" />
                </dataSource>
            </environment>
        </environments>
    
        <!--SqlMapConfig.xml:就是MyBatis的核心配置文件-->
        <!--配置需要加载的Mapper.xml映射文件-->
        <mappers>
            <!--resource:需要加载的映射文件的文件地址-->
            <!--<mapper resource="mapper/UserMapper.xml"/>-->
    
            <!--使用类加载的方式加载资源-->
            <!--前提1:名字一致,前提2:目录一致(在一起)-->
            <!--<mapper class="com.XXX.mapper.UserDao"/>-->
    
            <!--package使用包扫描的方式加载资源-->
            <!--前提1:名字一致,前提2:目录一致(在一起)-->
            <package name="com.XXX.mapper"/>
        </mappers>
    </configuration>    
    

    方式一(简单)

    直接使用配置文件

    配置

    mapper/UserMapper.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.XXX.mapper.ProductMapper">
        <select id="queryProductByPid" parameterType="int" resultType="com.XXX.pojo.Product">
            SELECT * from product WHERE pid=#{pid};
        </select>
    </mapper>
    

    操作

    List<Product> list = sqlSession.selectList("queryProductByPid", 1);
    

    方式二(old)

    创建接口

    PersonMapper.java

    public interface ProductMapper {
    
        List<Product> queryProductByPid(int pid);
    
    }
    

    配置mapper.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.XXX.mapper.ProductMapper">
        <select id="queryProductByPid" parameterType="int" resultType="com.XXX.pojo.Product">
            SELECT * from product WHERE pid=#{pid};
        </select>
    </mapper>
    

    实现接口

    ProductMapperImpl

    public class ProductMapperImpl implements ProductMapper {
        private SqlSessionFactory sqlSessionFactory;
    
        public ProductMapperImpl(SqlSessionFactory sqlSessionFactory) {
            this.sqlSessionFactory = sqlSessionFactory;
        }
    
        public List<Product> queryProductByPid(int pid) {
            SqlSession sqlSession = sqlSessionFactory.openSession();
            List<Product> list = sqlSession.selectList("queryProductByPid", pid);
            return list;
        }
    }
    

    操作

    ProductMapper mapper = new ProductMapperImpl(sessionFactory);
    List<Product> products = mapper.queryProductByPid(1);
    

    方式三(常用)

    创建接口

    PersonMapper.java

    public interface ProductMapper {
    
        List<Product> queryProductByPid(int pid);
    
    }
    

    配置mapper.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.XXX.mapper.UserDao">
    
        <!-- #{} 是传参数,防止sql注入 -->
        <!-- ${} 是拼接,用于非参数的拼接 -->
        
        <!--根据id查询-->
        <select id="queryUserById" parameterType="int" resultType="UsEr">
            select * FROM user WHERE  id=#{id}
        </select>
    
        <!--根据用户名模糊查询,传入的时候加:%!!!-->
        <select id="queryUserByUsername" parameterType="string" resultType="com.XXX.pojo.User">
            select * from USER WHERE username like #{username}
        </select>
    
        <!--新增-->
        <insert id="saveUser" parameterType="com.XXX.pojo.User">
            <selectKey keyColumn="id" keyProperty="id" resultType="int" order="AFTER">
                SELECT last_insert_id()
            </selectKey>
            insert into USER (username,birthday,sex,address) values (#{username},#{birthday},#{sex},#{address});
        </insert>
    
    </mapper>
    

    操作

    SqlSession sqlSession = sessionFactory.openSession();
    ProductMapper mapper = sqlSession.getMapper(ProductMapper.class);
    List<Product> products = mapper.queryProductByPid(1);
    System.out.println(products);
    

    配置详解

    传入参数

    <!--传入复杂参数-->
    <select id="selectProduct2" parameterType="ProductVo" resultMap="product2">
        SELECT * from product where pid>#{product.pid};
    </select>
    

    接收参数

    <!--传出参数和数据库列名不一致-->
    <resultMap id="product2" type="product2" autoMapping="true">
        <id column="pid" property="pid"/>
        <result column="category_id" property="cid"/>
    </resultMap>
    <select id="selectProduct2" parameterType="ProductVo" resultMap="product2">
        SELECT * from product where pid>#{product.pid};
    </select>
    

    判断循环

    <!--if判断-->
    <select id="queryUserByUsernameAndSex" parameterType="user" resultType="user">
        SELECT <include refid="fields"/> FROM `user`
        <where>
            <if test="sex!=null and sex!=''">
                AND sex=#{sex}
            </if>
            <if test="username!=null and username!=''">
                AND username LIKE #{username}
            </if>
        </where>
    </select>
    
    <!--代码片段-->
    <sql id="fields">
        id,username,birthday,sex,address
    </sql>
    
    <!--foreach-->
    <select id="queryUserByIds" parameterType="queryVo" resultType="user">
        SELECT <include refid="fields"/> FROM `user`
        <where>
            <foreach collection="ids" item="item" open="id in (" close=")" separator=",">
                #{item}
            </foreach>
        </where>
    </select>
    

    一对一查询

    <!--一对一查询,查询账号和对应的用户数据,方案一-->
    <select id="queryAccountUserAll" resultType="accountUser">
        SELECT a.*,u.username,u.address FROM account a LEFT JOIN `user` u ON a.UID=u.id
    </select>
    
    <!--配置一对一查询方案二的ResultMap-->
    <resultMap id="accountResultMap" type="account" autoMapping="true">
        <!--配置的Account的主键-->
        <id property="id" column="id"/>
        <result property="uid" column="uid"/>
        
        <association property="user" javaType="user" autoMapping="true">
            <id property="id" column="uid"/>
            <result property="username" column="username"/>
    
        </association>
    
    </resultMap>
    
    <!--一对一查询,查询账号和对应的用户数据,方案二(使用ResultMap)-->
    <select id="queryAccountAll" resultMap="accountResultMap">
        SELECT a.*,u.username,u.address FROM account a LEFT JOIN `user` u ON a.UID=u.id
    </select>
    

    一对多查询

    <!--配置ResultMap-->
    <resultMap id="userResultMap" type="user" autoMapping="true">
        <id property="id" column="id"/>
        <collection property="accounts" ofType="Account" autoMapping="true">
            <id property="id" column="aid"/>
        </collection>
    
    </resultMap>
    
    <!--查询所有的用户数据,使用一对多的方式,查询该用户的所有账号信息-->
    <select id="queryUserAll" resultMap="userResultMap">
        SELECT u.*,a.id aid,a.money FROM user u LEFT JOIN account a ON u.id=a.uid
    </select>
    

    延迟加载

    • 先再总配置里面打开
    <settings>
        <!--开启延时加载-->
        <setting name="lazyLoadingEnabled" value="true"/>
        <setting name="aggressiveLazyLoading" value="false" />
    </settings>
    
    • 再在mapper.xml里面配置column和select
    <!--一对一-->
    <association property="user" javaType="user" column="uid"
        select="com.alvin.mapper.UserMapper.queryUserById"></association>
    <!--一对多-->
    <collection property="accounts" ofType="Account" column="id"
        select="com.alvin.mapper.AccountMapper.queryAccountByUid"></collection>
    

    缓存

    一级缓存

    作用于具体sqlSession

    默认开启

    二级缓存

    作用于指定mapper文件,如果在account.mapper里面操作user,有可能会影响user表的操作,所以一般不用。

    • 核心配置文件(默认为true可以不设置)
    <!--全局打开二级缓存-->
    <setting name="cacheEnabled" value="true"/>
    
    • 普通mapper.xml
    <!--局部打开二级缓存-->
    <cache/>
    
    <!--useCache="true"打开某个select缓存-->
    <select id="queryUserById" parameterType="int" resultType="user" useCache="true">
        select * from user where id=#{id}
    </select>
    

    全注解开发

    @Select("select * from user where id=#{id}")
    public User queryUserById(Integer id);
    
    @Select("select * from user")
    public List<User> queryUserAll();
    
    //@SelectKey:扩展,配置主键返回,statement:用来配置查询主键数据的sql
    @SelectKey(statement = "select last_insert_id()", keyProperty = "id"
            , keyColumn = "id", before = false, resultType = Integer.class)
    @Insert("insert into user (username,birthday,sex,address) " +
            "values (#{username},#{birthday},#{sex},#{address})")
    public void saveUser(User user);
    
    @Update("update user set username=#{username} where id=#{id}")
    public void updateUserById(User user);
    
    @Delete("delete from user where id=#{id}")
    public void deleteUserById(Integer id);
    
    //扩展:如果要使用动态sql的标签,需要给最终的sql语句用<script>标签进行包裹
    @Select("<script>" +
            "SELECT * FROM USER
    " +
            "<where>
    " +
            "    <if test="sex!=null and sex!=''">
    " +
            "        AND sex=#{sex}
    " +
            "    </if>
    " +
            "    <if test="username!=null and username!=''">
    " +
            "        AND username like #{username}
    " +
            "    </if>
    " +
            "</where>" +
            "</script>")
    public List<User> queryUserByUsernameAndSex(User user);
    
    
    //查询所有的用户数据,使用延时加载的方式获取该用户的账户数据
    //@Results:相当于在配置ResultMap
    //@Result:相当于配置ResultMap里面的<id>和<result>标签
    //@Result里面的id属性:就是这个配置是否是主键,如果是true,就代表这是主键,如果是false就不是主键
    //@Result里面的property属性:就是配置对应的pojo的哪一个属性
    //@Result里面的column属性:配置对应的数据库结果集的那一列,
    // 如果是一对一和一对多,这里配置的就是延时加载的时候,需要使用的查询参数
    //本例中延时加载账户的用户数据,就需要通过uid进行查询
    //@Result注解里面没有ofType,而xml映射文件中有ofType,注解既然没有,就省略不写
    //@Result里面的javaType就是属性的类型
    //@Result里面的one配置的是一对一的延时加载,里面需要填写的是@One注解
    //@One里面的select属性是配置延时加载需要执行的方法,和映射文件中延时加载的select属性配置的效果是一样
    //@One里面的fetchType属性是配置是否使用延时加载,FetchType.LAZY代表使用延时加载
    @Select("select * from user")
    @Results({
            @Result(id = true,property = "id",column = "id"),
            @Result(property = "username",column = "username"),
            @Result(property = "birthday",column = "birthday"),
            @Result(property = "sex",column = "sex"),
            @Result(property = "address",column = "address"),
            @Result(property = "accounts",column = "id",
            many = @Many(select = "com.alvin.mapper.AccountMapper.queryAccountByUid"))
    })
    public List<User> queryUserAccountAll();
    
    //查询所有的账户数据,同时延时加载用户数据
    @Select("select * from account")
    @Results({
            @Result(id = true, property = "id", column = "id"),
            @Result(property = "uid", column = "uid"),
            @Result(property = "money", column = "money"),
            @Result(property = "user", column = "uid", javaType = User.class,
                    one = @One(select = "com.alvin.mapper.UserMapper.queryUserById")),
    })
    public List<Account> queryAccountUserAll();
    
    //支持用户的延时加载账户信息,所编写的方法
    @Select("select * from Account where uid=#{uid}")
    public List<Account> queryAccountByUid(Integer uid);
    
  • 相关阅读:
    一维数组
    do while循环(熟悉)
    while循环的概念和使用
    break关键字
    continue关键字
    for循环的概念与使用
    switchcase分支结构
    if else if else分支结构
    关于scanf()读取与返回值和回车键的问题
    WCF通过IIS寄宿服务
  • 原文地址:https://www.cnblogs.com/birdofparadise/p/10012278.html
Copyright © 2011-2022 走看看