简介

操作数据库

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\n" +
"<where>\n" +
" <if test=\"sex!=null and sex!=''\">\n" +
" AND sex=#{sex}\n" +
" </if>\n" +
" <if test=\"username!=null and username!=''\">\n" +
" AND username like #{username}\n" +
" </if>\n" +
"</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);

原生mybaits学习笔记的更多相关文章

  1. 原生nodejs 学习笔记1

    网上许多nodejs教程或书藉都是教你调用第三方模块来编写nodejs应用的,虽然这是非常便捷的,但是封装太厚,你基本一点东西还是没有学到.人家的模块,人家想怎么改就行,可以下一版本就改了接口,你的应 ...

  2. 原生nodejs 学习笔记2

    本章节学习流, 流的一个好处在于减少各种异步IO的回调地狱.IO操作遍及我们各种操作,比如数据库读写,文件读写, 文件转换压缩--别的不说,比如第一节,我们要将一个HTML文件返回浏览器,就涉及IO操 ...

  3. .NET 云原生架构师训练营(模块一 架构师与云原生)--学习笔记

    目录 什么是软件架构 软件架构的基本思路 单体向分布式演进.云原生.技术中台 1.1 什么是软件架构 1.1.1 什么是架构? Software architecture = {Elements, F ...

  4. 原生js学习笔记2

    知识点: 1:关于this指向问题,如果有函数a(),直接a()那么this指向window,new a()指向函数本身. 2:关于null和undefined.两者如果用“==”则认为两者是相等的, ...

  5. 【学习】原生js学习笔记1:添加class和使input为不可用

    <input type="checkbox" id="new_check" onChange="noUse()" checked> ...

  6. 【转载】Java学习笔记

    转载:博主主页 博主的其他笔记汇总 : 学习数据结构与算法,学习笔记会持续更新: <恋上数据结构与算法> 学习Java虚拟机,学习笔记会持续更新: <Java虚拟机> 学习Ja ...

  7. MongoDB学习笔记系列

    回到占占推荐博客索引 该来的总会来的,Ef,Redis,MVC甚至Sqlserver都有了自己的系列,MongoDB没有理由不去整理一下,这个系列都是平时在项目开发时总结出来的,希望可以为各位一些帮助 ...

  8. WeX5学习笔记

    目录 WeX5学习笔记... 1 1.轻松看透WeX5产品能力和技术... 1 2.WeX5可以怎么玩?... 3 一.纯本地App. 3 二.关联一个网站,希望默认就打开某页... 4 三.UI设计 ...

  9. jQuery 学习笔记

    jQuery 学习笔记   一.jQuery概述    宗旨: Write Less, Do More.    基础知识:        1.符号$代替document.getElementById( ...

随机推荐

  1. 3Q大战现高潮,360 推出Android "3Q" IM即时通讯,岁末年初3Q大战惊现高潮

    岁末年初3Q大战惊现高潮,360震撼推出Android "3Q" IM即时通讯       看过了QQ和360斗争的开端高潮,当然现在还不能说这场斗争已经结束,在我看来这次的事件未 ...

  2. EasyMock set方法报错: java.lang.AssertionError

    有返回值的方法没问题, 直接andReturn就行了. EasyMock.expect(info.getWebTitle()).andReturn(StringUtils.EMPTY).anyTime ...

  3. linux下的ps命令

    ps命令用于报告当前系统的进程状态.可以搭配kill指令随时中断.删除不必要的程序.ps命令是最基本同时也是非常强大的进程查看命令,使用该命令可以确定有哪些进程正在运行和运行的状态.进程是否结束.进程 ...

  4. Linux 命令 su 和 sudo 比较

    su : 可以用来切换到任何用户,但是要求输入目标用户的密码 比如:su - su - root (等价 su -) su - user su root 与 su - root 的区别在于,后者不切换 ...

  5. java几个经典的算法题目----------二维矩阵算法

    public class testClockwiseOutput { public static void main(String[] args) { //1.构建矩阵数据 int[][] arr = ...

  6. spingAOP在springMVC中的使用(我用在拦截controller中的方法。主要用于登录控制)

    首先截取了网上的一张配置execution的图片 我在项目中关于aop的配置:如果拦截controller的方法,需要在spring-mvc.xml文件中加入(如果在spring.xml中加入则无法拦 ...

  7. 在ViewDidLoad中往导航栈推ViewController报错

     Unbalanced calls to begin/end appearance transitions for <YZPMainViewController: 0x7fa04b4970f0& ...

  8. vue面试题总汇

    active-class是哪个组件的属性? vue-router模块的router-link组件. 嵌套路由怎么定义? 在实际项目中我们会碰到多层嵌套的组件组合而成,但是我们如何实现嵌套路由呢?因此我 ...

  9. SqlServer 2008 还原数据库的问题

    今天想把服务器上的一个SqlServer2005的数据库 还原到本地 SqlServer2008的数据库, 操作是报错:备份集中的数据库备份与现有的 'zyehouqin' 数据库不同. RESTOR ...

  10. vs2015编译时CS1056 C# Unexpected character解决办法

    https://stackoverflow.com/questions/42932577/error-cs1056-unexpected-character-running-the-msbuild-o ...