原生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( ...
随机推荐
- 安装TD出现Unknown user name or bad password问题
在Server 2003 sp2上安装TD8.0 出现Unknown user name or bad password,是因为2003启用了DEP保护. 关闭系统的DEP保护就可以了. 方法如下 ...
- 【es6】正则扩展
- apollo应用配置集成及使用
apollo应用配置集成及使用 1. 开发环境Apollo地址 用户名:apollo 密码:admin 开发环境Apollo管理台地址:http://localhost:8070/ ...
- applets
Java Applet 可以大大提高Web页面的交互能力和动态执行能力.包含Applet的网页被称为Java-powered页,可以称其为Java支持的网页. Applet 当用户访问这样的网页时,A ...
- MySQL数据库以及其Python用法
一 命令行模式下: mysql -u root -p # 进入进入mysql命令行模式 show databases; # 查看所有数据库 create database data; # 创建数据库, ...
- 使用 Angular 和 RxJS 实现的无限滚动加载
无限滚动加载应该是怎样的? 无限滚动加载列表在用户将页面滚动到指定位置后会异步加载数据.这是避免寻主动加载(每次都需要用户去点击)的好方法,而且它能真正保持应用的性能.同时它还是降低带宽和增强用户体验 ...
- replace替换,全局和局部替换
<script> var a=document.getElementById("introduce").innerHTML; var b=a.replace(/jone ...
- Rust by Example1
最近在学习Rust,想通过这个记录一下学习过程 首先是老规矩:HelloWorld // Rust单行注释 /// 文档注释 /* 多行注释 */ fn main() { // 这是个 ...
- Html-完整表格
表头th 特殊的单元格:加粗.居中 它的用户是取代td的位置即可 <table border="2"> <tr> <th>姓名</th&g ...
- 根据Time Protocol从NIST Internet Time Servers获取准确时间
Time Protocol(RFC-868)是一种非常简单的应用层协议:它返回一个32位的二进制数字,这个数字描述了从1900年1月1日0时0分0秒到现在的秒数,服务器在TCP的37号端口监听时间协议 ...