SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for t_emp
-- ----------------------------
DROP TABLE IF EXISTS `t_emp`;
CREATE TABLE `t_emp` (
`emp_id` int(11) NOT NULL AUTO_INCREMENT,
`emp_name` varchar(50) DEFAULT NULL,
`emp_salary` double(15,5) DEFAULT NULL,
`emp_age` int(11) DEFAULT NULL,
PRIMARY KEY (`emp_id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4;
-- ----------------------------
-- Records of t_emp
-- ----------------------------
INSERT INTO `t_emp` VALUES ('1', 'zzhua', '15000.00000', '25');
INSERT INTO `t_emp` VALUES ('2', 'ls', '13000.00000', '24');
INSERT INTO `t_emp` VALUES ('3', 'zj', '14000.00000', '22');
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0modelVersion>
<groupId>com.zzhuagroupId>
<artifactId>common-mapperartifactId>
<version>1.0-SNAPSHOTversion>
<properties>
<spring.version>5.0.2.RELEASEspring.version>
<mybatis.version>3.5.2mybatis.version>
<mybatis.spring.version>1.3.3mybatis.spring.version>
<mysql.version>5.1.47mysql.version>
<druid.version>1.0.9druid.version>
<log4j.version>1.2.17log4j.version>
<pagehelper.version>5.1.10pagehelper.version>
properties>
<dependencies>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-contextartifactId>
<version>${spring.version}version>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-beansartifactId>
<version>${spring.version}version>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-coreartifactId>
<version>${spring.version}version>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-expressionartifactId>
<version>${spring.version}version>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-txartifactId>
<version>${spring.version}version>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-jdbcartifactId>
<version>${spring.version}version>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<version>${mysql.version}version>
dependency>
<dependency>
<groupId>com.alibabagroupId>
<artifactId>druidartifactId>
<version>${druid.version}version>
dependency>
<dependency>
<groupId>org.mybatisgroupId>
<artifactId>mybatisartifactId>
<version>${mybatis.version}version>
dependency>
<dependency>
<groupId>org.mybatisgroupId>
<artifactId>mybatis-springartifactId>
<version>${mybatis.spring.version}version>
dependency>
<dependency>
<groupId>com.github.pagehelpergroupId>
<artifactId>pagehelperartifactId>
<version>${pagehelper.version}version>
dependency>
<dependency>
<groupId>log4jgroupId>
<artifactId>log4jartifactId>
<version>${log4j.version}version>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-testartifactId>
<version>${spring.version}version>
dependency>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<version>4.12version>
dependency>
dependencies>
project>
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/mybatis-demo?useUnicode=true&characterEncoding=utf8&useSSL=true
user=root
password=root
#maxActive \u6700\u5927\u7684\u8FDE\u63A5\u6570
maxActive=20
#initialSize \u521D\u59CB\u5316\u8FDE\u63A5\u7684\u4E2A\u6570
initialSize=1
#maxWait \u6700\u5927\u7B49\u5F85\u65F6\u95F4
maxWait=60000
#minIdle \u6700\u5C0F\u6D3B\u8DC3\u8FDE\u63A5
minIdle=1
filters=stat,log4j,wall
# Global logging configuration
log4j.rootLogger=ERROR, stdout
# MyBatis logging configuration...
log4j.logger.com.zzhua.dao=DEBUG
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
这里需要指明mybatis打印sql语句中dao所在的包
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<context:property-placeholder location="classpath:db.properties" system-properties-mode="FALLBACK"/>
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${driver}">property>
<property name="url" value="${url}">property>
<property name="username" value="${user}">property>
<property name="password" value="${password}">property>
<property name="maxActive" value="${maxActive}">property>
<property name="initialSize" value="${initialSize}">property>
<property name="maxWait" value="${maxWait}">property>
<property name="filters" value="${filters}">property>
bean>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource">property>
<property name="mapperLocations" value="classpath*:mybatis/mapper/*.xml">property>
<property name="configLocation" value="classpath:mybatis/mybatis.cfg.xml">property>
bean>
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.zzhua.dao">property>
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory">property>
bean>
beans>
<configuration>
<settings>
<setting name="logImpl" value="LOG4J"/>
settings>
<typeAliases>
<package name="com.zzhua.entity"/>
typeAliases>
<plugins>
<plugin interceptor="com.github.pagehelper.PageInterceptor" >
<property name="helperDialect" value="mysql"/>
plugin>
plugins>
configuration>
public class Emp{
/*省略setter、getter和toString方法*/
private Integer empId;
private String empName;
private Double empSalary;
private Integer empAge;
}
public interface EmpDao {
int deleteByPrimaryKey(Integer empId);
int insert(Emp record);
int insertSelective(Emp record);
Emp selectByPrimaryKey(Integer empId);
List selectAll(Emp emp);
int updateByPrimaryKeySelective(Emp record);
int updateByPrimaryKey(Emp record);
}
<mapper namespace="com.zzhua.dao.EmpDao">
<resultMap id="BaseResultMap" type="com.zzhua.entity.Emp">
<id column="emp_id" jdbcType="INTEGER" property="empId" />
<result column="emp_name" jdbcType="VARCHAR" property="empName" />
<result column="emp_salary" jdbcType="DOUBLE" property="empSalary" />
<result column="emp_age" jdbcType="INTEGER" property="empAge" />
resultMap>
<sql id="Base_Column_List">
emp_id, emp_name, emp_salary, emp_age
sql>
<select id="selectByPrimaryKey" parameterType="java.lang.Integer" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from t_emp
where emp_id = #{empId,jdbcType=INTEGER}
select>
<select id="selectAll" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from t_emp
<where>
<if test="empId!=null">
and emp_id = #{empId}
if>
<if test="empName!=null and empName!=''">
and emp_name = #{empName}
if>
<if test="emp_salary!=null">
and emp_salary = #{empSalary}
if>
<if test="emp_age!=null">
and empAge = #{empAge}
if>
where>
select>
<delete id="deleteByPrimaryKey" parameterType="java.lang.Integer">
delete from t_emp
where emp_id = #{empId,jdbcType=INTEGER}
delete>
<insert id="insert" keyColumn="emp_id" keyProperty="empId" parameterType="com.zzhua.entity.Emp" useGeneratedKeys="true">
insert into t_emp (emp_name, emp_salary, emp_age
)
values (#{empName,jdbcType=VARCHAR}, #{empSalary,jdbcType=DOUBLE}, #{empAge,jdbcType=INTEGER}
)
insert>
<insert id="insertSelective" keyColumn="emp_id" keyProperty="empId" parameterType="com.zzhua.entity.Emp" useGeneratedKeys="true">
insert into t_emp
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="empName != null">
emp_name,
if>
<if test="empSalary != null">
emp_salary,
if>
<if test="empAge != null">
emp_age,
if>
trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="empName != null">
#{empName,jdbcType=VARCHAR},
if>
<if test="empSalary != null">
#{empSalary,jdbcType=DOUBLE},
if>
<if test="empAge != null">
#{empAge,jdbcType=INTEGER},
if>
trim>
insert>
<update id="updateByPrimaryKeySelective" parameterType="com.zzhua.entity.Emp">
update t_emp
<set>
<if test="empName != null">
emp_name = #{empName,jdbcType=VARCHAR},
if>
<if test="empSalary != null">
emp_salary = #{empSalary,jdbcType=DOUBLE},
if>
<if test="empAge != null">
emp_age = #{empAge,jdbcType=INTEGER},
if>
set>
where emp_id = #{empId,jdbcType=INTEGER}
update>
<update id="updateByPrimaryKey" parameterType="com.zzhua.entity.Emp">
update t_emp
set emp_name = #{empName,jdbcType=VARCHAR},
emp_salary = #{empSalary,jdbcType=DOUBLE},
emp_age = #{empAge,jdbcType=INTEGER}
where emp_id = #{empId,jdbcType=INTEGER}
update>
mapper>
package com.zzhua;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.zzhua.dao.EmpDao;
import com.zzhua.entity.Emp;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import java.util.List;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {
"classpath:application.context-dao.xml"})
public class SpringTest {
@Autowired
private EmpDao empDao;
@Test
public void testEmpDao(){
Emp emp = empDao.selectByPrimaryKey(1);
System.out.println(emp);
}
@Test
public void testPage(){
Page<Emp> empPage = PageHelper.startPage(1, 2);
List<Emp> empList = empDao.selectAll(null);
System.out.println("一共有多少页?"+empPage.getPages());
System.out.println("当前第几页?"+empPage.getPageNum());
System.out.println("每页多少条?"+empPage.getPageSize());
System.out.println("一共多少条"+empPage.getTotal());
for (Emp emp : empList) {
System.out.println(emp);
}
System.out.println(empPage.getResult());
}
}
基于以上工程,在EmpDao中直接使用注解,无须其它扫描配置,即可
@Select("select * from t_emp")
@Results({
// @Results设置结果集与属性映射关系
@Result(id = true,column = "emp_id",property = "empId"),
@Result(column = "emp_name",property = "empName"),
@Result(column = "emp_salary",property = "empSalary"),
@Result(column = "emp_age",property = "empAge")
})
List<Emp> getAll();
@Options(useGeneratedKeys = true, keyProperty = "empId") // 返回主键给参数emp
@Insert("insert into t_emp(emp_name,emp_salary,emp_age)values(#{empName},#{empSalary},#{empAge})")
int addEmp(Emp emp);
测试通过
@Autowired
private EmpDao empDao;
@Test
public void test02(){
List<Emp> all = empDao.getAll();
System.out.println(all);
}
1. sqlSessionFactory
- dataSource 数据源
- mapper.xml sql语句
- mybatis.cfg.xml mybatis核心配置文件
2. MapperScannerConfigurer 【sql语句可以在mapper接口注解里】
- sqlSessionFacotry 【可以从sqlsessionFactory的mapper.xml里】
- mapper接口
创建数据库
SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for t_dept
-- ----------------------------
DROP TABLE IF EXISTS `t_dept`;
CREATE TABLE `t_dept` (
`d_id` int(11) NOT NULL AUTO_INCREMENT,
`d_name` varchar(5) DEFAULT NULL,
PRIMARY KEY (`d_id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COMMENT='部门表';
-- ----------------------------
-- Records of t_dept
-- ----------------------------
INSERT INTO `t_dept` VALUES ('1', '开发部');
INSERT INTO `t_dept` VALUES ('2', '业务部');
生成实体类
public class Dept {
/*省略setter、getter和toString方法*/
private Integer dId;
private String dName;
}
生成mapper.xml
<mapper namespace="com.zzhua.dao.DeptDao">
<resultMap id="BaseResultMap" type="com.zzhua.entity.Dept">
<id column="d_id" jdbcType="INTEGER" property="dId" />
<result column="d_name" jdbcType="VARCHAR" property="dName" />
resultMap>
<sql id="Base_Column_List">
d_id, d_name
sql>
<select id="selectByPrimaryKey" parameterType="java.lang.Integer" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from t_dept
where d_id = #{dId,jdbcType=INTEGER}
select>
<delete id="deleteByPrimaryKey" parameterType="java.lang.Integer">
delete from t_dept
where d_id = #{dId,jdbcType=INTEGER}
delete>
<insert id="insert" parameterType="com.zzhua.entity.Dept">
insert into t_dept (d_id, d_name)
values (#{dId,jdbcType=INTEGER}, #{dName,jdbcType=VARCHAR})
insert>
<insert id="insertSelective" parameterType="com.zzhua.entity.Dept">
insert into t_dept
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="dId != null">
d_id,
if>
<if test="dName != null">
d_name,
if>
trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="dId != null">
#{dId,jdbcType=INTEGER},
if>
<if test="dName != null">
#{dName,jdbcType=VARCHAR},
if>
trim>
insert>
<update id="updateByPrimaryKeySelective" parameterType="com.zzhua.entity.Dept">
update t_dept
<set>
<if test="dName != null">
d_name = #{dName,jdbcType=VARCHAR},
if>
set>
where d_id = #{dId,jdbcType=INTEGER}
update>
<update id="updateByPrimaryKey" parameterType="com.zzhua.entity.Dept">
update t_dept
set d_name = #{dName,jdbcType=VARCHAR}
where d_id = #{dId,jdbcType=INTEGER}
update>
mapper>
生成mapper接口
public interface DeptDao {
int deleteByPrimaryKey(Integer dId);
int insert(Dept record);
int insertSelective(Dept record);
Dept selectByPrimaryKey(Integer dId);
int updateByPrimaryKeySelective(Dept record);
int updateByPrimaryKey(Dept record);
}
一个员工对应一个部门: 查询一个员工,同时把他的部门查询出来
public class Emp{
private String empName;
private Double empSalary;
private Integer empAge;
private Dept dept; // 添加部门属性
}
EmpMapper.xml
<mapper namespace="com.zzhua.dao.EmpDao">
<resultMap id="BaseResultMap" type="com.zzhua.entity.Emp">
<id column="emp_id" jdbcType="INTEGER" property="empId" />
<result column="emp_name" jdbcType="VARCHAR" property="empName" />
<result column="emp_salary" jdbcType="DOUBLE" property="empSalary" />
<result column="emp_age" jdbcType="INTEGER" property="empAge" />
resultMap>
<resultMap id="extendedMap" type="com.zzhua.entity.Emp" extends="BaseResultMap">
<association property="dept" javaType="com.zzhua.entity.Dept">
<id column="d_id" property="dId"/>
<result column="d_name" property="dName"/>
association>
resultMap>
<select id="selectByPrimaryKey" resultMap="extendedMap">
select * from t_emp e left join t_dept d on e.emp_id = d.d_id
where e.emp_id = #{empId}
select>
mapper>
EmpDao
public interface EmpDao{
Emp selectByPrimaryKey(@Param("empId") Integer empId);
}
测试
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {
"classpath:application.context-dao.xml"})
public class SpringTest {
@Autowired
private EmpDao empDao;
@Test
public void test05(){
Emp emp = empDao.selectByPrimaryKey(1);
System.out.println(emp);
}
}
EmpDao
@Select("select * from t_emp e left join t_dept d on e.emp_id = d.d_id"+
"where e.emp_id = #{empId}")
@Results(value = {
@Result(id = true, column = "emp_id", property = "empId"),
@Result(column = "emp_name", property = "empName"),
@Result(column = "emp_salary", property = "empSalary"),
@Result(column = "emp_age", property = "empAge"),
//根据查询结果列名d_id,去查询部门,再把结果设置给emp的部门属性
@Result(column = "d_id",property = "dept",
one = @One(select = "com.zzhua.dao.DeptDao.selectById",
fetchType = FetchType.EAGER))
})
Emp selectById(Integer empId);
DeptDao
@Select("select * from t_dept where d_id = #{id}")
@Results({
@Result(id = true,column = "d_id",property ="dId"),
@Result(id = true,column = "d_name",property ="dName")
})
Dept selectById(@Param("id") Integer id);
测试
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {
"classpath:application.context-dao.xml"})
public class SpringTest {
@Autowired
private EmpDao empDao;
@Test
public void test05(){
Emp emp = empDao.selectById(1);
System.out.println(emp);
}
}
一个部门对应多个员工:查询部门,同时把这个部门下的所有员工查询出来
Dept
public class Dept {
private Integer dId;
private String dName;
private List<Emp> empList; // 添加员工的List集合
}
DeptMapper.xml
<mapper namespace="com.zzhua.dao.DeptDao">
<resultMap id="BaseResultMap" type="com.zzhua.entity.Dept">
<id column="d_id" jdbcType="INTEGER" property="dId" />
<result column="d_name" jdbcType="VARCHAR" property="dName" />
resultMap>
<resultMap id="ExtendedResultMap" type="com.zzhua.entity.Dept" extends="BaseResultMap">
<collection property="empList" ofType="com.zzhua.entity.Emp" >
<id column="emp_id" property="empId"/>
<result column="emp_name" property="empName"/>
<result column="emp_salary" property="empSalary"/>
<result column="emp_age" property="empAge"/>
collection>
resultMap>
<select id="selectByPrimaryKey"
parameterType="java.lang.Integer" resultMap="ExtendedResultMap">
select *
from t_dept d left join t_emp e on d.d_id = e.d_id
where d.d_id = #{dId,jdbcType=INTEGER}
select>
mapper>
测试
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {
"classpath:application.context-dao.xml"})
public class SpringTest {
@Autowired
private DeptDao deptDao;
@Test
public void test05(){
Dept dept = deptDao.selectByPrimaryKey(1);
System.out.println(dept);
}
}
DeptDao
@Select("select * from t_dept where d_id = #{id} ")
@Results({
@Result(id = true,column = "d_id",property = "dId"),
@Result(column = "d_name",property = "dName"),
@Result(column = "d_id",property = "empList",
<!--根据部门id,查询这个部门下的所有员工集合,再把结果设置给部门的empList属性-->
many = @Many(select = "com.zzhua.dao.EmpDao.selectEmpsByDid",
fetchType = FetchType.EAGER))
})
Dept selectById(@Param("id") Integer id);
EmpDao
@Select("select * from t_emp where d_id = #{id} ")
@Results({
@Result(id = true, column = "emp_id", property = "empId"),
@Result(column = "emp_name", property = "empName"),
@Result(column = "emp_salary", property = "empSalary"),
@Result(column = "emp_age", property = "empAge")
})
List<Emp> selectEmpsByDid(@Param("id") Integer id);
测试
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {
"classpath:application.context-dao.xml"})
public class SpringTest {
@Autowired
private DeptDao deptDao;
@Test
public void test05(){
Dept dept = deptDao.selectById(1);
System.out.println(dept);
}
}
Customer
public class Customer {
private Integer id;
private String customerName;
private List<Goods> goodsList;
}
Goods
public class Goods {
private Integer id;
private String goodsName;
private List<Customer> customerList;
}
CustomerMapper
public interface CustomerMapper {
Customer getById(Integer id);
List<Customer> getBy2Id(@Param("id1") int id1, @Param("id2") int id2);
}
CustomerMapper.xml
<mapper namespace="com.zzhua.dao.CustomerMapper">
<resultMap id="BaseResultMap" type="com.zzhua.entity.Customer">
<id column="id" jdbcType="INTEGER" property="id" />
<result column="customer_name" jdbcType="VARCHAR" property="customerName" />
resultMap>
<sql id="Base_Column_List">
id, customer_name
sql>
<resultMap id="ExtendedMap" type="Customer" extends="BaseResultMap">
<collection property="goodsList" ofType="com.zzhua.entity.Goods">
<result column="gid" property="id"/>
<result column="goods_name" property="goodsName"/>
collection>
resultMap>
<select id="getById" resultMap="ExtendedMap">
select * from t_customer c,t_cg cg,t_goods g
where c.id = cg.cid and g.id = cg.gid and c.id = #{id};
select>
<select id="getBy2Id" resultMap="ExtendedMap">
select * from t_customer c,t_cg cg,t_goods g
where c.id = cg.cid and g.id = cg.gid and (c.id = #{param1} or c.id = #{param2})
select>
mapper>
测试
1.getById查询结果
顾客表 t_custome 顾客购买商品的记录表 t_cg、 商品表 t_goods
顾客ID | 顾客名字 | 顾客ID | 商品ID | 商品ID | 商品名称 |
---|---|---|---|---|---|
id | customer_name | c_id | g_id | id1 | goods_name |
1 | a | 1 | 1 | 1 | 笔记本电脑 |
1 | a | 1 | 2 | 2 | 移动硬盘 |
1 | a | 1 | 3 | 3 | 鼠标 |
// 一个客户买了3件商品,将3种商品封装到这个顾客的商品列表里
@Test
public void test007() {
Customer customer = customerMapper.getById(1);
System.out.println("---------------------------");
System.out.println(customer.getCustomerName());
for (Goods goods : customer.getGoodsList()) {
System.out.println(goods);
}
System.out.println("---------------------------");
}
// 测试结果
---------------------------
a
Goods{
id=1, goodsName='笔记本电脑', customerList=null}
Goods{
id=2, goodsName='移动硬盘', customerList=null}
Goods{
id=3, goodsName='鼠标', customerList=null}
---------------------------
2.getBy2Id查询结果
顾客ID | 顾客名字 | 顾客ID | 商品ID | 商品ID | 商品名称 |
---|---|---|---|---|---|
id | customer_name | c_id | g_id | id1 | goods_name |
1 | a | 1 | 1 | 1 | 笔记本电脑 |
1 | a | 1 | 2 | 2 | 移动硬盘 |
1 | a | 1 | 3 | 3 | 鼠标 |
2 | b | 2 | 1 | 1 | 笔记本电脑 |
2 | b | 2 | 2 | 2 | 移动硬盘 |
// 查询了2位顾客,他们分别买了不同的商品;将他们各自的商品封装到他们的商品集合属性里
@Test
public void test008() {
List<Customer> customerList = customerMapper.getBy2Id(1, 2);
for (Customer customer : customerList) {
System.out.println("---------------------------");
System.out.println(customer.getCustomerName());
for (Goods goods : customer.getGoodsList()) {
System.out.println(goods);
}
System.out.println("---------------------------");
}
}
// 测试结果
---------------------------
a
Goods{
id=1, goodsName='笔记本电脑', customerList=null}
Goods{
id=2, goodsName='移动硬盘', customerList=null}
Goods{
id=3, goodsName='鼠标', customerList=null}
---------------------------
---------------------------
b
Goods{
id=2, goodsName='移动硬盘', customerList=null}
Goods{
id=3, goodsName='鼠标', customerList=null}
---------------------------
1.在mybatis中,核心就是先用sql语句,查询出结果。一定要先把sql语句写出来,获取查询结果集。
2.查询结果出来后,剩下的就是指定封映射装的规则。
延迟加载也叫懒加载,在查询的时候,有时候没有必要用到其它的信息,这时,可以用延迟加载。
比如查询员工信息的时候,并不需要查询员工对应的部门信息,而我们的sql是通过员工表和部门表连接查询得到结果集。将结果集封装成员工对象。在这个过程里,多了一个连接查询的步骤。因此,可以使用延迟加载,先只查询员工信息(不连接部门表),在需要查询该员工对应的部门信息时,再执行查询部门的sql语句
// 员工查询接口
Emp getById(@Param("id") Integer id);
// 对应的resultMap和sql
<resultMap id="BaseResultMap" type="com.zzhua.entity.Emp">
<id column="emp_id" jdbcType="INTEGER" property="empId" />
<result column="emp_name" jdbcType="VARCHAR" property="empName" />
<result column="emp_salary" jdbcType="DOUBLE" property="empSalary" />
<result column="emp_age" jdbcType="INTEGER" property="empAge" />
resultMap>
<resultMap id="LazyLoadMap" type="com.zzhua.entity.Emp" extends="BaseResultMap">
<id column="emp_id" jdbcType="INTEGER" property="empId" />
<result column="emp_name" jdbcType="VARCHAR" property="empName" />
<result column="emp_salary" jdbcType="DOUBLE" property="empSalary" />
<result column="emp_age" jdbcType="INTEGER" property="empAge" />
<association property="dept" javaType="com.zzhua.entity.Dept" column="d_id"
fetchType="lazy" select="com.zzhua.dao.DeptDao.getByDId" >
association>
resultMap>
<select id="getById" resultMap="LazyLoadMap">
select * from t_emp where emp_id = #{id}
select>
测试
@Test
public void test002(){
Emp emp = empDao.getById(1);
System.out.println(emp.getEmpName()); // 没有用到部门信息,因此没有加载部门信息
System.out.println("-------------------------");
System.out.println(emp.getDept()); // 用到了部门信息,此时再加载
}
// 打印结果
DEBUG [main] - ==> Preparing: select * from t_emp where emp_id = ?
DEBUG [main] - ==> Parameters: 1(Integer)
DEBUG [main] - <== Total: 1
zzhua
-------------------------
DEBUG [main] - ==> Preparing: select * from t_dept where d_id = ?
DEBUG [main] - ==> Parameters: 1(Integer)
DEBUG [main] - <== Total: 1
Dept{
dId=1, dName='开发部', empList=null}
通过使用缓存,可以减少对数据库的访问次数,第一次查询时,将查询结果放入缓存;第二次查询时,直接从缓存中获取数据。mybatis缓存分为一级缓存和二级缓存。
环境准备
<settings>
<setting name="logImpl" value="STDOUT_LOGGING"/>
settings>
添加findById方法
<select id="findById" resultMap="BaseResultMap">
select * from t_emp where emp_id = #{id}
select>
Emp findById(@Param("id") Integer id);
测试
@Test
public void test002(){
empDao.findById(1);
empDao.findById(1);
}
// 执行结果,很显然查询了两次,
// mybatis和spring集成后,每次查询都会创建sqlSession对象
Creating a new SqlSession // 创建sqlsession
==> Preparing: select * from t_emp where emp_id = ?
==> Parameters: 1(Integer)
<== Columns: emp_id, emp_name, emp_salary, emp_age, d_id
<== Row: 1, zzhua, 15000.00000, 25, 1
<== Total: 1
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@20bd8be5]
--------------------
Creating a new SqlSession // 创建sqlsession
==> Preparing: select * from t_emp where emp_id = ?
==> Parameters: 1(Integer)
<== Columns: emp_id, emp_name, emp_salary, emp_age, d_id
<== Row: 1, zzhua, 15000.00000, 25, 1
<== Total: 1
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@72437d8d]
概念
sqlsession级别,默认开启
sqlsession对象中有一个hashmap用于存储缓存数据,不同的sqlsession之间缓存数据互不影响。
一级缓存的作用域是SqlSession范围级别的,在同一个Sqlsession中,执行两次相同的sql语句时,第一次执行完毕,会将结果保存到缓存中,第二次查询时,会直接从缓存中获取数据。
一旦sqlsession执行了DML(增删改)操作,Mybatis会将缓存数据清空,来保证数据的准确定。
使用一级缓存
mybatis一级缓存是sqlsession级别,并且是默认开启的,但是每次查询都会创建一个sqlSession对象。
需要开启事务,因为同一个事务中spring使用的是同一个SqlSession,才会走一级缓存
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<property name="dataSource" ref="dataSource">property>
bean>
<tx:annotation-driven/>
beans>
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations =
{
"classpath:spring-dao.xml","classpath:spring-service.xml"})
public class SpringTest {
@Autowired
private EmpService empService;
@Test
@Transactional
public void test002(){
empService.findById(1);
System.out.println("--------------------");
empService.findById(1);
}
}
// 执行结果 开启事务后,在同一个事务里,用的是同一个sqlSession,第二次查询走了sqlSession的缓存
Creating a new SqlSession
==> Preparing: select * from t_emp where emp_id = ?
==> Parameters: 1(Integer)
<== Columns: emp_id, emp_name, emp_salary, emp_age, d_id
<== Row: 1, zzhua, 15000.00000, 25, 1
<== Total: 1
Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@3f67593e]
--------------------
Fetched SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@3f67593e] from current transaction
Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@3f67593e]
Transaction synchronization deregistering SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@3f67593e]
Transaction synchronization closing SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@3f67593e]
概念
使用二级缓存
因为二级缓存是跨sqlsession的,所以可以不需要使用事务(即每次查询都会创建一个新的sqlSession)。
<mapper namespace="com.zzhua.dao.EmpDao">
<resultMap id="BaseResultMap" type="com.zzhua.entity.Emp">
<id column="emp_id" jdbcType="INTEGER" property="empId" />
<result column="emp_name" jdbcType="VARCHAR" property="empName" />
<result column="emp_salary" jdbcType="DOUBLE" property="empSalary" />
<result column="emp_age" jdbcType="INTEGER" property="empAge" />
resultMap>
<cache/>
<select id="findById" resultMap="BaseResultMap">
select * from t_emp where emp_id = #{id}
select>
mapper>
<configuration>
<settings>
<setting name="logImpl" value="STDOUT_LOGGING"/>
<setting name="cacheEnabled" value="true"/>
settings>
<typeAliases>
<package name="com.zzhua.entity"/>
typeAliases>
<plugins>
<plugin interceptor="com.github.pagehelper.PageInterceptor" >
<property name="helperDialect" value="mysql"/>
plugin>
plugins>
configuration>
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations =
{
"classpath:spring-dao.xml","classpath:spring-tx.xml"})
public class SpringTest {
@Autowired
private EmpDao empDao;
@Test
// @Transactional // 不开启事务(即每次查询都会创建新的sqlSession)
public void test002(){
empDao.findById(1);
System.out.println("--------------------");
empDao.findById(1);
}
}
// 执行结果
Creating a new SqlSession
SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@1a5a4e19] was not registered for synchronization because synchronization is not active
Cache Hit Ratio [com.zzhua.dao.EmpDao]: 0.0 // 没有从缓存中找到
JDBC Connection [com.alibaba.druid.proxy.jdbc.ConnectionProxyImpl@20435c40] will not be managed by Spring
==> Preparing: select * from t_emp where emp_id = ?
==> Parameters: 1(Integer)
<== Columns: emp_id, emp_name, emp_salary, emp_age, d_id
<== Row: 1, zzhua, 15000.00000, 25, 1
<== Total: 1
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@1a5a4e19]
--------------------
Creating a new SqlSession
SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@a87f8ec] was not registered for synchronization because synchronization is not active
Cache Hit Ratio [com.zzhua.dao.EmpDao]: 0.5 // 命中缓存
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@a87f8ec]
导入ehcache的依赖
<dependency>
<groupId>org.mybatisgroupId>
<artifactId>mybatis-ehcacheartifactId>
<version>1.0.0version>
dependency>
<dependency>
<groupId>net.sf.ehcachegroupId>
<artifactId>ehcache-coreartifactId>
<version>2.4.3version>
dependency>
编写ehcache.xml
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd">
<diskStore/>
<defaultCache maxElementsInMemory="1000"
maxElementsOnDisk="10000000"
eternal="false"
overflowToDisk="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU">
defaultCache>
ehcache>
开启缓存
mybatis.cfg.xml
<configuration>
<settings>
<setting name="logImpl" value="STDOUT_LOGGING"/>
<setting name="cacheEnabled" value="true"/>
settings>
<typeAliases>
<package name="com.zzhua.entity"/>
typeAliases>
<plugins>
<plugin interceptor="com.github.pagehelper.PageInterceptor" >
<property name="helperDialect" value="mysql"/>
plugin>
plugins>
configuration>
EmpDao.xml
<mapper namespace="com.zzhua.dao.EmpDao">
<cache type="org.mybatis.caches.ehcache.EhcacheCache">
<property name="timeToIdleSeconds" value="3600"/>
<property name="timeToLiveSeconds" value="3600"/>
<property name="memoryStoreEvictionPolicy" value="LRU"/>
cache>
<resultMap id="BaseResultMap" type="com.zzhua.entity.Emp">
<id column="emp_id" jdbcType="INTEGER" property="empId" />
<result column="emp_name" jdbcType="VARCHAR" property="empName" />
<result column="emp_salary" jdbcType="DOUBLE" property="empSalary" />
<result column="emp_age" jdbcType="INTEGER" property="empAge" />
resultMap>
<select id="findById" resultMap="BaseResultMap">
select * from t_emp where emp_id = #{id}
select>
mapper>
实体类不需要实现Serializable接口
测试
@Test
//@Transactional // 不使用事务
public void test002() {
empDao.findById(1);
System.out.println("--------------------");
empDao.findById(1);
}
//执行结果
Creating a new SqlSession
SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@3e2059ae] was not registered for synchronization because synchronization is not active
Cache Hit Ratio [com.zzhua.dao.EmpDao]: 0.0
JDBC Connection [com.alibaba.druid.proxy.jdbc.ConnectionProxyImpl@1608bcbd] will not be managed by Spring
==> Preparing: select * from t_emp where emp_id = ?
==> Parameters: 1(Integer)
<== Columns: emp_id, emp_name, emp_salary, emp_age, d_id
<== Row: 1, zzhua, 15000.00000, 25, 1
<== Total: 1
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@3e2059ae]
--------------------
Creating a new SqlSession
SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@74960bfa] was not registered for synchronization because synchronization is not active
Cache Hit Ratio [com.zzhua.dao.EmpDao]: 0.5
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@74960bfa]
if 标签通常用于 WHERE 语句、UPDATE 语句、INSERT 语句中,通过判断参数值来决定是否使用某个查询条件、判断是否更新某一个字段、判断是否插入某个字段的值。
<if test="name != null and name != ''">
and NAME = #{name}
if>
当 name 值为 null 时,查询语句会出现 “WHERE AND” 的情况,解决该情况除了将"WHERE"改为“WHERE 1=1”之外,还可以利用 where标签。
这个“where”标签会知道如果它包含的标签中有返回值的话,它就插入一个‘where’。此外,如果标签返回的内容是以 AND 或 OR 开头的,则它会剔除掉。
<select id="getStudentListWhere" parameterType="Object" resultMap="BaseResultMap">
SELECT * from STUDENT
<where>
<if test="name!=null and name!='' ">
NAME LIKE CONCAT(CONCAT('%', #{name}),'%')
if>
<if test="hobby!= null and hobby!= '' ">
AND hobby = #{hobby}
if>
where>
select>
<update id="updateUser" parameterType="com.pojo.User">
UPDATE user
<set>
<if test="username!= null and username != '' ">
username = #{username},
if>
<if test="sex!= null and sex!= '' ">
sex = #{sex},
if>
<if test="birthday != null ">
birthday = #{birthday},
if>
set>
WHERE user_id = #{userid}
update>
<select id="selectByNameOrHobby" resultMap="BaseResultMap">
select * from student
<trim prefix="WHERE" prefixOverrides="AND | OR">
<if test="name != null and name.length()>0">
AND name=#{name}
if>
<if test="hobby != null and hobby.length()>0">
AND hobby=#{hobby}
if>
trim>
select>
主要用于构建 in 条件,可在 sql 中对集合进行迭代。也常用到批量删除、添加等操作中
<select id="selectIn" resultMap="BaseResultMap">
select name,hobby from student
where id in
<foreach item="item" index="index" collection="list" open="("
separator="," close=")">
#{item}
foreach>
select>
按顺序判断 when 中的条件出否成立,如果有一个成立,则 choose 结束。当 choose 中所有 when
的条件都不满则时,则执行 otherwise 中的 sql
<select id="getStudentListChoose" parameterType="Student" resultMap="BaseResultMap">
SELECT * from STUDENT WHERE 1=1
<where>
<choose>
<when test="Name!=null and student!='' ">
AND name LIKE CONCAT(CONCAT('%', #{student}),'%')
when>
<when test="hobby!= null and hobby!= '' ">
AND hobby = #{hobby}
when>
<otherwise>
AND AGE = 15
otherwise>
choose>
where>
select>
基于以上工程,pom.xml中继续加入tkmapper的依赖
<dependency>
<groupId>tk.mybatisgroupId>
<artifactId>mapperartifactId>
<version>${tkmapper.version}version>
dependency>
org.mybatis.spring.mapper.MapperScannerConfigurer
修改为org.mybatis.spring.mapper.MapperScannerConfigurer
<bean class="tk.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.zzhua.dao">property>
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory">property>
bean>
@Table(name="t_emp") // 建立实体类和数据库表之间的对应关系
public class Emp{
@Id // 定义主键
@GeneratedValue(strategy=GenerationType.IDENTITY) // 自增主键,并返回给对象,
// @GeneratedValue(strategy=GenerationType.IDENTITY,
// generator = "select SEQ_ID.nextval from dual" // 序列主键
// )
private Integer empId;
@Column(name = "emp_name") // 建立属性和数据库表字段之间的对应关系,
private String empName; // 默认支持驼峰式,此处可省略
private Double empSalary;
private Integer empAge;
@Transient // 标记不与数据库表字段对应的实体类字段
privateStringotherThings;
//...省略setter、getter方法
}
public interface EmpDao extends Mapper{
}
测试成功
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {
"classpath:application.context-dao.xml"})
public class SpringTest {
@Autowired
private EmpDao empDao;
@Test
public void test05(){
Emp emp = empDao.selectByPrimaryKey(1);
System.out.println(emp);
}
}
注意:
tkMapper中的Mapper接口
,就有了基础的增删改查的方法,但是没有多表查询的功能。因此,要用到多表查询,还是须在mapper.xml文件中自己写!实体类封装查询条件生成 WHERE 子句的规则
- 使用非空的值生成 WHERE 子句
- 在条件表达式中使用 “=” 进行比较
要求必须返回一个实体类结果,如果有多个,则会抛出异常
需要使用@Id 主键明确标记和数据库表主键字段对应的实体类字段
否则通用 Mapper 会将所有实体类字段作为联合主键
非主键字段如果为 null 值,则不加入到 SQL 语句
插件注入即可
sqlSessionFactory中注入Interceptor,而PageInterceptor是它的一个实现,
PageInteceptor中定义了default_dialect_class = “com.github.pagehelper.PageHelper”;
下面进入源码中其实是把properties配置给了pageHelper
@Bean
PageInterceptor pageInterceptor(){
PageInterceptor pageInterceptor = new PageInterceptor();
Properties properties = new Properties();
properties.setProperty("helperDialect", "mysql");
pageInterceptor.setProperties(properties); // 由此可进入源码,
return pageInterceptor;
}
SpringBoot整合mybatis,注解,分页查询
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0modelVersion>
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>2.1.8.RELEASEversion>
<relativePath/>
parent>
<groupId>com.zzhuagroupId>
<artifactId>demo-mybatisartifactId>
<version>0.0.1-SNAPSHOTversion>
<name>demo-mybatisname>
<description>Demo project for Spring Bootdescription>
<properties>
<java.version>1.8java.version>
properties>
<dependencies>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<scope>runtimescope>
dependency>
<dependency>
<groupId>org.mybatis.spring.bootgroupId>
<artifactId>mybatis-spring-boot-starterartifactId>
<version>2.1.3version>
dependency>
<dependency>
<groupId>com.github.pagehelpergroupId>
<artifactId>pagehelperartifactId>
<version>5.1.7version>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-devtoolsartifactId>
<scope>runtimescope>
<optional>trueoptional>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-configuration-processorartifactId>
<optional>trueoptional>
dependency>
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
<optional>trueoptional>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-testartifactId>
<scope>testscope>
<exclusions>
<exclusion>
<groupId>org.junit.vintagegroupId>
<artifactId>junit-vintage-engineartifactId>
exclusion>
exclusions>
dependency>
dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-maven-pluginartifactId>
plugin>
plugins>
build>
project>
yml文件配置
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/zblog?serverTimezone=UTC
username: root
password: root
mybatis:
mapper-locations: classpath:mapper/*Mapper.xml
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
启动类
@SpringBootApplication
@MapperScan("com.zzhua.mapper")
public class DemoMybatisApplication {
public static void main(String[] args) {
SpringApplication.run(DemoMybatisApplication.class, args);
}
@Bean
PageInterceptor pageInterceptor(){
//
PageInterceptor pageInterceptor = new PageInterceptor();
Properties properties = new Properties();
properties.setProperty("helperDialect", "mysql");
pageInterceptor.setProperties(properties);
return pageInterceptor;
}
}
自动生成文件
public interface TagMapper {
int deleteByPrimaryKey(Integer id);
int insert(Tag record);
int insertSelective(Tag record);
Tag selectByPrimaryKey(Integer id);
int updateByPrimaryKeySelective(Tag record);
int updateByPrimaryKey(Tag record);
@Results({
@Result(id = true,property = "id",column = "id"),
@Result(property = "tagName",column = "tag_name"),
@Result(property = "createTime",column = "create_time")
})
@Select("select * from t_tag t1 right join t_article_tag t2 on t1.id = t2.tag_id
where t2.article_id = #{
articleId} ")
List<Tag> findTags(@Param("articleId") Integer articleId);
}
public interface ArticleMapper {
int deleteByPrimaryKey(Integer id);
int insert(Article record);
int insertSelective(Article record);
Article selectByPrimaryKey(Integer id);
int updateByPrimaryKeySelective(Article record);
int updateByPrimaryKey(Article record);
@Results({
@Result(id = true, property = "id", column = "id"),
@Result(property = "title", column = "title"),
@Result(property = "content", column = "content"),
@Result(property = "tagList",column = "id",
many = @Many(select = "com.zzhua.mapper.TagMapper.findTags"))
})
@Select("select * from t_article")
List<ArticleVo> findAll();
}
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0modelVersion>
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>2.1.8.RELEASEversion>
<relativePath/>
parent>
<groupId>com.zzhuagroupId>
<artifactId>demo-mybatisplusartifactId>
<version>0.0.1-SNAPSHOTversion>
<name>demo-mybatisplusname>
<description>Demo project for Spring Bootdescription>
<properties>
<java.version>1.8java.version>
properties>
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>p6spygroupId>
<artifactId>p6spyartifactId>
<version>3.8.6version>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<scope>runtimescope>
dependency>
<dependency>
<groupId>com.baomidougroupId>
<artifactId>mybatis-plus-boot-starterartifactId>
<version>3.3.2version>
dependency>
<dependency>
<groupId>com.baomidougroupId>
<artifactId>mybatis-plus-generatorartifactId>
<version>3.3.2version>
dependency>
<dependency>
<groupId>org.freemarkergroupId>
<artifactId>freemarkerartifactId>
<version>2.3.30version>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starterartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-devtoolsartifactId>
<scope>runtimescope>
<optional>trueoptional>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-configuration-processorartifactId>
<optional>trueoptional>
dependency>
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
<optional>trueoptional>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-testartifactId>
<scope>testscope>
<exclusions>
<exclusion>
<groupId>org.junit.vintagegroupId>
<artifactId>junit-vintage-engineartifactId>
exclusion>
exclusions>
dependency>
dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-maven-pluginartifactId>
plugin>
plugins>
build>
project>
yml
# DataSource Config
spring:
datasource:
driver-class-name: com.p6spy.engine.spy.P6SpyDriver
url: jdbc:p6spy:mysql://127.0.0.1:3306/test?serverTimezone=UTC
username: root
password: root
spy.properties
#3.2.1以上使用
modulelist=com.baomidou.mybatisplus.extension.p6spy.MybatisPlusLogFactory,com.p6spy.engine.outage.P6OutageFactory
#3.2.1以下使用或者不配置
#modulelist=com.p6spy.engine.logging.P6LogFactory,com.p6spy.engine.outage.P6OutageFactory
# 自定义日志打印
logMessageFormat=com.baomidou.mybatisplus.extension.p6spy.P6SpyLogger
#日志输出到控制台
appender=com.baomidou.mybatisplus.extension.p6spy.StdoutLogger
# 使用日志系统记录 sql
#appender=com.p6spy.engine.spy.appender.Slf4JLogger
# 设置 p6spy driver 代理
deregisterdrivers=true
# 取消JDBC URL前缀
useprefix=true
# 配置记录 Log 例外,可去掉的结果集有error,info,batch,debug,statement,commit,rollback,result,resultset.
excludecategories=info,debug,result,commit,resultset
# 日期格式
dateformat=yyyy-MM-dd HH:mm:ss
# 实际驱动可多个
#driverlist=org.h2.Driver
# 是否开启慢SQL记录
outagedetection=true
# 慢SQL记录标准 2 秒
outagedetectioninterval=2
代码生成器
package com.zzhua;
import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class CodeGenerator {
/**
*
* 读取控制台内容
*
*/
public static String scanner(String tip) {
Scanner scanner = new Scanner(System.in);
StringBuilder help = new StringBuilder();
help.append("请输入" + tip + ":");
System.out.println(help.toString());
if (scanner.hasNext()) {
String ipt = scanner.next();
if (StringUtils.isNotEmpty(ipt)) {
return ipt;
}
}
throw new MybatisPlusException("请输入正确的" + tip + "!");
}
public static void main(String[] args) {
// 代码生成器
AutoGenerator mpg = new AutoGenerator();
// set freemarker engine
mpg.setTemplateEngine(new FreemarkerTemplateEngine());
// 全局配置
GlobalConfig gc = new GlobalConfig();
String projectPath = System.getProperty("user.dir");
gc.setOutputDir(projectPath + "/src/main/java");
gc.setAuthor("zzhua");
gc.setOpen(false);
// gc.setSwagger2(true); 实体属性 Swagger2 注解
mpg.setGlobalConfig(gc);
// 数据源配置
DataSourceConfig dsc = new DataSourceConfig();
dsc.setUrl("jdbc:mysql://localhost:3306/test?serverTimezone=UTC&useUnicode=true&useSSL=false&characterEncoding=utf8");
// dsc.setSchemaName("public");
dsc.setDriverName("com.mysql.jdbc.Driver");
dsc.setUsername("root");
dsc.setPassword("root");
mpg.setDataSource(dsc);
// 包配置
PackageConfig pc = new PackageConfig();
pc.setModuleName(scanner("模块名"));
pc.setParent("com.zzhua");
mpg.setPackageInfo(pc);
// 自定义配置
InjectionConfig cfg = new InjectionConfig() {
@Override
public void initMap() {
// to do nothing
}
};
// 如果模板引擎是 freemarker
String templatePath = "/templates/mapper.xml.ftl";
// 如果模板引擎是 velocity
// String templatePath = "/templates/mapper.xml.vm";
// 自定义输出配置
List<FileOutConfig> focList = new ArrayList<>();
// 自定义配置会被优先输出
focList.add(new FileOutConfig(templatePath) {
@Override
public String outputFile(TableInfo tableInfo) {
// 自定义输出文件名 , 如果你 Entity 设置了前后缀、此处注意 xml 的名称会跟着发生变化!!
return projectPath + "/src/main/resources/mapper/" + pc.getModuleName()
+ "/" + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML;
}
});
/*
cfg.setFileCreate(new IFileCreate() {
@Override
public boolean isCreate(ConfigBuilder configBuilder, FileType fileType, String filePath) {
// 判断自定义文件夹是否需要创建
checkDir("调用默认方法创建的目录,自定义目录用");
if (fileType == FileType.MAPPER) {
// 已经生成 mapper 文件判断存在,不想重新生成返回 false
return !new File(filePath).exists();
}
// 允许生成模板文件
return true;
}
});
*/
cfg.setFileOutConfigList(focList);
mpg.setCfg(cfg);
// 配置模板
TemplateConfig templateConfig = new TemplateConfig();
// 配置自定义输出模板
//指定自定义模板路径,注意不要带上.ftl/.vm, 会根据使用的模板引擎自动识别
// templateConfig.setEntity("templates/entity2.java");
// templateConfig.setService();
// templateConfig.setController();
templateConfig.setXml(null);
mpg.setTemplate(templateConfig);
// 策略配置
StrategyConfig strategy = new StrategyConfig();
strategy.setNaming(NamingStrategy.underline_to_camel);
strategy.setColumnNaming(NamingStrategy.underline_to_camel);
// strategy.setSuperEntityClass("你自己的父类实体,没有就不用设置!");
strategy.setEntityLombokModel(true);
strategy.setRestControllerStyle(true);
// 公共父类
//strategy.setSuperControllerClass("你自己的父类控制器,没有就不用设置!");
// 写于父类中的公共字段
//strategy.setSuperEntityColumns("id");
strategy.setInclude(scanner("表名,多个英文逗号分割").split(","));
strategy.setControllerMappingHyphenStyle(true);
// strategy.setTablePrefix(pc.getModuleName() + "_");
strategy.setTablePrefix("t_");
mpg.setStrategy(strategy);
mpg.setTemplateEngine(new FreemarkerTemplateEngine());
mpg.execute();
}
}
实体类
/**
*
*
*
*
* @author zzhua
* @since 2020-06-24
*/
@Data
@EqualsAndHashCode(callSuper = false)
@TableName("t_user")
@ToString
public class User implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
private String name;
private LocalDate birth;
private String rightSign;
}
添加自定义方法
/**
*
* Mapper 接口
*
*
* @author zzhua
* @since 2020-06-24
*/
public interface UserMapper extends BaseMapper<User> {
@Select("select * from t_user")
IPage<User> paging(Page page, QueryWrapper wrapper);
@Select("select * from t_user ${ew.customSqlSegment}")
List<User> getList(@Param(Constants.WRAPPER)QueryWrapper wrapper);
}
其它具体做法参看官网即可