原生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\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学习笔记的更多相关文章
- 原生nodejs 学习笔记1
网上许多nodejs教程或书藉都是教你调用第三方模块来编写nodejs应用的,虽然这是非常便捷的,但是封装太厚,你基本一点东西还是没有学到.人家的模块,人家想怎么改就行,可以下一版本就改了接口,你的应 ...
- 原生nodejs 学习笔记2
本章节学习流, 流的一个好处在于减少各种异步IO的回调地狱.IO操作遍及我们各种操作,比如数据库读写,文件读写, 文件转换压缩--别的不说,比如第一节,我们要将一个HTML文件返回浏览器,就涉及IO操 ...
- .NET 云原生架构师训练营(模块一 架构师与云原生)--学习笔记
目录 什么是软件架构 软件架构的基本思路 单体向分布式演进.云原生.技术中台 1.1 什么是软件架构 1.1.1 什么是架构? Software architecture = {Elements, F ...
- 原生js学习笔记2
知识点: 1:关于this指向问题,如果有函数a(),直接a()那么this指向window,new a()指向函数本身. 2:关于null和undefined.两者如果用“==”则认为两者是相等的, ...
- 【学习】原生js学习笔记1:添加class和使input为不可用
<input type="checkbox" id="new_check" onChange="noUse()" checked> ...
- 【转载】Java学习笔记
转载:博主主页 博主的其他笔记汇总 : 学习数据结构与算法,学习笔记会持续更新: <恋上数据结构与算法> 学习Java虚拟机,学习笔记会持续更新: <Java虚拟机> 学习Ja ...
- MongoDB学习笔记系列
回到占占推荐博客索引 该来的总会来的,Ef,Redis,MVC甚至Sqlserver都有了自己的系列,MongoDB没有理由不去整理一下,这个系列都是平时在项目开发时总结出来的,希望可以为各位一些帮助 ...
- WeX5学习笔记
目录 WeX5学习笔记... 1 1.轻松看透WeX5产品能力和技术... 1 2.WeX5可以怎么玩?... 3 一.纯本地App. 3 二.关联一个网站,希望默认就打开某页... 4 三.UI设计 ...
- jQuery 学习笔记
jQuery 学习笔记 一.jQuery概述 宗旨: Write Less, Do More. 基础知识: 1.符号$代替document.getElementById( ...
随机推荐
- 【文档】一、Mysql Binlog概述
Binlog是一系列日志文件,他们包含的内容是Mysql数据内容的改变.如果想开启binlog功能,需要在启动时带上--log-bin参数. binlog是从Mysql3.23.14版本开始的.它包含 ...
- reifiable type与raw type
下面的逻辑需要明白如下两个概念: 4.7. Reifiable Types 4.8. Raw Types 举几个是Reifiable Types的例子,如下: class A{} class B< ...
- 关于dubbo调度时出现Request processing failed; nested exception is com.alibaba.dubbo.rpc.RpcException: Failed to invoke the method insertTestTb in the service cn.cuibusi.core.service.TestTbService.的解决办法
在用dubbo跨项目调度service时出现如下错误: 错误原因:pojo没有实现序列化 解决方法:在pojo实现序列化接口即可
- 向div添加圆角边框
初级参数:border-radius: 4px;中级参数:border-radius: 4px 6px 6px 4px;终极参数:border-radius: 5px 5px 3px 2px / 5p ...
- Lucio: We avoided Mourinho after every loss
Former Inter defender Lucio has revealed how players had to avoid former Nerazzurri coach Mourinho e ...
- Basic .do(Can be used as template)
#Time: 2017-05-06 #By : YINBin@122275 quit -sim cd D:/Documents/Work/UVM_PRJ/uvm-crc-test set ...
- i.mx6 Android5.1.1 初始化流程之框架
Android启动过程分为以下几个步骤: 1. Boot ROM: 上电后启动芯片固话代码. 2. BootLoader:固话代码会根据启动模式启动bootloader,(一般为启动引脚的电平的 ...
- ThinkPHP出现项目目录不可写,目录无法自动生成
问题描述:维护一个老项目,用的TP2.1,down完代码,配好环境,访问的时候出现“项目目录不可写,目录无法自动生成!请使用项目生成器或者手动生成项目目录~”: 问题原因:在linux 服务器上,th ...
- 用JavaScript将数字转换为大写金额(收藏)
(非原创, 来自网络,仅作收藏) var digitUppercase = function(n) { var fraction = ['角', '分']; var digit = [ '零', '壹 ...
- java map常用的4种遍历方法
public static void main(String[] args) { Map<String, String> map = new HashMap<String, Stri ...