bash-文件-linux命令行输出重定向

无论是shell 还是 dos ,用法是一样的。

一共有4个输出到文件的命令,现以jar命令打war包举例说明:

命令 说明 举例
> 正常输出覆盖指定文件  jar -xvf my.war @select.txt  > output.txt
2> 正常输出尾部追加到指定文件  jar -xvf my.war @select.txt  2> output.txt
>> 异常输出覆盖指定文件  jar -xvf my.war @select.txt  >> error.txt
2>> 异常输出尾部追加到指定文件  jar -xvf my.war @select.txt  2>> error.txt

 

# 我这里用到 的 重定向 测试
netstat -r >/Users/cool/Desktop/test.txt

 

bash-概述-bash和shell的区别

Linux 中的 shell 有很多类型,其中最常用的几种是: Bourne shell (sh)、C shell (csh) 和 Korn shell (ksh), 各有优缺点。Bourne shell 是 UNIX 最初使用的 shell,并且在每种 UNIX 上都可以使用, 在 shell 编程方面相当优秀,但在处理与用户的交互方面做得不如其他几种shell。Linux 操作系统缺省的 shell 是Bourne Again shell,它是 Bourne shell 的扩展,简称 Bash,与 Bourne shell 完全向后兼容,并且在Bourne shell 的基础上增加、增强了很多特性。Bash放在/bin/bash中,它有许多特色,可以提供如命令补全、命令编辑和命令历史表等功能,它还包含了很多 C shell 和 Korn shell 中的优点,有灵活和强大的编程接口,同时又有很友好的用户界面。

GNU/Linux 操作系统中的 /bin/sh 本是 bash (Bourne-Again Shell) 的符号链接,但鉴于 bash 过于复杂,有人把 ash 从 NetBSD 移植到 Linux 并更名为 dash (Debian Almquist Shell),并建议将 /bin/sh 指向它,以获得更快的脚本执行速度。Dash Shell 比 Bash Shell 小的多,符合POSIX标准。

Ubuntu继承了Debian,所以从Ubuntu 6.10开始默认是Dash Shell。

luotaijia@ubuntu:~$ ls -l /bin/sh /bin/bash 
-rwxr-xr-x 1 root root 801808 2010-08-11 03:58 /bin/bash 
lrwxrwxrwx 1 root root 4 2012-11-28 08:06 /bin/sh -> dash

在centos中,
1、/bin 是超链接 指向 /usr/bin
2、/bin/sh 【真实路径/usr/bin/sh】  是超链接 指向  /bin/bash 【真实路径/usr/bin/bash】

[cool@localhost /]$ ls -l /bin/sh  
lrwxrwxrwx. 1 root root 4 Jun 26 03:58 /bin/sh -> bash
[cool@localhost /]$ ls -l /bin/bash
-rwxr-xr-x. 1 root root 964544 Apr 11 08:06 /bin/bash

应该说, /bin/sh 与 /bin/bash 虽然大体上没什么区别, 但仍存在不同的标准. 标记为 “#!/bin/sh” 的脚本不应使用任何 POSIX 没有规定的特性 (如 let 等命令, 但 “#!/bin/bash” 可以). Debian 曾经采用 /bin/bash 更改 /bin/dash,目的使用更少的磁盘空间、提供较少的功能、获取更快的速度。但是后来经过 shell 脚本测试存在运行问题。因为原先在 bash shell 下可以运行的 shell script (shell 脚本),在 /bin/sh 下还是会出现一些意想不到的问题,不是100%的兼用。

Linux中的shell有多种类型,其中最常用的几种是Bourne shell(sh)、C shell(csh)和Korn shell(ksh)。三种shell各有优缺点。
Bourne shell是UNIX最初使用的shell,并且在每种UNIX上都可以使用。Bourne shell在shell编程方面相当优秀,但在处理与用户的交互方面做得不如其他几种shell。

Linux操作系统缺省的shell是Bourne Again shell,它是Bourne shell的扩展,简称Bash,与Bourne shell完全向后兼容,并且在Bourne shell的基础上增加、增强了很多特性。Bash放在/bin/bash中,它有许多特色,可以提供如命令补全、命令编辑和命令历史表等功能,它还包含了很多C shell和Korn shell中的优点,有灵活和强大的编程接口,同时又有很友好的用户界面。
GNU/Linux 操作系统中的 /bin/sh 是 bash(Bourne-Again Shell)的符号链接,
但鉴于 bash 过于复杂,有人把 ash 从 NetBSD 移植到 Linux 并更名为 dash(Debian Almquist Shell),并建议将 /bin/sh 指向它,以获得更快的脚本执行速度。Ubuntu 号称自从他们在 6.10 版里这样做了以后,系统启动速度有了明显的提升。Debian 计划在下一个发行版(代号 lenny)中也将 dash 作为默认的 /bin/sh。

 

 

mysql问题-命令行连接mysql密码无效

mysql -u root -p 解释

 

使用此命令首先确保你的mysql运行环境已经搭建好

这是客户端连接mysql服务器的指令,比较全的写法是下面两种

第一个是全拼,第二个是第一个的缩写

mysql –host=localhost –user=myname –password=password mydb

mysql -h localhost -u myname -ppassword mydb

一般在使用中,我们会省略-h参数,mysql会自动默认为本地连接

还有一点就是各个参数之间是否有空格的问题,-u后面可以有也可以省略空格,对于-p后面的参数我要单独说一下

这是我从mysql官方文档拷过来的内容

for password options, the password value is optional:

If you use a -p or --password option and specify the password value, there must be no space between -p or --password= and the password following it.

  If you use a -p or --password option but do not specify the password value, the client program prompts you to enter the password. The password is not displayed as you enter it. This is more secure than giving the password on the command line. Other users on your system may be able to see a password specified on the command line by executing a command such as ps auxw

具体就是:对于password选项,此选项是可选的

如果你明确指定了-p或者–password的值,那么-p或者–password和密码值之间是不能有空格的。

如果你使用了-p或者–password选项但是没有给出password值,客户端程序提示您输入密码。

For mysql, the first nonoption argument is taken as the name of the default database. If there is no such option, mysql does not select a default database.

对于MySQL,第一个非选项参数被当作默认数据库的名称。如果没有这样的选项,MySQL就不会选择默认数据库。

也就是说在命令行中,你的mysql密码和-p或者–password参数之间有空格,mysql会认为你输入的是登录mysql后自动选择的数据库,而不是你所期望的密码

当然命令行连接数据库还有其它参数,这里主要介绍几个经常使用的,其它请参考https://dev.mysql.com/doc/refman/5.5/en/connecting.html

来自:https://www.cnblogs.com/phproom/p/9549229.html

mybatis映射文件-(8)-resultMap关联查询之discriminator鉴别器

鉴别器:mybatis可以使用discriminator判断某列的值,然后根据某列的值改变封装行为。比如封装Employee:根据gender值
1、如果查出的是女生:就把部门信息查询出来,否则不查询;
2、如果是男生,把last_name这一列的值赋值给email;

1、搭建数据库

tbl_employee表【d_id 是外键 对应 tbl_dept表】

id	last_name    gender	  email       d_id
1	   mike	       0      [email protected]      1
2          book        0      [email protected]    2
3          tom         1      [email protected]    2
4          jerry       1       [email protected]       1

tbl_dept表:

id    dept_name
1      开发部
2      测试部

2、编辑 javabean

Employee.java

package com.mybatis.bean;

public class Employee {
	private int id;
	private String lastName;
	private String email;
	private String gender;
	private Department department;

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getLastName() {
		return lastName;
	}

	public void setLastName(String lastName) {
		this.lastName = lastName;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public String getGender() {
		return gender;
	}

	public void setGender(String gender) {
		this.gender = gender;
	}
	
	public Department getDepartment() {
		return department;
	}

	public void setDepartment(Department department) {
		this.department = department;
	}

	@Override
	public String toString() {
		return "Employee [id=" + id + ", lastName=" + lastName + ", email=" + email + ", gender=" + gender + "]";
	}

}

Department.java

package com.mybatis.bean;

import java.util.List;

public class Department {
	
	private Integer id;
	private String departmentName;
	
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getDepartmentName() {
		return departmentName;
	}
	public void setDepartmentName(String departmentName) {
		this.departmentName = departmentName;
	}
	@Override
	public String toString() {
		return "Department [id=" + id + ", departmentName=" + departmentName
				+ "]";
	}
	
	

}

3、编辑接口文件

EmployeeMapper.java

package com.mybatis.mapper;

import com.mybatis.bean.Employee;

public interface EmployeeMapper {
		
	public Employee getEmpByIdStep(Integer id);

}

DepartmentMapper.java

package com.mybatis.mapper;

import com.mybatis.bean.Department;

public interface DepartmentMapper {
	
	public Department getDeptById(Integer id);

}

4、编辑sql映射文件

EmployeeMapper.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.mybatis.mapper.EmployeeMapperPlus">

	<!--自定义某个javaBean的封装规则
	type:自定义规则的Java类型
	id:唯一id方便引用
	  -->
	  
	<!-- public Employee getEmpById(Integer id); -->
	<select id="getEmpByIdStep"  resultMap="MyEmpDis">
		select * from tbl_employee where id=#{id}
	</select>
	
	
	<!-- =======================鉴别器============================ -->
	<!-- <discriminator javaType=""></discriminator>
		鉴别器:mybatis可以使用discriminator判断某列的值,然后根据某列的值改变封装行为
		封装Employee:
			如果查出的是女生:就把部门信息查询出来,否则不查询;
			如果是男生,把last_name这一列的值赋值给email;
	 -->
	 <resultMap type="com.mybatis.bean.Employee" id="MyEmpDis">
	 	<id column="id" property="id"/>
	 	<result column="last_name" property="lastName"/>
	 	<result column="email" property="email"/>
	 	<result column="gender" property="gender"/>
	 	<!--
	 		column:指定判定的列名
	 		javaType:列值对应的java类型 ,string 是 mybatis 对String类型 直接默认设置 的别名 -->
	 	<discriminator javaType="string" column="gender">
	 		<!--女生  resultType:指定封装的结果类型;不能缺少。/resultMap-->
	 		<case value="0" resultType="com.mybatis.bean.Employee">
	 			<association property="department" 
			 		select="com.mybatis.mapper.DepartmentMapper.getDeptById"
			 		column="d_id">
		 		</association>
	 		</case>
	 		<!--男生 ;如果是男生,把last_name这一列的值赋值给email; -->
	 		<case value="1" resultType="com.mybatis.bean.Employee">
		 		<id column="id" property="id"/>
			 	<result column="last_name" property="lastName"/>
			 	<result column="last_name" property="email"/>
			 	<result column="gender" property="gender"/>
	 		</case>
	 	</discriminator>
	 </resultMap>
</mapper>

DepartmentMapper.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.mybatis.mapper.DepartmentMapper">
	
	<!--public Department getDeptById(Integer id);  -->
	<select id="getDeptById" resultType="com.mybatis.bean.Department">
		select id,dept_name departmentName from tbl_dept where id=#{id}
	</select>

</mapper>

5、编辑全局配置文件:

mybatis-config.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>

	<environments default="development">
		<environment id="development">
			<transactionManager type="JDBC" />
			<dataSource type="POOLED">
				<property name="driver" value="com.mysql.jdbc.Driver" />
				<property name="url" value="jdbc:mysql://localhost:3306/mybatis" />
				<property name="username" value="root" />
				<property name="password" value="Kitty521!" />
			</dataSource>
		</environment>
	</environments>
	<!-- 将我们写好的sql映射文件(EmployeeMapper.xml)一定要注册到全局配置文件(mybatis-config.xml)中 
	如果 数据库全局文件 和 子配置文件 不在同一个目录 ,就需要 /目录/目录/.../EmployeeMapper_old.xml
	-->
	<mappers>
	    <!-- 新方法操作mybatis 需要 的配置文件 -->
		<mapper resource="EmployeeMapperPlus.xml"  />
		<mapper resource="DepartmentMapper.xml" />
	</mappers>
	
</configuration>

特别注意:分步查询需要 调用两句sql语句。因为这两句sql语句分布在两个不同的sql映射文件,所以两个sql映射文件都需要注册到 全局配置文件中。

 

mybatis映射文件-(7)-resultMap关联查询之非级联一对多分步查询

1、搭建数据库

tbl_employee表【d_id 是外键 对应 tbl_dept表】

id	last_name    gender	  email       d_id
1	   mike	       0      [email protected]      1
2          book        0      [email protected]    2
3          tom         1      [email protected]    2
4          jerry       1       [email protected]       1

tbl_dept表:

id    dept_name
1      开发部
2      测试部

2、编辑 javabean

Employee.java

package com.mybatis.bean;

public class Employee {
	private int id;
	private String lastName;
	private String email;
	private String gender;
	private Department department;

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getLastName() {
		return lastName;
	}

	public void setLastName(String lastName) {
		this.lastName = lastName;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public String getGender() {
		return gender;
	}

	public void setGender(String gender) {
		this.gender = gender;
	}
	
	public Department getDepartment() {
		return department;
	}

	public void setDepartment(Department department) {
		this.department = department;
	}

	@Override
	public String toString() {
		return "Employee [id=" + id + ", lastName=" + lastName + ", email=" + email + ", gender=" + gender + "]";
	}

}

Department.java

package com.mybatis.bean;

import java.util.List;

public class Department {
	
	private Integer id;
	private String departmentName;
	private List<Employee> employees;
	
	
	public List<Employee> getEmployees() {
		return employees;
	}
	public void setEmployees(List<Employee> employees) {
		this.employees = employees;
	}
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getDepartmentName() {
		return departmentName;
	}
	public void setDepartmentName(String departmentName) {
		this.departmentName = departmentName;
	}
	@Override
	public String toString() {
		return "Department [id=" + id + ", departmentName=" + departmentName
				+ "]";
	}
	
	

}

3、编辑接口文件

DepartmentMapper.java

package com.mybatis.mapper;

import com.mybatis.bean.Department;

public interface DepartmentMapper {
	
	//分步查询
	public Department getDeptByIdStep(Integer id);

}

EmployeeMapper.java

package com.mybatis.mapper;

import java.util.List;

import com.mybatis.bean.Employee;

public interface EmployeeMapperPlus {
	
	public List<Employee> getEmpsByDeptId(Integer deptId);

}

4、编辑sql映射文件

DepartmentMapper.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.mybatis.mapper.DepartmentMapper">
	
<!-- collection:分步查询 -->
	<resultMap type="com.mybatis.bean.Department" id="MyDeptStep">
		<id column="id" property="id"/>
		<id column="dept_name" property="departmentName"/>
		<collection property="employees" 
			select="com.mybatis.mapper.EmployeeMapperPlus.getEmpsByDeptId"
			column="id" fetchType="lazy"></collection>
	</resultMap>
	<!-- public Department getDeptByIdStep(Integer id); -->
	<select id="getDeptByIdStep" resultMap="MyDeptStep">
		select id,dept_name from tbl_dept where id=#{id}
	</select>

		<!-- 扩展:多列的值传递过去:
			将多列的值封装map传递;
			column="{key1=column1,key2=column2}"
		fetchType="lazy":表示使用延迟加载;
				- lazy:延迟
				- eager:立即
	 -->
	
</mapper>

EmployeeMapper.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.mybatis.mapper.EmployeeMapperPlus">

	<!--自定义某个javaBean的封装规则
	type:自定义规则的Java类型
	id:唯一id方便引用
	  -->
	
	<!-- public List<Employee> getEmpsByDeptId(Integer deptId); -->
	<select id="getEmpsByDeptId" resultType="com.mybatis.bean.Employee">
		select * from tbl_employee where d_id=#{deptId}
	</select>

</mapper>

5、编辑全局配置文件:

mybatis-config.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>

	<environments default="development">
		<environment id="development">
			<transactionManager type="JDBC" />
			<dataSource type="POOLED">
				<property name="driver" value="com.mysql.jdbc.Driver" />
				<property name="url" value="jdbc:mysql://localhost:3306/mybatis" />
				<property name="username" value="root" />
				<property name="password" value="Kitty521!" />
			</dataSource>
		</environment>
	</environments>
	<!-- 将我们写好的sql映射文件(EmployeeMapper.xml)一定要注册到全局配置文件(mybatis-config.xml)中 
	如果 数据库全局文件 和 子配置文件 不在同一个目录 ,就需要 /目录/目录/.../EmployeeMapper_old.xml
	-->
	<mappers>
	    <!-- 新方法操作mybatis 需要 的配置文件 -->
		<mapper resource="EmployeeMapperPlus.xml"  />
		<mapper resource="DepartmentMapper.xml" />
	</mappers>
	
</configuration>

特别注意:分步查询需要 调用两句sql语句。因为这两句sql语句分布在两个不同的sql映射文件,所以两个sql映射文件都需要注册到 全局配置文件中。

6、补充说明

分步查询中:子句查询时(无论是association 还是 collection 标签),传入多个参数问题,延迟加载设置:

### 举例:
### fetchType="lazy" 代表子句执行时,用的是延迟加载。
### - lazy:延迟  
### - eager:立即

### 子查询 多个入参问题
### column="{deptId=id}" 代表 sql字段的 id ,传入给 子句查询中的 deptId 入参
### 将多列的值封装成map;column="{key1=column1,key2=column2}"  来传给子查询的入参

<collection property="employees" 
	select="com.mybatis.mapper.EmployeeMapperPlus.getEmpsByDeptId"
	column="{deptId=id}" fetchType="lazy">
</collection>

 

 

 

mybatis映射文件-(6)-resultMap关联查询之非级联一对多一步查询

前面提到的关联查询中,bean里面的 某个属性就是一个对象,属于 一对一映射:可以采用一步查询,级联赋值 或者  采用分步查询 ,单独赋值。现在如果 bean的某个属性是 一个集合,属于一对多映射,那么 查询结果 就不能用级联赋值了。级联赋值 是 一对一 关系映射中的 一种方法。


1、搭建数据库

tbl_employee表【d_id 是外键 对应 tbl_dept表】

id	last_name    gender	  email       d_id
1	   mike	       0      [email protected]      1
2          book        0      [email protected]    2
3          tom         1      [email protected]    2
4          jerry       1       [email protected]       1

tbl_dept表:

id    dept_name
1      开发部
2      测试部

数据库测试:

select  d.id  did, d.dept_name dept_name, e.id eid, e.last_name last_name,
e.email email, e.gender gender
from tbl_dept d
left join tbl_employee e
on d.id = e.d_id
where d.id =1

2、编辑 javabean

Employee.java

package com.mybatis.bean;

public class Employee {
	private int id;
	private String lastName;
	private String email;
	private String gender;
	private Department department;

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getLastName() {
		return lastName;
	}

	public void setLastName(String lastName) {
		this.lastName = lastName;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public String getGender() {
		return gender;
	}

	public void setGender(String gender) {
		this.gender = gender;
	}
	
	public Department getDepartment() {
		return department;
	}

	public void setDepartment(Department department) {
		this.department = department;
	}

	@Override
	public String toString() {
		return "Employee [id=" + id + ", lastName=" + lastName + ", email=" + email + ", gender=" + gender + "]";
	}

}

Department.java

package com.mybatis.bean;

import java.util.List;

public class Department {
	
	private Integer id;
	private String departmentName;
        private List<Employee> employees;
        
        public List<Employee> getEmployees() {
		return employees;
	}
	public void setEmployees(List<Employee> employees) {
		this.employees = employees;
	}

	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getDepartmentName() {
		return departmentName;
	}
	public void setDepartmentName(String departmentName) {
		this.departmentName = departmentName;
	}
	@Override
	public String toString() {
		return "Department [id=" + id + ", departmentName=" + departmentName
				+ "]";
	}
	
	

}

3、编辑接口文件

DepartmentMapper.java

package com.mybatis.mapper;

import com.mybatis.bean.Department;

public interface DepartmentMapper {
	
	//增强版 还能查出员工
	public Department getDeptByIdPlus(Integer id);

}

4、编辑sql映射文件

DepartmentMapper.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.mybatis.mapper.DepartmentMapper">
	<!-- 
	public class Department {
			private Integer id;
			private String departmentName;
			private List<Employee> emps;
	  did  dept_name  ||  eid  last_name  email   gender  
	 -->
	 
	<!--嵌套结果集的方式,使用collection标签定义关联的集合类型的属性封装规则  -->
	<resultMap type="com.mybatis.bean.Department" id="MyDept">
		<id column="did" property="id"/>
		<result column="dept_name" property="departmentName"/>
		<!-- 
			collection定义关联集合类型的属性的封装规则 
			ofType:指定集合里面元素的类型
		-->
		<collection property="employees" ofType="com.mybatis.bean.Employee">
			<!-- 定义这个集合中元素的封装规则 -->
			<id column="eid" property="id"/>
			<result column="last_name" property="lastName"/>
			<result column="email" property="email"/>
			<result column="gender" property="gender"/>
		</collection>
	</resultMap>
	<!-- public Department getDeptByIdPlus(Integer id); -->
	<select id="getDeptByIdPlus" resultMap="MyDept">
		SELECT d.id did,d.dept_name dept_name,
				e.id eid,e.last_name last_name,e.email email,e.gender gender
		FROM tbl_dept d
		LEFT JOIN tbl_employee e
		ON d.id=e.d_id
		WHERE d.id=#{id}
	</select>
</mapper>

5、编辑全局配置文件:

mybatis-config.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>

	<environments default="development">
		<environment id="development">
			<transactionManager type="JDBC" />
			<dataSource type="POOLED">
				<property name="driver" value="com.mysql.jdbc.Driver" />
				<property name="url" value="jdbc:mysql://localhost:3306/mybatis" />
				<property name="username" value="root" />
				<property name="password" value="Kitty521!" />
			</dataSource>
		</environment>
	</environments>
	<!-- 将我们写好的sql映射文件(EmployeeMapper.xml)一定要注册到全局配置文件(mybatis-config.xml)中 
	如果 数据库全局文件 和 子配置文件 不在同一个目录 ,就需要 /目录/目录/.../EmployeeMapper_old.xml
	-->
	<mappers>
		<mapper resource="DepartmentMapper.xml" />
	</mappers>
	
</configuration>

6、单元测试:

MybatisTest.java

package com.mybatis.test;


import java.io.IOException;
import java.io.InputStream;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;

import com.mybatis.bean.Department;
import com.mybatis.bean.Employee;
import com.mybatis.mapper.DepartmentMapper;
import com.mybatis.mapper.EmployeeMapperPlus;


/**
 * 1、接口式编程
 * 	原生:		Dao		====>  DaoImpl
 * 	mybatis:	Mapper	====>  xxMapper.xml
 * 
 * 2、SqlSession代表和数据库的一次会话;用完必须关闭;
 * 3、SqlSession和connection一样她都是非线程安全。每次使用都应该去获取新的对象。(就是不要放在共享成员变量里面,A线程用完释放,B线程再用就为空了)
 * 4、mapper接口没有实现类,但是mybatis会为这个接口生成一个代理对象。
 * 		(将接口和xml进行绑定)
 * 		EmployeeMapper empMapper =	sqlSession.getMapper(EmployeeMapper.class);
 * 5、两个重要的配置文件:
 * 		mybatis的全局配置文件:包含数据库连接池信息,事务管理器信息等...系统运行环境信息
 * 		sql映射文件:保存了每一个sql语句的映射信息:
 * 					将sql抽取出来。	
 *
 */

public class MybatisTest {


	/********************************************************************/
	
	public SqlSessionFactory getSqlSessionFactory() throws IOException {
		String resource = "mybatis-config.xml";
		InputStream inputStream = Resources.getResourceAsStream(resource);
		return new SqlSessionFactoryBuilder().build(inputStream);
	}
	
	@Test
	public void test_new() throws IOException {
		// 1、获取sqlSessionFactory对象
		SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
		// 2、获取sqlSession对象
		SqlSession openSession = sqlSessionFactory.openSession();
		try {
			// 3、获取接口的实现类对象
			//会为接口自动的创建一个代理对象,代理对象去执行增删改查方法

//			EmployeeMapperPlus mapper = openSession.getMapper(EmployeeMapperPlus.class);
//			Employee employee = mapper.getEmpByIdStep(1);
//			System.out.println(mapper.getClass());
//			System.out.println(employee);
//			System.out.println(employee.getDepartment());
			
			DepartmentMapper mapper = openSession.getMapper(DepartmentMapper.class);
			Department department = mapper.getDeptByIdPlus(1);
			System.out.println(mapper.getClass());
			System.out.println(department);
			System.out.println(department.getEmployees());

		} finally {
			openSession.close();
		}

	}

}

 

mybatis映射文件-(5)-resultMap关联查询之分步查询与非级联赋值

1、搭建数据库

tbl_employee表【d_id 是外键 对应 tbl_dept表】

id	last_name    gender	  email       d_id
1	   mike	       0      [email protected]      1
2          book        0      [email protected]    2
3          tom         1      [email protected]    2
4          jerry       1       [email protected]       1

tbl_dept表:

id    dept_name
1      开发部
2      测试部

2、编辑 javabean

Employee.java

package com.mybatis.bean;

public class Employee {
	private int id;
	private String lastName;
	private String email;
	private String gender;
	private Department department;

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getLastName() {
		return lastName;
	}

	public void setLastName(String lastName) {
		this.lastName = lastName;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public String getGender() {
		return gender;
	}

	public void setGender(String gender) {
		this.gender = gender;
	}
	
	public Department getDepartment() {
		return department;
	}

	public void setDepartment(Department department) {
		this.department = department;
	}

	@Override
	public String toString() {
		return "Employee [id=" + id + ", lastName=" + lastName + ", email=" + email + ", gender=" + gender + "]";
	}

}

Department.java

package com.mybatis.bean;

import java.util.List;

public class Department {
	
	private Integer id;
	private String departmentName;

	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getDepartmentName() {
		return departmentName;
	}
	public void setDepartmentName(String departmentName) {
		this.departmentName = departmentName;
	}
	@Override
	public String toString() {
		return "Department [id=" + id + ", departmentName=" + departmentName
				+ "]";
	}
	
	

}

3、编辑接口文件

EmployeeMapper.java

package com.mybatis.mapper;

import java.util.List;

import com.mybatis.bean.Employee;

public interface EmployeeMapper {
	
	
	public Employee getEmpByIdStep(Integer id);
	

}

DepartmentMapper.java

package com.mybatis.mapper;

import com.mybatis.bean.Department;

public interface DepartmentMapper {
	
	public Department getDeptById(Integer id);
	
}

4、编辑sql映射文件

DepartmentMapper.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.mybatis.mapper.DepartmentMapper">
	<!--public Department getDeptById(Integer id);  -->
	<select id="getDeptById" resultType="com.mybatis.bean.Department">
		select id,dept_name departmentName from tbl_dept where id=#{id}
	</select>
	
</mapper>

EmployeeMapper.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.mybatis.mapper.EmployeeMapper">

	<!--自定义某个javaBean的封装规则
	type:自定义规则的Java类型
	id:唯一id方便引用
	  -->
        <!-- 使用association进行分步查询:
		1、先按照员工id查询员工信息
		2、根据查询员工信息中的d_id值去部门表查出部门信息
		3、部门设置到员工中;
	 -->
	 
	 <!--  id  last_name  email   gender    d_id   -->
	 <resultMap type="com.mybatis.bean.Employee" id="MyEmpByStep">
	 	<id column="id" property="id"/>
	 	<result column="last_name" property="lastName"/>
	 	<result column="email" property="email"/>
	 	<result column="gender" property="gender"/>
	 	<!-- association定义关联对象的封装规则
	 		select:表明当前属性是调用select指定的方法查出的结果
	 		column:指定将哪一列的值传给这个方法
	 		
	 		流程:使用select指定的方法(传入column指定的这列参数的值)查出对象,并封装给property指定的属性
	 	 -->
 		<association property="department" 
	 		select="com.mybatis.mapper.DepartmentMapper.getDeptById"
	 		column="d_id">
 		</association>
	 </resultMap>
	 <!--  public Employee getEmpByIdStep(Integer id);-->
	 <select id="getEmpByIdStep" resultMap="MyEmpByStep">
	 	select * from tbl_employee where id=#{id}
	 	<if test="_parameter!=null">
	 		and 1=1
	 	</if>
	 </select>
</mapper>

5、编辑全局配置文件:

<?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>

	<environments default="development">
		<environment id="development">
			<transactionManager type="JDBC" />
			<dataSource type="POOLED">
				<property name="driver" value="com.mysql.jdbc.Driver" />
				<property name="url" value="jdbc:mysql://localhost:3306/mybatis" />
				<property name="username" value="root" />
				<property name="password" value="Kitty521!" />
			</dataSource>
		</environment>
	</environments>
	<!-- 将我们写好的sql映射文件(EmployeeMapper.xml)一定要注册到全局配置文件(mybatis-config.xml)中 
	如果 数据库全局文件 和 子配置文件 不在同一个目录 ,就需要 /目录/目录/.../EmployeeMapper_old.xml
	-->
	<mappers>
	    <!-- 新方法操作mybatis 需要 的配置文件 -->
		<mapper resource="EmployeeMapper.xml" />
	</mappers>
	
</configuration>

特别强调,上面的配置文件忘记添加了<mapper resource="DepartmentMapper.xml" />

<mappers>
<!-- 因为涉及到分步查询,所以每一步,查询语句都要注册好,
一开始下面第一句 sql 映射文件 没有注册,结果就报错了 -->
<mapper resource="DepartmentMapper.xml" />
<mapper resource="EmployeeMapperPlus.xml" />

</mappers>

因为没有添加<mapper resource="DepartmentMapper.xml" />导致报错结果:

org.apache.ibatis.exceptions.PersistenceException: 
### Error querying database.  Cause: java.lang.IllegalArgumentException: Mapped Statements collection does not contain value for com.mybatis.mapper.DepartmentMapper.getDeptById
### The error may exist in EmployeeMapperPlus.xml
### The error may involve com.mybatis.mapper.EmployeeMapperPlus.getEmpByIdStep
### The error occurred while handling results
### SQL: select * from tbl_employee where id=?          and 1=1
### Cause: java.lang.IllegalArgumentException: Mapped Statements collection does not contain value for com.mybatis.mapper.DepartmentMapper.getDeptById
	at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30)
	at 

所以一定要添加啊,<mapper resource="DepartmentMapper.xml" />

6、单元测试:

package com.mybatis.test;


import java.io.IOException;
import java.io.InputStream;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;

import com.mybatis.bean.Employee;
import com.mybatis.mapper.EmployeeMapperPlus;


/**
 * 1、接口式编程
 * 	原生:		Dao		====>  DaoImpl
 * 	mybatis:	Mapper	====>  xxMapper.xml
 * 
 * 2、SqlSession代表和数据库的一次会话;用完必须关闭;
 * 3、SqlSession和connection一样她都是非线程安全。每次使用都应该去获取新的对象。(就是不要放在共享成员变量里面,A线程用完释放,B线程再用就为空了)
 * 4、mapper接口没有实现类,但是mybatis会为这个接口生成一个代理对象。
 * 		(将接口和xml进行绑定)
 * 		EmployeeMapper empMapper =	sqlSession.getMapper(EmployeeMapper.class);
 * 5、两个重要的配置文件:
 * 		mybatis的全局配置文件:包含数据库连接池信息,事务管理器信息等...系统运行环境信息
 * 		sql映射文件:保存了每一个sql语句的映射信息:
 * 					将sql抽取出来。	
 *
 */

public class MybatisTest {


	/********************************************************************/
	
	public SqlSessionFactory getSqlSessionFactory() throws IOException {
		String resource = "mybatis-config.xml";
		InputStream inputStream = Resources.getResourceAsStream(resource);
		return new SqlSessionFactoryBuilder().build(inputStream);
	}
	
	@Test
	public void test_new() throws IOException {
		// 1、获取sqlSessionFactory对象
		SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
		// 2、获取sqlSession对象
		SqlSession openSession = sqlSessionFactory.openSession();
		try {
			// 3、获取接口的实现类对象
			//会为接口自动的创建一个代理对象,代理对象去执行增删改查方法
			EmployeeMapperPlus mapper = openSession.getMapper(EmployeeMapperPlus.class);
			Employee employee = mapper.getEmpByIdStep(1);
			System.out.println(mapper.getClass());
			System.out.println(employee);
			System.out.println(employee.getDepartment());
		} finally {
			openSession.close();
		}

	}

}

7、延迟加载

<!-- 可以使用延迟加载(懒加载);(按需加载)
	 	Employee==>Dept:
	 		我们每次查询Employee对象的时候,都将一起查询出来。
	 		部门信息在我们使用的时候再去查询;
	 		分段查询的基础之上加上两个配置:
 -->

这两个配置,需要写在mybatis全局配置中:

<!-- 
	2、settings包含很多重要的设置项
	setting:用来设置每一个设置项
		name:设置项名
		value:设置项取值
 -->
<settings>
	<!-- 配置驼峰命名法 <setting name="mapUnderscoreToCamelCase" value="true"/> -->
	<!-- 配置oracle 字段内容 null类型 兼容 <setting name="jdbcTypeForNull" value="NULL"/> -->
		
	<!--下面这两个是用来开启延迟加载用的,显示的指定每个我们需要更改的配置的值,即使他是默认的。防止版本更新带来的问题  -->
	<setting name="lazyLoadingEnabled" value="true"/>
	<setting name="aggressiveLazyLoading" value="false"/>
</settings>

8、补充说明

分步查询中:子句查询时(无论是association 还是 collection 标签),传入多个参数问题,延迟加载设置:

### 举例:
### fetchType="lazy" 代表子句执行时,用的是延迟加载。
### - lazy:延迟  
### - eager:立即

### 子查询 多个入参问题
### column="{deptId=id}" 代表 sql字段的 id ,传入给 子句查询中的 deptId 入参
### 将多列的值封装成map;column="{key1=column1,key2=column2}"  来传给子查询的入参

<association property="department" 
	 select="com.mybatis.mapper.DepartmentMapper.getDeptById"
	 column="{id=d_id}" fetchType="lazy">
</association>

 

mybatis映射文件-(4)-resultMap关联查询之一步查询与级联赋值

sql查询结果,自动映射方法

•1、全局setting设置
–autoMappingBehavior默认是PARTIAL,开启自动映射的功能。唯一的要求是列名和javaBean属性名一致
–如果autoMappingBehavior设置为null则会取消自动映射
–数据库字段命名规范,POJO属性符合驼峰命名法,如A_COLUMN->aColumn,我们可以开启自动驼峰命名规则映射功能,mapUnderscoreToCamelCase=true。

•2、sql语句查询时,使用别名,完成bean的映射。

•3、自定义resultMap,实现高级结果集映射,完成自定义封装查询结果。

sql映射文件中   sql语句   的 resultMap 与 resultType 只能二选一。


测试数据库:

创建数据库:【第一次写的时候,居然写成tbl_employee{},sql语句没有{},应该是()  】

create table tbl_employee(
  id int(11) primary key auto_increment,
  last_name varchar(255),
  gender char(1),
  email varchar(255)
)

添加数据:

id	last_name    gender	     email
1	   mike	       0     [email protected]

resultMap:简单映射

Junit单元测试:
EmployeeMapperPlus mapper = openSession.getMapper(EmployeeMapperPlus.class);
Employee employee = mapper.getEmpById(1);
System.out.println(mapper.getClass());
System.out.println(employee);

接口文件:
public Employee getEmpById(Integer id);

sql映射文件:
<!--自定义某个javaBean的封装规则
type:自定义规则的Java类型
id:唯一id方便引用
 -->
<resultMap type="com.mybatis.bean.Employee" id="MySimpleEmp">
	<!--指定主键列的封装规则
	id定义主键会底层有优化;
	column:指定哪一列
	property:指定对应的javaBean属性
	-->
	<id column="id" property="id"/>
	<!-- 定义普通列封装规则 -->
	<result column="last_name" property="lastName"/>
	<!-- 其他不指定的列会自动封装,但是为了以后维护方便,我们只要写resultMap就把全部的映射规则都写上。 -->
	<result column="email" property="email"/>
	<result column="gender" property="gender"/>
</resultMap>
	
<!-- resultMap:自定义结果集映射规则;  -->
<!-- public Employee getEmpById(Integer id); -->
<select id="getEmpById"  resultMap="MySimpleEmp">
	select * from tbl_employee where id=#{id}
</select>

eclipse:控制台输出数据库接口

Employee [id=1, lastName=mike, [email protected], gender=0]

resultMap:级联映射

1、新建雇员表:

create table tbl_employee(
  id int(11) primary key auto_increment,
  last_name varchar(255),
  gender char(1),
  email varchar(255)
)

2、添加雇员信息:

id	last_name    gender	     email
1	   mike	       0     [email protected]

3、添加部门表:

create table tbl_dept(
   id int(11) primary key auto_increment,
   dept_name varchar(255)
)

4、添加部门信息:

id    dept_name
1      开发部
2      测试部

5、添加表关联

下面是两条sql语句,第一条语句后面要写分号,这样才能顺利执行。

alter table tbl_employee add column d_id int(11);

alter table tbl_employee add CONSTRAINT fk_emp_dept 
FOREIGN key(d_id) REFERENCES tbl_dept(id)

6、

sql 客户端 查询:

select e.id id,e.last_name last_name,e.gender gender,e.d_id d_id,
d.id did,d.dept_name dept_name from tbl_employee e,tbl_dept d where e.d_id = d.id and e.id =1

项目代码文件:

Employee.java文件:

package com.mybatis.bean;

public class Employee {
	private int id;
	private String lastName;
	private String email;
	private String gender;
	private Department department;

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getLastName() {
		return lastName;
	}

	public void setLastName(String lastName) {
		this.lastName = lastName;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public String getGender() {
		return gender;
	}

	public void setGender(String gender) {
		this.gender = gender;
	}
	
	public Department getDepartment() {
		return department;
	}

	public void setDepartment(Department department) {
		this.department = department;
	}

	@Override
	public String toString() {
		return "Employee [id=" + id + ", lastName=" + lastName + ", email=" + email + ", gender=" + gender + "]";
	}

}

Department.java

package com.mybatis.bean;

import java.util.List;

public class Department {
	
	private Integer id;
	private String departmentName;
	
	
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getDepartmentName() {
		return departmentName;
	}
	public void setDepartmentName(String departmentName) {
		this.departmentName = departmentName;
	}
	@Override
	public String toString() {
		return "Department [id=" + id + ", departmentName=" + departmentName
				+ "]";
	}
	
	

}

 

JUnit测试文件:
EmployeeMapperPlus mapper = openSession.getMapper(EmployeeMapperPlus.class);
Employee employee = mapper.getEmpAndDept(1);
System.out.println(employee);
System.out.println(employee.getDepartment());


接口文件:
public Employee getEmpAndDept(Integer id);

sql映射文件:
<!-- 
场景一:
	查询Employee的同时查询员工对应的部门
	Employee===Department
	一个员工有与之对应的部门信息;
	id  last_name  gender    d_id     did  dept_name (private Department dept;)
 -->
	 
<!--
	联合查询:级联属性封装结果集
  -->
<resultMap type="com.mybatis.bean.Employee" id="MyDifEmp">
	<id column="id" property="id"/>
	<result column="last_name" property="lastName"/>
	<result column="gender" property="gender"/>
	<result column="did" property="department.id"/>
	<result column="dept_name" property="department.departmentName"/>
</resultMap>

<!--  public Employee getEmpAndDept(Integer id);-->
<select id="getEmpAndDept" resultMap="MyDifEmp">
	SELECT e.id id,e.last_name last_name,e.gender gender,e.d_id d_id,
	d.id did,d.dept_name dept_name FROM tbl_employee e,tbl_dept d
	WHERE e.d_id=d.id AND e.id=#{id}
</select>

sql映射文件也可以替换 采用  association标签方法:

<!-- 
	使用association定义关联的单个对象的封装规则;
 -->
<resultMap type="com.mybatis.bean.Employee" id="MyDifEmp2">
	<id column="id" property="id"/>
	<result column="last_name" property="lastName"/>
	<result column="gender" property="gender"/>
		
	<!--  association可以指定联合的javaBean对象
	property="department":指定哪个属性是联合的对象
	javaType:指定这个属性对象的类型[不能省略]
	-->
	<association property="department" javaType="com.mybatis.bean.Department">
		<id column="did" property="id"/>
		<result column="dept_name" property="departmentName"/>
	</association>
</resultMap>
<!--  public Employee getEmpAndDept(Integer id);-->
<select id="getEmpAndDept" resultMap="MyDifEmp2">
	SELECT e.id id,e.last_name last_name,e.gender gender,e.d_id d_id,
	d.id did,d.dept_name dept_name FROM tbl_employee e,tbl_dept d
	WHERE e.d_id=d.id AND e.id=#{id}
</select>