本次博文有疑问,请先看MyBatis(1)-简单入门MyBatis(2)-全局配置文件!

如在有疑问,请留言或者咨询博主,博主每天都在!谢谢!

映射文件:

主要是在xxxmapper.xml文件里的配置

映射文件指导这MyBatis如何进行数据库的增删该查,有着很重要的意义。

下面开始进入正题,最后会发一个完整版的代码

因为实现的主要内容是增删改查,所以我们现在接口类中定义好相关的方法,后面不在进行单一的定义!

工程的目录如下:

EmployeeMapper.java

package com.MrChengs.dao;

import java.util.Map;

import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select; import com.MrChengs.bean.Employee; public interface EmployeeMapper {   //我们直接传入map
public Employee getByMap(Map<String,Object> map); //查询满足两个条件的数据
public Employee getByIdAndNames(@Param("id")int id,@Param("name")String name); //查询
public Employee getEmployee(int id); //增加
public void addEmp(Employee employee); //更新
public void updateEmp(Employee employee); //删除
public void deleteById(int id);
}

1)insert-映射插入语句

1.1)EmployeeMapper.xml

  <insert id="addEmp" >

             insert into test(name,gender,email) values(#{name},#{gender},#{email})

     </insert>
 
1.2)在测试类中MyBatisTest.java
   @Test
public void test2() throws IOException{
//1.得到SqlSeesionFactory
SqlSessionFactory sessionFactory = getSqlSessionFactory();
//2.得到SqlSession
SqlSession sqlSession = sessionFactory.openSession();
try{
EmployeeMapper mapper = (EmployeeMapper) sqlSession.getMapper(EmployeeMapper.class);
//手动添加数据:
Employee em = new Employee( "zhangsan", "boy", "zhangsan@qq.com");
mapper.addEmp(em);
//手动提交数据
sqlSession.commit();
}finally{
sqlSession.close(); }}

1.3)测试成功

2)update映射更新语句

2.1)EmployeeMapper.xml

 <update id="updateEmp">
update test set name=#{name},gender=#{gender} where id=#{id}
</update>

2.2)测试类中

   @Test
public void test3() throws IOException{
//1.得到SqlSeesionFactory
SqlSessionFactory sessionFactory = getSqlSessionFactory();
//2.得到SqlSession
SqlSession sqlSession = sessionFactory.openSession();
try{
EmployeeMapper mapper = (EmployeeMapper) sqlSession.getMapper(EmployeeMapper.class);
//手动添加数据:
Employee em = new Employee( 6,"Jerry", "gril", null);
mapper.updateEmp(em);
//手动提交数据
sqlSession.commit();
}finally{
sqlSession.close();}}

2.3)测试成功!

3)delete-映射删除操作

3.1)EmployeeMapper.xml

     <delete id="deleteById">
delete from test where id=#{id}
</delete>

3.2)测试类中

 @Test
public void test4() throws IOException{
//1.得到SqlSeesionFactory
SqlSessionFactory sessionFactory = getSqlSessionFactory();
//2.得到SqlSession
SqlSession sqlSession = sessionFactory.openSession();
try{
EmployeeMapper mapper = (EmployeeMapper) sqlSession.getMapper(EmployeeMapper.class);
//手动添加数据:
mapper.deleteById(6);
//手动提交数据
sqlSession.commit();
}finally{
sqlSession.close();}}

3.3)测试成功!

4)关于主键的值问题

有时候需要用到主键值的问题,所以我们需要去学习这个知识点!

4.1)EmployeeMapper.xml

    <!-- useGeneratedKeys="true"使用自增主键获取主键的值 -->
<!-- keyProperty=""接受对应的主键值-->
<insert id="addEmp" useGeneratedKeys="true" keyProperty="id">
insert into test(name,gender,email) values(#{name},#{gender},#{email})
</insert>

4.2)测试类

  @Test
public void test2() throws IOException{
//1.得到SqlSeesionFactory
SqlSessionFactory sessionFactory = getSqlSessionFactory();
//2.得到SqlSession
SqlSession sqlSession = sessionFactory.openSession();
try{
EmployeeMapper mapper = (EmployeeMapper) sqlSession.getMapper(EmployeeMapper.class);
//手动添加数据:
Employee em = new Employee( "zhangsan", "boy", "zhangsan@qq.com");
mapper.addEmp(em);
//获取主键值的属性值进行打印
System.out.println(em.getId());
//手动提交数据
sqlSession.commit();
}finally{
sqlSession.close();
}
}

4.3)测试成功

5)参数处理

5.1)单个参数:MyBatis不会做任何处理

    #{参数名} : 取出参数值

5.1.1)xml配置文件中

<select id="getId" resultType="com.MrChengs.bean.Employee">
select id,name,gender,email from test where id = #{idabc}
</select>

5.1.2)测试类

@Test
public void test() throws IOException {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = (SqlSessionFactory) new
SqlSessionFactoryBuilder().build(inputStream);
SqlSession session = sqlSessionFactory.openSession();
try{
Employee employee = session.selectOne("getId",5);
System.out.println(employee);
}finally{
session.close();
}
}

5.1.3)测试是成功的!

5.2)多个参数时

MyBatis会做特殊的处理

多个参数时封装成map

key param1 ,param2......

value 传入的值

5.2.1)接口类中的查询代码设计如上所展示的

public Employee getByIdAndNames(@Param("id")int id,@Param("name")String name);
此时去掉@param:
public Employee getByIdAndNames(int id,String name);

5.2.2) xml文件

<select id="getByIdAndNames" resultType="com.MrChengs.bean.Employee" >
select id,name,gender,email from test where id = #{id} and name=#{name}
</select>

5.2.3)测试代码

  @Test
public void test5() throws IOException{
SqlSessionFactory sessionFactory = getSqlSessionFactory();
SqlSession sqlSession = sessionFactory.openSession();
try{
EmployeeMapper mapper = sqlSession.getMapper(EmployeeMapper.class);
Employee employee = mapper.getByIdAndNames(5, "MrChengs");
System.out.println(employee);
}finally{
sqlSession.close();
}
}

5.2.4)此时会报错

5.2.5)处理方案:是在EmployeeMapper.xml文件中修改的

<!-- 同时使用两个参数进行数据库的查询 -->
<!-- public Employee getByIdAndNames(int id,String name); -->
<select id="getByIdAndNames" resultType="com.MrChengs.bean.Employee" >
select id,name,gender,email from test where id = #{param1}
      and name=#{param2}
</select>

此时得到正确的答案!

5.3)多个查询字段时推荐使用的命名字段

明确指定封装参数时的map和key @param("id")
key:使用@param指定的值
5.3.1)接口类中
public Employee getByIdAndNames(@Param("id")int id,@Param("name")String name);

5.3.2)xml文件中

<select id="getByIdAndNames" resultType="com.MrChengs.bean.Employee" >
select id,name,gender,email from test where id = #{id} and name=#{name}
</select>
测试类是5.2.3中的测试类,此时可以得到正确的结果!
 
 
5.4)
pojo:
如果参数过多,正好是业务逻辑的数据模型,我们直接传入pojo刚刚好
#{属性名} : 取出传入的pojo的属性值
如果多个参数不是业务逻辑数据,没有对应pojo,为了方法我们也可以直接传入map
#{key}就是取出对应的值
 
5.4.1)接口类中的
  public Employee getByMap(Map<String,Object> map);

5.4.2)xml文件中添加

<select id="getByMap" resultType="com.MrChengs.bean.Employee" >
select id,name,gender,email from test where id = #{id} and name=#{name}
</select>

5.4.3)测试类

  @Test
public void test6() throws IOException{
SqlSessionFactory sessionFactory = getSqlSessionFactory();
SqlSession sqlSession = sessionFactory.openSession();
try{
EmployeeMapper mapper = sqlSession.getMapper(EmployeeMapper.class);
Map<String, Object> map = new HashMap<>();
map.put("id", 5);
map.put("name", "MrChengs");
Employee employee = mapper.getByMap(map);
System.out.println(employee);
}finally{
sqlSession.close();
}
}

运行时,可以正确输出结果!

5.5)思考问题注意

6).参数值的获取

   #{ }:可以获取map中的值,或者pojo对象中的属性值,只能是参数部分的 

  

${ }:可以获取map中的值,或者pojo对象中的属性值,还可是查询中的数据表

  

区别:
        #{} :是以预定义的形式,将sql参数设置到sql语句中, PerparedStatement;可防止注入
       ¥{}:取出值直接放在sql语句中,会有安全问题
     大多情况下,建议使用#{}
     原生sql不支持占位符,我们就可以使用 ${} 进行取值
     比如分表:按照年份拆分
          select * from  2018_salary where xxx
 
 
#{ } : 可以规定参数的规则
        javaType   jdbcType   mode(存储过程)   numericScale
        resultMao   typeHandler   jdbcTypeName   expression(未来准备支持的功能)
 
   jdbcType:通常需要在某种特定的条件下设置
                    在做数据为 null的情况下,有时候数据库可能不能识别mybatis对null的默认处理
                    比如Oracle(会报错)
                    jdbcType OTHER :会报错为无效的类型,因为mybatis对所有的null都映射为jdbc的OTHER类型,Oracle不认识,mysql可以识别
      
处理方法:
由于全局配置中:jdbcTypeForNull=OTHER,Oracle不支持
解决两种方案
A:

B:在全局配置里面(Oracle&MySql都课识别)

    在mybatis-config.xml文件中
   <!-- 修改全局信息 --> 
  <settings>
<setting name="jdbcTypeForNull" value="NULl"/>
</settings>
 7).select-映射查询元素
Select元素来定义查询元素操作
属性如下:
id:唯一的标识符
    ->用来引用这一条语句,需要和接口的方法名一致
parameterType:参数类型
    ->可以不传,MyBatis会根据TypeHandler自动判断
resultType:返回值类型
    ->别名或者全类名,如果返回值是集合,定义集合中的元素类型
        不可以和resultMap同时使用
 
A.查询返回的是集合属性
在接口类中:
    //返回集合
public List<Employee> getByList(String name);

在xml文件中:

     <!-- 返回值是集合 -->
<!-- resultType:如果返回值是一个集合,要写集合中的元素类型 -->
<!-- 模糊查询 -->
<!-- 此时查询的类型还是Emoloyee类的 -->
<select id="getByList" resultType="com.MrChengs.bean.Employee">
select * from test where name like #{name}
</select>

实现类:

 @Test
public void testList() throws IOException{
SqlSessionFactory sessionFactory = getSqlSessionFactory();
SqlSession sqlSession = sessionFactory.openSession();
try{
EmployeeMapper mapper = sqlSession.getMapper(EmployeeMapper.class);
List<Employee> name = mapper.getByList("%Mr%");
for(Employee em : name){
System.out.println(em);
}
}finally{
sqlSession.close();
}
}

数据库&结果图

B.把单个数据封装成map

接口类:

 //返回一条记录的map, key是列名,值是对应的值
public Map<String,Object> getByIdReturnMap(int id);

xml文件:

   <!-- 单个数据封装成map -->
<!-- public Map<String,Object> getByIdReturnMap(int id); -->
<select id="getByIdReturnMap" resultType="map">
select * from test where id=#{id}
</select>

实现类:

     @Test
public void testgetByIdReturnMap() throws IOException{
SqlSessionFactory sessionFactory = getSqlSessionFactory();
SqlSession sqlSession = sessionFactory.openSession();
try{
EmployeeMapper mapper = sqlSession.getMapper(EmployeeMapper.class);
Map<String,Object> map = mapper.getByIdReturnMap();
System.out.println(map);
}finally{
sqlSession.close();
}
}

结果:

C.把多个结果封装成map

接口类:

   //多个记录封装成一个map Map<int,Employee>,键是记录的主键,值是封装的值
//告诉mybatis封装map使用那个属性作为map的key
//若改为name,则name为key
@MapKey("id")
public Map<Integer,Employee> getByNameMap(String name);

xml文件:

  <select id="getByNameMap" resultType="com.MrChengs.bean.Employee">
select * from test where name like #{name}
</select>

实现类:

@Test
public void testByMapName() throws IOException{
SqlSessionFactory sessionFactory = getSqlSessionFactory();
SqlSession sqlSession = sessionFactory.openSession();
try{
EmployeeMapper mapper = sqlSession.getMapper(EmployeeMapper.class)
Map<Integer,Employee> ems = mapper.getByNameMap("%M%");
System.out.println(ems);
}finally{
sqlSession.close();
}
}

结果:

D).resultMap自定义查询

 
此时由于EmployeeMapper.java和EmployeeMapper.xml文件的测试内容已经相应的比较多
 
此时创建新的文件 ,均在原来文件的相同路径下!
 
EmployeeMapperTwo.java接口类
EmployeeMapperTwo.xml映射文件

在EmployeeMapperTwo.java接口类:

     //resultMap自定义结果映射
public Employee getById(Integer id);

在全局配置文件中进行引入:mybatis-config.xml(博主当时没引入,一致忽略这个问题,手动查询问题好久)

     <mappers>
<mapper resource="EmployeeMapper.xml" />
<mapper resource="EmployeeMapperTwo.xml"/>
</mappers>
EmployeeMapperTwo.xml映射文件中:
(所有的相关注释都已经写好)
     <!-- 自定义某个javaBean的封装规则 -->
<!-- type:是全类名,也可以是起的别名 -->
<!-- id:唯一性便于引用 -->
<resultMap type="com.MrChengs.bean.Employee" id="MyEmp">
<!-- 指定主键列的封装规则 -->
<!-- id:定义主键会底层优化 -->
<!-- column:指定那一列 -->
<!-- property:指定对应的JavaBean属性 -->
<id column="id" property="id"/>
<!-- 定义普通列封装规则 -->
<result column="name" property="name"/>
<!-- 其他不指定的列会自动封装 -->
<!-- 但是建议所有的都写出来,便于后期的维护和检查 -->
<result column="gender" property="gender"/>
<result column="email" property="email"/>
</resultMap>
<!-- public Employee getById(Integer id); -->
<!-- resultMap自定义自定义结果映射 -->
<!-- 使用resultMap则不能使用resultType两者只能二选一 -->
<select id="getById" resultMap="MyEmp">
select * from test where id=#{id}
</select>

测试类中:

//resultMap自定义结果映射
//public Employee getById(Integer id);
@Test
public void testResultMap() throws IOException{
SqlSessionFactory sessionFactory = getSqlSessionFactory();
SqlSession sqlSession = sessionFactory.openSession();
try{
EmployeeMapperTwo mapper1 = sqlSession.getMapper(EmployeeMapperTwo.class); Employee emp = mapper1.getById(5);
System.out.println(emp);
}finally{
sqlSession.close();
}
}

得到查询的结果:

 E).查询时的外键约束
 
数据库的完善:
test表:添加新的键d_id
新建表tbl_dept:两个件id和dept_name
两个表建立关联关系(外键)
alter table user add foreign key(d_id) references tbl_dept(id);

在数据库中查询两个表

SELECT * FROM test e,tbl_dept d
where e.d_id=d.id AND e.id=5

方法一:

数据库查询进一步优化方案:

SELECT e.id id,e.name,e.gender gender,e.email email,e.d_id d_id,d.dept_name dept
FROM test e,tbl_dept d
where e.d_id=d.id AND e.id=5

此时此刻我们开始上代码:
接口类中:
    //场景一查询Employee同时查询Deapment
public Employee getEmpAndDept(int id);

xml文件中:

     <!-- 查询员工对应的部门信息 -->
<!-- public Employee getEmpAndDept(Integer id); -->
<!-- 结果集封装 -->
<resultMap type="com.MrChengs.bean.Employee" id="MyEmpMangTable">
<id column="id" property="id"/>
<result column="name" property="name"/>
<result column="gender" property="gender"/>
<result column="email" property="email"/>
<!-- 级联属性的赋值方式!!! -->
<result column="d_id" property="dept.id"/>
<!-- 级联属性的赋值方式!!! -->
<result column="dept_name" property="dept.departName"/> </resultMap>
<select id="getEmpAndDept" resultMap="MyEmpMangTable">
SELECT e.id id,e.name name,e.gender gender,e.email
       email,e.d_id d_id,d.dept_name dept_name
FROM test e,tbl_dept d
where e.d_id=d.id AND e.id=#{id}
</select>

实现的方法:

 //场景一:查询Employee的同时查询员工对应的部门
// Employee ---.> Department
//一个员工与之对应的部门信息
@Test
public void testAndDept() throws IOException{
SqlSessionFactory sessionFactory = getSqlSessionFactory();
SqlSession sqlSession = sessionFactory.openSession();
try{
EmployeeMapperTwo mapper = sqlSession.getMapper(EmployeeMapperTwo.class); Employee emp = mapper.getEmpAndDept(5);
System.out.println(emp);
System.out.println(emp.getDept());
}finally{
sqlSession.close();
}
}

查询结果:(可以同上上面的数据库进行对比)

 

方法二:
在xml文件中:
<!-- 不使用级联属性 -->
<resultMap type="com.MrChengs.bean.Employee" id="MyEmpMangTable1">
<id column="id" property="id"/>
<result column="name" property="name"/>
<result column="gender" property="gender"/>
<result column="email" property="email"/> <!-- association:联合的意思,可以联合JavaBean对象 -->
<!-- property="dept":指定那个是联合的对象 -->
<!-- javaType="com.MrChengs.bean.Department": 指定这个属性对象的类型 -->
<association property="dept" javaType="com.MrChengs.bean.Department">
<!--此时再次类似resultMap标签 -->
<!-- 此时的对象是Department -->
<id column="d_id" property="id"/>
<result column="dept_name" property="departName"/>
</association>
</resultMap> <select id="getEmpAndDept" resultMap="MyEmpMangTable1">
SELECT e.id id,e.name name,e.gender gender,e.email email,
      e.d_id d_id,d.dept_name dept_name
FROM test e,tbl_dept d
where e.d_id=d.id AND e.id=#{id}
</select>

其他方法不变,依然可以查出结果!!!!

 F)association的分布实施方法(important):
 1.首先创建一个接口和一个xml映射文件,具体看图
 

2.新添加文件的代码:
DepartmentMapper.java
public interface DepartmentMapper {
public Department getDeptById(int id);
}

DepartmentMapper.xml

<mapper namespace="com.MrChengs.dao.DepartmentMapper">
<!-- public Department getDeptById(int id); -->
<select id="getDeptById" resultType="com.MrChengs.bean.Department">
select id,dept_name departName from tbl_dept where id=#{id}
</select>
</mapper>

解释:这两个文件其实是一个简单查询的过程

 3.在EmployeeMapper.xml文件zhong

<!-- association:可以进行封闭查询 -->
<!-- public Employee getEmpAndDeptByStep(int id); -->
<resultMap type="com.MrChengs.bean.Employee" id="MyEmpByStep">
<!-- 1.先查出员工信息 -->
<id column="id" property="id"/>
<result column="name" property="name"/>
<result column="gender" property="gender"/>
<result column="email" property="email"/> <!-- association 定义关联关系的封装对象 -->
<!-- select: 调用当前属性指定的方法查出结果-->
<!-- column:指定将那个值传递给这个方法 -->
<association property="dept"
select="com.MrChengs.dao.DepartmentMapper.getDeptById"
<!-- 传值 -->
column="d_id"></association>
</resultMap> <select id="getEmpAndDeptByStep" resultMap="MyEmpByStep">
select * from test where id=#{id}
</select>

3.测试类:

//分布查询
@Test
public void testAndDeptByStep() throws IOException{
SqlSessionFactory sessionFactory = getSqlSessionFactory();
SqlSession sqlSession = sessionFactory.openSession();
try{
EmployeeMapperTwo mapper = sqlSession.getMapper(EmployeeMapperTwo.class); Employee emp = mapper.getEmpAndDept(5);
System.out.println(emp);
System.out.println(emp.getDept());
}finally{
sqlSession.close();
}
}
然后得到结果!!!
aaarticlea/png;base64,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" alt="" />
 

 
分布查询相当于:
1.select * from test where id = 5
2.select * from tbl_dept where id = 1;
两个步骤分开进行实现的。
 
 
 G.延迟加载
分布查询还可以使用延迟加载
我们每次查询EMployee时,都将部门信息一起查询出来,
那么我们希望在使用部门信息再去查询
此时可以节省时间资源
在分段查询的时候,加上两个配置,在使用的时候进行加载,
不使用的时候,不进行加载,能大大的节约查询时间
全局配置文件:
<settings>
<!-- 显示的指定我们需要更改的配置信息,防止版本更新带来的问题 -->
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="aggressiveLazyLoading" value="false"/>
</settings>
其余的代码不变可以进行去尝试那个测试类的代码,不适用Dept和使用Dept的方法的区别:
注释掉使用Department类的时候,此时我们时简单的查询Employee
使用Department类的时候,此时两个都能查询出来!
 
H.查询部门的同时查询员工
SELECT    d.id,d.dept_name dept,e.id id,e.name,e.gender gender,e.email email,e.d_id d_id 
FROM test e,tbl_dept d
where e.d_id=d.id AND d.id=1;

在Department类中:

在DepartmentMapper.xml文件中:

<!-- public Department getDeptByIds(int id); -->
<!-- 查询部门同时查看出部门里面的员工 -->
<resultMap type="com.MrChengs.bean.Department" id="employees">
<id column="id" property="id"/>
<result column="dept" property="departName"/> <!-- collection:定义集合对象 -->
<!-- ofType:指定测试集合的类型 -->
<!-- property:定义对象的原型属性,即是我们在类中的定义方法 -->
<collection property="employees" ofType="com.MrChengs.bean.Employee">
<!-- 定义集合封装规则 -->
<id column="id" property="id"/>
<result column="name" property="name"/>
<result column="gender" property="gender"/>
<result column="email" property="email"/>
</collection>
</resultMap> <select id="getDeptByIds" resultMap="employees">
SELECT d.id id,d.dept_name dept,
e.id id,e.name name,e.gender gender,e.email email
FROM test e,tbl_dept d
where e.d_id=d.id AND d.id=#{id}
</select>
 
在DepartmentMapper接口

     //查询部门时查员工
public Department getDeptByIds(int id);

测试类中:

//场景二:
//在查询部门信息的时候,查询员工信息
//分布查询
@Test
public void testEmps() throws IOException{
SqlSessionFactory sessionFactory = getSqlSessionFactory();
SqlSession sqlSession = sessionFactory.openSession();
try{
DepartmentMapper mapper = sqlSession.getMapper(DepartmentMapper.class); Department dept = mapper.getDeptByIds(1);
System.out.println(dept);
System.out.println(dept.getEmployees());
}finally{
sqlSession.close();
}
}

相当于一个嵌套查询

 
//collection分布查询
DepartmentMapper.java

//collection分布查询
public Department getDeptByIdsByStep(int id);

EmployeeMapperTwo.java

     //collection分布实现
public List<Employee> getEmpByStep(int id);
 
EmployeeMapper.xml
<!-- collection分布查询 -->
<!-- public List<Employee> getEmpByStep(int id); -->
<select id="getEmpByStep" resultType="com.MrChengs.bean.Employee">
select * from test where d_id=#{d_id}
</select>

DepartmentMapper.xml

    <!-- 分布实现 -->
<!-- public Department getDeptByIdsByStep(int id); -->
<!-- collection分布实现 --> <resultMap type="com.MrChengs.bean.Department" id="MyStept">
<id column="id" property="id"/>
<result column="departName" property="departName"/> <collection property="employees" select="com.MrChengs.dao.EmployeeMapperTwo.getEmpByStep" column="id">
</collection> </resultMap>
<select id="getDeptByIdsByStep" resultMap="MyStept">
select id,dept_name departName from tbl_dept where id=#{id}
</select>

实现类

//collection 分布实现
@Test
public void testEmpsStep() throws IOException{
SqlSessionFactory sessionFactory = getSqlSessionFactory();
SqlSession sqlSession = sessionFactory.openSession();
try{
DepartmentMapper mapper = sqlSession.getMapper(DepartmentMapper.class); Department dept = mapper.getDeptByIdsByStep(1);
System.out.println(dept);
System.out.println(dept.getEmployees());
}finally{
sqlSession.close();
}
}
 
讲解:
collection中:<discriminator javaType=""></discriminator>
鉴别器:mybatis可以使用此属性判别某列的值,然后根据某列的值封装行为

MyBatis(3)-映射文件的更多相关文章

  1. Mybatis sql映射文件浅析 Mybatis简介(三)

    简介 除了配置相关之外,另一个核心就是SQL映射,MyBatis 的真正强大也在于它的映射语句. Mybatis创建了一套规则以XML为载体映射SQL 之前提到过,各项配置信息将Mybatis应用的整 ...

  2. Mybatis sql映射文件浅析 Mybatis简介(三) 简介

    Mybatis sql映射文件浅析 Mybatis简介(三)   简介 除了配置相关之外,另一个核心就是SQL映射,MyBatis 的真正强大也在于它的映射语句. Mybatis创建了一套规则以XML ...

  3. mybatis中映射文件和实体类的关联性

    mybatis的映射文件写法多种多样,不同的写法和用法,在实际开发过程中所消耗的开发时间.维护时间有很大差别,今天我就把我认为比较简单的一种映射文件写法记录下来,供大家修改建议,争取找到一个最优写法~ ...

  4. Mybatis SQL映射文件详解

    Mybatis SQL映射文件详解 mybatis除了有全局配置文件,还有映射文件,在映射文件中可以编写以下的顶级元素标签: cache – 该命名空间的缓存配置. cache-ref – 引用其它命 ...

  5. Mybatis Mapper 映射文件(xxxMapper.xml)

    什么是 Mapper 映射文件 Mapper 映射文件是 Mybatis 用于实现 ORM 映射规则的配置文件,Mybatis 通过映射文件可将数据库查询结构映射为 Java 对象. 创建 Mappe ...

  6. MyBatis学习-映射文件标签篇(select、resultMap)

    MyBatis 真正的核心在映射文件中.比直接使用 JDBC 节省95%的代码.而且将 SQL 语句独立在 Java 代码之外,可以进行更为细致的 SQL 优化. 一. 映射文件的顶级元素 selec ...

  7. Mybatis(三) 映射文件详解

    前面说了全局配置文件中内容的详解,大家应该清楚了,现在来说说这映射文件,这章就对输入映射.输出映射.动态sql这几个知识点进行说明,其中高级映射(一对一,一对多,多对多映射)在下一章进行说明. 一.输 ...

  8. mybatis 生成 映射文件生成工具 mybatisGenerator 使用

    第一:新建 generatorConfig.xml 文件 ,写入下面的 内容 <?xml version="1.0" encoding="UTF-8"?& ...

  9. springboot整合mybatis(映射文件方式和注解方式)

    springboot作为一个微服务框架,给我们开发人员提供极大的便利,秉着约定大于配置的原则,通过starter包的形式为我们做了许多默认的配置,在进行数据持久化到关系型数据库时,我们一般都会首选sp ...

随机推荐

  1. flask笔记三:flask-login插件的使用

    flask-login插件的使用 安装: pip install flask-login 初始化LoginManager ##############LoginManager设置########### ...

  2. 怎样求逆序对数(Inverse Number)?

    #返回上一级 @Author: 张海拔 @Update: 2014-01-14 @Link: http://www.cnblogs.com/zhanghaiba/p/3520089.html /* * ...

  3. python学习之老男孩python全栈第九期_day027知识点总结——反射、类的内置方法

    一. 反射 ''' # isinstance class A:pass class B(A):pass a = A() print(isinstance(a,A)) # 判断对象和类的关系 print ...

  4. python学习之老男孩python全栈第九期_day019知识点总结——collections模块、时间模块、random模块、os模块、sys模块

    一. collections模块 在内置数据类型(dict.list.set.tuple)的基础上,collections模块还提供了几个额外的数据类型:namedtuple.deque.Counte ...

  5. java停止一个线程

    Thread类中有start(), stop()方法,不过stop方法已经被废弃掉. 平时其实也有用过,共享一个变量,相当于标志,不断检查标志,判断是否退出线程 如果有阻塞,需要使用Thread的in ...

  6. RHEL5.X 重启网卡出现./network-functions: line 78: .: ifcfg-eth0: file not found

    错误信息: 红帽RHEL5.5系统,重启网卡报错 [root@localhost network-scripts]# service network restart Shutting down int ...

  7. 【es6】Generator 函数

    1. 基本概念 状态机,封装了多个内部状态 2. 应用 返回一个遍历器对象. 3. 代码形式 function* helloWorldGenertor() { yield 'hello'; yield ...

  8. Install Java JDK JRE on Ubuntu/Debian with Apt-Get

    Introduction As a lot of articles and programs require to have Java installed, this article will gui ...

  9. Codeforces Round #417 C. Sagheer and Nubian Market

    C. Sagheer and Nubian Market time limit per test  2 seconds memory limit per test  256 megabytes   O ...

  10. tomcat优化记录

    1.使用jdk自带的Jconsole进行可视化查看: 2.使用jmeter做压力测试,做完后有几个重要的指标:正确率.cpu占用率.qps jvm: 3.tomcat server.xml优化: ar ...