LayUI
LayUI异步登录1.页面
<body>
<div id="container">
<div></div>
<div class="admin-login-background">
<div class="admin-header">
<span>layuimini</span>
</div>
<form id="form" class="layui-form">
<div>
<i class="layui-icon layui-icon-username admin-icon"></i>
<input type="text" name="username" id="username" placeholder="请输入用户名" autocomplete="off" class="layui-input admin-input admin-input-username" value="admin">
</div>
<div>
<i class="layui-icon layui-icon-password admin-icon"></i>
<input type="password" name="password" id="password" placeholder="请输入密码" autocomplete="off" class="layui-input admin-input" value="123456">
</div>
<div>
<input type="text" name="captcha" placeholder="请输入验证码" autocomplete="off" class="layui-input admin-input admin-input-verify" value="xszg">
<img class="admin-captcha" width="90" height="30" src="../images/captcha.jpg">
</div>
<button class="layui-btn admin-button" lay-submit="" lay-filter="login">登 陆</button>
</form>
</div>
</div>
<!--jquery的js文件-->
<script src="/LayUI_war_exploded/lib/jquery-3.4.1/jquery-3.4.1.min.js"></script>
<script src="/LayUI_war_exploded/lib/layui-v2.5.5/layui.js" charset="utf-8"></script>
<!--layUI--脚本--表单模块-->
<script>
layui.use(['form'], function () {
var form = layui.form,
layer = layui.layer;
// 登录过期的时候,跳出ifram框架
if (top.location != self.location) top.location = self.location;
// 进行登录操作
//layUI表单提交操作
form.on('submit(login)', function (data) {
data = data.field; //将原生js对象转换成layUi里面的js对象
//alert(data.username+"--"+data.password) ;
if (data.username == '') {
layer.msg('用户名不能为空');
return false;
}
if (data.password == '') {
layer.msg('密码不能为空');
return false;
}
//忽略验证码
if (data.captcha == '') {
//layer.msg('验证码不能为空');
return true;
}
//jquery的ajax
$.ajax({
url:"/LayUI_war_exploded/admin_login",
type:"post",
//发送json数据---JSON.stringfy(
data: JSON.stringify(data) , //data {"username":xx","password":"xxx"}
//规定发送的数据格式是json格式
contentType:"applicaton/json",
success:function(resp){ //服务器响应数据---解析成json
//处理resp
layer.msg(resp.msg, function () {
window.location = '/LayUI_war_exploded/index.html';
})
},
dataType:"json" //服务器响应格式
})
/* layer.msg('登录成功', function () {
window.location = '/index.html';
});*/
return false;
});
});
</script>
</body>
LayUI异步登录2.servlet
@WebServlet("/admin_login")
public class AdminLoginServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//这种方式不适合:前端application/json 数据格式
//String username = request.getParameter("username");
//System.out.println(username);
//创建Map集合----存放前端提交所有参数
Map<String,Object> parms = new HashMap<>() ;
//获取前端提交的字节输入流
ServletInputStream inputStream = request.getInputStream() ;
//commons-IO-提供 IOUtils
//public String toString(InputStream inputstraem,String encoding)
//参数1:获取到post提交的内容 -- 保存在字节输入流中 (获取到流的内容)
//参数2:编码 :支持utf-8
String jsonStr = IOUtils.toString(inputStream, "utf-8");
System.out.println(jsonStr) ;//{"username":"李国栋","password":"123456","captcha":"xszg"}
//fastjson.jar包-- 工具栏JSON--将上面的这个json传解析成实体
//JSONObject parseObject(String text, Class<T> class):参数1:获取json串,参数2:将对应的内容存在实体中,当前类型的字节码文件
Map map = JSON.parseObject(jsonStr, Map.class);
//System.out.println(map) ;//{password=123456, captcha=xszg, username=梁飞虎}
parms.putAll(map) ;
//遍历parms
/* Set<Map.Entry<String, Object>> entries = parms.entrySet();
for(Map.Entry<String,Object> entry:entries){
//获取键和值
String key = entry.getKey();
String value = (String) entry.getValue();
System.out.println(key+"--"+value);
}*/
String username = (String) parms.get("username");
String password = (String) parms.get("password");
System.out.println(username+"---"+password) ;
//调用业务接口,通过用户名和密码完成登录逻辑
AdminService adminService = new AdminServiceImpl() ;
BaseResp baseResp = adminService.getAdminByName(username, password);
//解析成json格式
JSONObject jsonObject = new JSONObject() ;
String baseRespStr= jsonObject.toJSONString(baseResp);
System.out.println(baseRespStr) ;
response.setContentType("application/json;charset=utf-8");
response.getWriter().write(baseRespStr) ;
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request,response);
}
}
LayUI一步登陆3.service/dao
public class AdminServiceImpl implements AdminService{
/**
* 获取管理员信息,返回响应实体
* @param username 管理员名称
* @param password 密码
* @return 返回结果对象
*/
@Override
public BaseResp getAdminByName(String username, String password) {
try {
AdminDao adminDao = new AdminDaoImpl() ;
Admin admin = adminDao.selectAdminByName(username);
if(admin!=null){
//判断管理员密码
if(password.equals(admin.getPassword())){
return new BaseResp(0,"登录成功",null,null) ;
}
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}
//没有查到
return new BaseResp(1,"error",null,null) ;
}
}
public class AdminDaoImpl implements AdminDao {
@Override
public Admin selectAdminByName(String username) throws SQLException {
QueryRunner qr = new QueryRunner(DruidJdbcUtils.getDataSource()) ;
String sql = "select * from admin where username = ?" ;
Admin admin = qr.query(sql, new BeanHandler<>(Admin.class), username);
return admin;
}
}
@Data
@NoArgsConstructor
@AllArgsConstructor
public class BaseResp {
private Integer code ; //0表示数据,1表示没有数据
private String msg ; //消息字符串提示内容
private Object data ; //响应实际内容:实体或者list或者Map
private Integer count ; //总记录
}
LayUI表格使用
{
"title": "用户管理",
"href": "",
"icon": "fa fa-flag-o",
"target": "_self",
"child": [
{
"title": "查询用户",
"href": "/LayUI_war_exploded/page/admin/user_list.html",
"icon": "fa fa-stumbleupon-circle",
"target": "_self"
}
]
},
<head>
<meta charset="UTF-8">
<title>用户列表页面</title>
<meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<link rel="stylesheet" href="/LayUI_war_exploded/lib/layui-v2.5.5/css/layui.css" media="all">
<link rel="stylesheet" href="/LayUI_war_exploded/css/public.css" media="all">
</head>
<body>
<script type="text/html" id="toolbarDemo">
<div class="layui-btn-container">
<button class="layui-btn layui-btn-sm data-add-btn"> 添加用户 </button>
<!-- <button class="layui-btn layui-btn-sm layui-btn-danger data-delete-btn"> 删除用户 </button>-->
</div>
</script>
<!--删除-->
<script type="text/html" id="barDemo">
<a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="del">删除</a>
</script>
<!--layui的过滤属性值-->
<table class="layui-hide"
id="currentTableId"
lay-filter="currentTableFilter"></table>
<script type="text/html" id="currentTableBar">
<a href="shopadd.html" class="layui-btn layui-btn-xs data-count-edit" lay-event="edit">编辑</a>
<a class="layui-btn layui-btn-xs layui-btn-danger data-count-delete" lay-event="delete">删除</a>
</script>
</div>
</div>
<script src="/LayUI_war_exploded/lib/layui-v2.5.5/layui.js" charset="utf-8"></script>
<script src="/LayUI_war_exploded/lib/jquery-3.4.1/jquery-3.4.1.min.js" charset="utf-8"></script>
<script>
/*
* 加载和初始化模块 表单模块,表格模块
* */
layui.use([ 'table','util'], function () {
var table = layui.table, //给表格组件初始化
util = layui.util; //表格中的单元格编辑进行初始化
table.render({
//发送json数据
elem: '#currentTableId', //获取当前table标签对象
url: '/LayUI_war_exploded/findAllUser?page=1&limit=10', // 请求的后台接口
toolbar: '#toolbarDemo',
defaultToolbar: ['filter', 'exports', 'print', { //默认的工具栏: 右边:打印,导出,帅选列
title: '',
layEvent: 'LAYTABLE_TIPS',
icon: 'layui-icon-tips'
}],
//表格中的数据内容
cols: [[
{type: "checkbox", width: 50, fixed: "left"},
//field:实体属性名称
//tittle:列的标题名称
{field: 'uid', width: 80, title: '用户ID', sort: true},
{field: 'username', width: 80, title: '用户名'},
{field: 'password', width: 80, title: '密码'},
{field: 'name', width: 80, title: '真实姓名'},
{field: 'email', title: '邮箱', minWidth: 150},
{field: 'birthday', width: 80, title: '出生日期', sort: true},
{field: 'sex', width: 80, title: '性别'},
{title: '操作', minWidth: 50, templet: '#currentTableBar', fixed: "right", align: "center"}
]],
limit: 10,
page: true/*开启分页*/
});
//监听单元格编辑
//currentTableFilter table标签中的lay-filter属性值
table.on('edit(currentTableFilter)', function(obj){
var value = obj.value //得到修改后的值
,data = obj.data //得到所在行所有键值
,field = obj.field; //得到字段
// layer.msg('[ID: '+ data.id +'] ' + field + ' 字段更改值为:'+ util.escape(value));
});
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
//接收参数:page参数以及limit每页显示的条数
//默认第一页,每页显示15条
String page = request.getParameter("page");
String limit = request.getParameter("limit");
System.out.println(page+"---"+limit) ;
int page_number = Integer.parseInt(page) ;
int limit_number = Integer.parseInt(limit) ;
//调用AdminService
AdminService adminService = new AdminServiceImpl() ;
BaseResp baseResp = adminService.findUserByPage(page_number, limit_number) ;
//转换成json,响应前端
//FastJson
JSONObject jsonObject = new JSONObject();
String jsonString = jsonObject.toJSONString(baseResp);
System.out.println(jsonString);
response.setContentType("applicaton/json;charset=utf-8") ;
response.getWriter().write(jsonString);
}
前后端json数据
1.导包
<!--json解析工具:阿里提供的
可以将前端发送的json进行解析,
或者也可以后端获取到数据,转换成json,给前端
-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.78</version>
</dependency>
<!--commons-io-->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
2.前端json(post提交)
$.ajax({
url:"/LayUI_war_exploded/admin_login",
type:"post",
//发送json数据---JSON.stringfy(
data: JSON.stringify(data) , //data {"username":xx","password":"xxx"}
//规定发送的数据格式是json格式
contentType:"applicaton/json",
success:function(resp){ //服务器响应数据---解析成json
//处理resp
layer.msg(resp.msg, function () {
window.location = '/LayUI_war_exploded/index.html';
})
},
dataType:"json" //服务器响应格式
})
3.后端接收并响应json数据
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//这种方式不适合post提交:前端发送的application/json 数据格式
//String username = request.getParameter("username");
//System.out.println(username);
//创建Map集合----存放前端提交所有参数
Map<String,Object> parms = new HashMap<>() ;
//获取前端提交的字节输入流
ServletInputStream inputStream = request.getInputStream() ;
//commons-IO-提供 IOUtils
//public String toString(InputStream inputstraem,String encoding)
//参数1:获取到post提交的内容 -- 保存在字节输入流中 (获取到流的内容)
//参数2:编码 :支持utf-8
String jsonStr = IOUtils.toString(inputStream, "utf-8");//io流数据转换为字符串形式的数据
System.out.println(jsonStr) ;//{"username":"李国栋","password":"123456","captcha":"xszg"}
//fastjson.jar包-- 工具栏JSON--将上面的这个json传解析成实体
//JSONObject parseObject(String text, Class<T> class):参数1:获取json串,参数2:将对应的内容存在实体中,当前类型的字节码文件
Map map = JSON.parseObject(jsonStr, Map.class);
//System.out.println(map) ;//{password=123456, captcha=xszg, username=梁飞虎}
parms.putAll(map) ;
//遍历parms
/* Set<Map.Entry<String, Object>> entries = parms.entrySet();
for(Map.Entry<String,Object> entry:entries){
//获取键和值
String key = entry.getKey();
String value = (String) entry.getValue();
System.out.println(key+"--"+value);
}*/
String username = (String) parms.get("username");
String password = (String) parms.get("password");
//调用业务接口,通过用户名和密码完成登录逻辑
AdminService adminService = new AdminServiceImpl() ;
BaseResp baseResp = adminService.getAdminByName(username, password);
//解析成json格式
JSONObject jsonObject = new JSONObject() ;
String baseRespStr= jsonObject.toJSONString(baseResp);
response.setContentType("application/json;charset=utf-8");
response.getWriter().write(baseRespStr) ;
MyBatis
mybatis涉及的设计模式
mybatis核心配置文档结构
configuration(配置)
properties(属性)
settings(设置)
typeAliases(类型别名)
typeHandlers(类型处理器)
objectFactory(对象工厂)
plugins(插件)
environments(环境配置)
environment(环境变量)
transactionManager(事务管理器)
dataSource(数据源)
databaseIdProvider(数据库厂商标识)
mappers(映射器)
<?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">
<!--xx.dtd是xml文件约束,约束标签-->
<!--核心配置-->
<configuration>
<!--属性配置,加载外部配置文件-->
<properties resource="jdbc.properties"></properties>
<!--实体类的别名配置-->
<typeAliases>
<package name="com.qf.pojo"/>
</typeAliases>
<!--配置插件-->
<plugins>
<plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin>
</plugins>
<!--环境配置-->
<environments default="mysql">
<environment id="mysql">
<transactionManager type="JDBC"/>
<dataSource type="com.qf.datasource.MyDruidDataSourceFactory">
<property name="driverClassName" value="${jdbc.driverClassName}"/>
<!--连接数据库的地址-->
<property name="url" value="${jdbc.url}"/>
<!--用户名-->
<property name="username" value="${jdbc.username}"/>
<!--登录密码-->
<property name="password" value="${jdbc.password}"/>
<property name="maxActive" value="${jdbc.maxActive}"/>
</dataSource>
</environment>
<!--配置其他环境-->
</environments>
<!--加载mapper映射器-->
<mappers>
<!--配置接口的包名-->
<package name="com.qf.mapper"/>
</mappers>
</configuration>
属性配置properties
<!--属性配置,加载外部配置文件-->
<properties resource="jdbc.properties"></properties>
jdbc.properties文件:
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis_01?characterEncoding=utf-8
jdbc.username=root
jdbc.password=123456
jdbc.maxActive=10
类型别名配置typeAliases
方式1:指定一个包名,MyBatis 会在包名下面搜索需要的 Java Bean
<typeAliases>
<package name="com.qf.pojo"/>
</typeAliases>
方式2:
<!--type指定的当前实体类的完全限定名称
alias:实体的类别名(自己指定,见名知意)
这种方式麻烦(实体类很多,配置很多个typeAlias),可以直接指定实体类的包名
所有的实体类的包名就是默认当前类名(建议小写),不区分大小写
-->
<typeAlias alias="user" type="com.qf.pojo.User"></typeAlias>
<typeAlias alias="vouser" type="com.qf.pojo.VoUser"></typeAlias>
<typeAlias alias="queryvo" type="com.qf.pojo.QueryVo"></typeAlias>
配置插件plugins
分页插件:
<plugins>
<!--插件里面属性
interceptor指定当前拦截器
-->
<plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin>
</plugins>
环境配置environments,druid连接池
1.配置druid连接池
<!--环境配置,默认属于mysql数据库-->
<environments default="mysql">
<!--可以配置多个环境-->
<environment id="mysql">
<!--mybatis事务管理器,连接数据库操作-->
<transactionManager type="JDBC"/>
<!--启用druid连接池 -->
<dataSource type="com.qf.datasource.MyDruidDataSourceFactory">
<!--配置连接池这个类中的属性参数 -->
<!-- ${获取外部资源文件的key对应的内容} -->
<property name="driverClassName" value="${jdbc.driverClassName}"/>
<!--连接数据库的地址-->
<property name="url" value="${jdbc.url}"/>
<!--用户名-->
<property name="username" value="${jdbc.username}"/>
<!--登录密码-->
<property name="password" value="${jdbc.password}"/>
<property name="maxActive" value="${jdbc.maxActive}"/>
</dataSource>
</environment>
<!--配置其他环境-->
<!--<environment id="oracle">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment> -->
</environments>
自定义数据源工厂--提供德鲁伊的数据源DruidDataSource
public class MyDruidDataSourceFactory extends PooledDataSourceFactory {
public MyDruidDataSourceFactory(){
//给数据源进行初始化
this.dataSource = new DruidDataSource() ;//创建德鲁伊数据源
}
}
mybatis自带的连接池
<environment id="mysql">
<transactionManager type="JDBC"/>
<!--启用mybatis自带的连接池-->
<dataSource type="POOLED">
<!--配置连接池这个类中的属性参数
org.apache.ibatis.datasource.pooled.PooledDataSource信息
-->
<!--驱动类-->
<property name="driver" value="com.mysql.jdbc.Driver"/>
<!--连接数据库的地址-->
<property name="url" value="jdbc:mysql://localhost:3306/mybatis_01"/>
<!--用户名-->
<property name="username" value="root"/>
<!--登录密码-->
<property name="password" value="123456"/>
映射配置mappers
方式1.将包内的映射器接口实现全部注册为映射器
实体类的包名,实体名必须和resources文件下的实体类配置文件的结构一致
com.ddl.mapper.EmployeeDao
配置文件resources下:com.ddl.mapper.EmployeeDao.xml
<!--加载mapper映射器-->
<mappers>
<!--配置接口的包名,对应-->
<package name="com.qf.mapper"/>
</mappers>
方式2. 使用相对于类路径的资源引用
<mappers>
<!--配置多个mapper-->
<mapper resource="com/qf/mapper/UserDao.xml"></mapper>
<mapper resource="com/qf/mapper/ProductDao.xml"></mapper>
<mapper resource="com/qf/mapper/OrderDao.xml"></mapper>-->
</mappers>
数据访问接口Dao的配置
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--映射器的配置
namesapce:名称空间指定接口的完全限定名称
-->
<mapper namespace="com.qf.mapper.UserDao">
<!--大量的sql标签
id必须和接口文件中的方法名必须一致
当前接口中的方法有返回值,返回值如果是实体类型或者是List集合
输出映射:resultType必须要指定为当前实体类型的完全限定名称
输入映射 paramterType:如果当前接口中方法形式参数是一个实体类型,写上当前类的完全限定名称
如果形式参数String/int,写成String/int/Integer
mybatis中书写sql语句,也必须使用占位符号 #{实体类的属性名称一致}
-->
<!--插入用户-->
<insert id="addUser" parameterType="com.qf.pojo.User">
insert into user(username,gender,age,address) values(#{username},#{gender},#{age},#{address})
</insert>
<select id="findAll" resultType="com.qf.pojo.User">
select * from user
</select>
<!--更新用户-->
<update id="updateUser" parameterType="com.qf.pojo.User">
update user set username=#{username},gender = #{gender},age = #{age},address = #{address}
where id = #{id}
</update>
<!--删除用户-->
<delete id="deleteUser" parameterType="int">
delete from user where id = #{id}
</delete>
</mapper>
crud实现
public class MybatisTest {
private AccountDao accountDao ;
private UserDao userDao ;
private SqlSession sqlSession ;
@Before
public void init() throws IOException {
//1)读取resource下面的mybatis-config.xml文件
//org.apache.ibatis.io.Resources --InputStream getResourceAsStream(配置文件名称)
InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
//2)创建一个对象SqlSessionFactoryBuilder
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder() ;
//3)创建SqlSessionFactory
SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);//加载流对象 获取到工厂对象
//4)创建 SqlSession---就是执行对象--底层就是PreparedStatement
//SqlSession sqlSession = sqlSessionFactory.openSession();//自动提交
sqlSession = sqlSessionFactory.openSession(false);//手动提交
//5)获取AccountDao接口对象---通过mybatis的动态代理获取接口对象
//mybatis的写法
// accountDao = sqlSession.getMapper(AccountDao.class);//接口类型字节码文件
//ibatis的写法
//List<Object> objects = sqlSession.selectList("com.qf.mapper.AccountDao.findAllAccounts");
//使用动态代理,获得Dao接口的对象
userDao = sqlSession.getMapper(UserDao.class) ;
}
添加实现
@Test
public void testAddUser(){
//封装User对象
User user = new User() ;
user.setUsername("张蒋杰3") ;
user.setGender("男3") ;
user.setAge(23) ;
user.setAddress("宝鸡市3") ;
//调用方法
userDao.addUser(user);
}
}
@After
public void commitAndColose(){
//提交事务
sqlSession.commit();
sqlSession.close();
}
优化–别名配置
每一个在包 domain.blog 中的 Java Bean,在没有注解的情况下,会使用 Bean 的首字母小写的非限定类名来作为它的别名。 比如 domain.blog.Author 的别名为 author(不区分大小写);若有注解,则别名为其注解值。见下面的例子:
@Alias("author")
public class Author {
...
}
1.mybatis.xml核心配置中:
<typeAliases>
<package name="com.qf.pojo"/>
</typeAliases>
2. Dao.xml配置中
<!--<insert id="addUser" parameterType="com.qf.pojo.User" > 优化-->
<insert id="addUser" parameterType="user" > <!--不区分大小写-->
mybatis模糊查询的语法${} 和 #{}
1.占位符#{}
<select id="selectUsersByUserName" parameterType="java.lang.String" resultType="user">
select * from user where username like #{username}
</select>
<!--select * from user where username like concat(' %’,#{username}, ' %'
其中名为conat(‘%’,#{关键字},‘%’)-->
2.字符串拼接${}
使用字符串拼接符号 ${} 固定写法'%${value}%',不推荐,存在字符串拼接,可能导致sql注入
<select id="selectUsersByUserName" parameterType="java.lang.String" resultType="com.qf.pojo.User">
select * from user where username like '%${value}%'
</select>
模糊查询实现
@Test
public void testselectUsersByUserName(){
//List<User> users = userDao.selectUsersByUserName("%张%") ;
List<User> users = userDao.selectUsersByUserName("张") ;
if(users!=null || users.size()>0){
for(User user:users){
System.out.println(user);
}
}
}
mybatis关于添加用户的时候,获取到最后一次插入数据id值
<insert id="addUser" parameterType="user" > 方式二:在insert标签中useGeneratedKeys="true" keyProrerty="id"
<!--在插入的时候,获取id自增长主键的值,配置一些函数
selectKey
属性
keyColumn:表的主键字段名称,仅适用insert和update
keyProperty:实体类的属性名称,仅适用insert和update
resultType:返回值自增长主键的值类型
order:AFTER:在执行插入语句insert之后执行selectkey的语句获取最后一次id的值
-->
<selectKey keyColumn="id" keyProperty="id" resultType="int" order="AFTER">
<!--通过这个函数获取最后一次自增长主键的id值-->
SELECT LAST_INSERT_ID() ;
</selectKey>
insert into user(username,gender,age,address) values(#{username},#{gender},#{age},#{address})
</insert>
id主键自增长
public void testAddUser(){
//封装User对象
User user = new User() ;
System.out.println("插入前:"+user) ;
user.setUsername("张蒋杰3") ;
user.setGender("男3") ;
user.setAge(23) ;
user.setAddress("宝鸡市3") ;
//调用方法
userDao.addUser(user);
System.out.println("插入后:"+user); //显示自增长的id值
}
方式二:在insert标签中useGeneratedKeys="true"
<insert id="addUser" parameterType="user" >
通过uuid()查询主键
create table t_order(
id varchar (32)primary key, #字符型主键name varchar(50)
)default charset = utf8;
<mapper namespace="com.qf.mybatis.part1.basic.0rderDao">
<insert id="insert0rder" parameterType="order">
<selectKey keyProperty="id" resultType="String" order="BEFORE" ><!-- 插入之前-->
SELECT REPLACE (UUID(), '-','') <!--适用于字符类型主键-->
</selectKey>
INSERT INTO t_order(id, name) VALUES(#{id},#{name})
< /insert>
< /mapper>
mybatis多个参数传递
指定多个条件查询用户
方式1:使用mybatis参数绑定注解方式(推荐)
<!--#{}里面的内容需要和@Param里面的参数名称一致 -->
<select id="findUserByMultConditon" resultType="user">
select * from user where username = #{username} and address = #{address}
</select>
//dao层
//启用mybatis的@Param注解--指定绑定参数名称,这个参数名称就是等会需要赋值的参数,自定义(#{参数名称})
User findUserByMultConditon(@Param("username") String name, @Param("address") String addr) ;
方式2:按照参数的顺序进行查询,param1,param2...
<!--指定多个条件查询用户
按照参数的顺序进行查询,param1,param2....依次,不利于管理维护(不推荐)
-->
<select id="findUserByMultConditon" resultType="com.qf.pojo.User">
select * from user where username = #{param1} and address = #{param2}
</select>
dao:
User findUserByMultConditon(String name,String addr)
方式3:使用Map集合
<!-- #{}里面的内容需要和map集合的key一致 -->
<select id="findUserByMultConditon" resultType="com.qf.pojo.User">
select * from user where username = #{name} and address = #{addr}
</select>
dao:
//使用Map集合接收所有参数 --复杂类型
// User findUserByMultConditon(Map<String,String> map) ;
实现:
Map map = new HashMap() ;
map.put("name","黄老师") ;
map.put("addr","咸阳市") ;
User user = userDao.findUserByMultConditon(map);
方式4:使用自定义vo实体,将参数放在实体中
<!--通过vo实体查询指定的用户
参数形式QueryVo实体类型,里面包含另一个实体属性user属性
获取到QueryVo对象.getUser().getUsername():获取到用户名
一个实体类中的getXxx()里面xxx就是实体类的bean属性
ognl简写表达式 get()去掉,第一个字母小写
-->
<!--方法参数为对象时,可直接使用#{属性名}进行获取-->
<select id="findUserByQueryVo" parameterType="queryvo" resultType="user">
select * from user where username = #{user.username}
</select>
dao:
//通过自定义的实体类,将查询的参数封装到这个类中
User findUserByMultConditon(VoUser voUser) ;
实现:
VoUser voUser = new VoUser() ;
voUser.setName("高圆圆") ;
voUser.setAddr("西安市") ;
User user = userDao.findUserByMultConditon(voUser);
System.out.println(user);
@Data
@NoArgsConstructor
@AllArgsConstructor
public class QueryVo {
private User user ;
}
mybatis分页实现
导包
<!--mybatis的分页插件-->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.1.2</version>
</dependency>
@Test
public void testFindAll() throws IOException {
//通过mybatis的分页插件完成分页条件
//PageHelper父类有一个API---
//public static <E> Page<E> startPage(int pageNum, int pageSize)
//当前页码1,每页显示3条
PageHelper.startPage(1,3) ;
//6)调用方法
List<User> users = userDao.findAll(); //获取分页列表数据
//创建PageInfo对象
PageInfo pageInfo = new PageInfo(users) ;
System.out.println(pageInfo); //展示分页的数据
if(users!=null || users.size()>0){
for(User user :users){
System.out.println(user);
}
}
}
日志
Mybatis 通过使用内置的日志工厂提供日志功能。内置日志工厂将会把日志工作委托给下面的实现之一:
SLF4J
Apache Commons Logging
Log4j 2
Log4j
JDK logging
MyBatis 内置日志工厂会基于运行时检测信息选择日志委托实现。它会(按上面罗列的顺序)使用第一个查找到的实现。当没有找到这些实现时,将会禁用日志功能
步骤 1:添加 Log4J 的 jar 包
<!--log4j的日志包-->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
步骤 2:配置 Log4J.properties
# Set root category priority to INFO and its only appender to CONSOLE.
#log4j.rootCategory=INFO, CONSOLE debug info warn error fatal
# 全局日志配置
log4j.rootCategory=debug, CONSOLE, LOGFILE
# Set the enterprise logger category to FATAL and its only appender to CONSOLE.
log4j.logger.org.apache.axis.enterprise=FATAL, CONSOLE
#跟踪具体的接口或者接口中的指定方法
#log4j.logger.com.qf.mapper.UserDao.addEmployee=TRACE,跟踪接口中的指定方法
# 跟踪具体的接口
log4j.logger.com.qf.mapper.EmployeeDao=TRACE
# CONSOLE is set to be a ConsoleAppender using a PatternLayout.
#控制台输出
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=%d{ISO8601} %-6r [%15.15t] %-5p %30.30c %x - %m\n
#本地磁盘上产生日志文件
# LOGFILE is set to be a File appender using a PatternLayout.
log4j.appender.LOGFILE=org.apache.log4j.FileAppender
#自定义产生的日志文件路径
log4j.appender.LOGFILE.File=E:/Java/QFJava/mybatis_exercise/log4j.log
log4j.appender.LOGFILE.Append=true
log4j.appender.LOGFILE.layout=org.apache.log4j.PatternLayout
log4j.appender.LOGFILE.layout.ConversionPattern=%d{ISO8601} %-6r [%15.15t] %-5p %30.30c %x - %m\n
动态sql及常见标签
一.sql标签
<sql id="mySql"> 自定义id名称
select * from user
</sql>
<select id="findUserByCondition" resultMap="baseMap">
<include refid="mySql"></include> include标签引入动态sql
</select>
二:if标签
针对条件进行判断
mybatis提供动态sql语句之if标签对 条件的参数进行判断
if标签的test属性,判断赋值的参数是否为null
<select id="selectUserByUsername" parameterType="java.lang.String" resultMap="baseMap">
select * from user where 1 =1
<if test="userName!=null">
and username = #{userName}
</if>
<if test="userAddress!=null">
and address = #{userAddress}
</if>
</select>
三:where标签
代替sql语句中的where
<where>
<if test="userName!=null">
username = #{userName}
</if>
</where>
mybatis的where标签
当前if里面条件参数判断都不成立,最终select * from user where ,出现sql异常
当前if里面条件参数判断都不成立,使用where标签则没有约束条件
四:trim标签
trim:mybatis动态标签
帮助写sql语句的时候,指定前缀信息/指定后缀信息/忽略前缀信息/忽略后缀信息
prefix属性:指定前缀
prefixOverrides:忽略前缀 and | or
where条件里面第一个and或者or都可以省略
suffix=指定的后缀名称
suffixOverrid es:忽略后缀的信息
<select id="findUserByCondition" resultMap="baseMap">
<include refid="mySql"></include>
<trim prefix="where" prefixOverrides="and">
<where>
<if test="userName!=null">
username = #{userName}
</if>
<if test="userAddress!=null">
and address = #{userAddress}
</if>
</where>
</trim>
</select>
五:set标签
<update id="updateUser" parameterType="user">
<!--mybatis动态sql之set标签
加入动态标签:动态判断这参数值
-->
update user
<set>
<if test="userName!=null">
username = #{userName},
</if>
<if test="userGender!=null">
gender = #{userGender},
</if>
<if test="userAge!=null">
age = #{userAge},
</if>
</set>
<where>
<if test="userId!=null">
id = #{userId}
</if>
</where>
</update>
六:foreach标签
mybatis的foreach标签
collection:配置的集合属性
separator:分隔符号
open:以什么样的sql语句开头
close:以什么样的sql结尾
item:循环中的变量名
<select id="findUserByQueryVo" parameterType="queryvo" resultMap="baseMap">
<include refid="mySql"></include>
<where>
<foreach collection="ids" separator="," open="id in(" close=")" item="myId">
<!--和循环中的变量名一致-->
#{myId}
</foreach>
</where>
</select>
public class QueryVo {
private List<Integer> ids ; //list集合属性 属性名称ids
}
输出映射resultMap
数据库字段名和实体类字段名不一致
实体类的属性名和表字段不对应,只有字段名相同时自动映射,其他值为null
方式1:使用mybatis高级输出映射(结果映射)resultMap,它可以在里面配置实体类的属性名称和表的字段
<mapper namespace="com.qf.mapper.UserDao">
<!--使用resultMap,先定义resultMap
id,这个结果映射标识,必须唯一,
type:结果映射的结果集的类型
-->
<resultMap id="baseMap" type="user">
<!--配置实体的属性和表字段的一一对应
id指定主键字段和实体的属性名称
result:指定其他字段和实体类属性名称对应
column:表的字段名称
property:实体的属性名称
-->
<id column="id" property="userId"></id>
<result column="username" property="userName"></result>
<result column="gender" property="userGender"></result>
<result column="age" property="userAge"></result>
<result column="address" property="userAddress"></result>
</resultMap>
<select id="findAll" resultMap="baseMap">
SELECT u.*,a.id aid, a.`money`, a.uid FROM USER u, account a WHERE u.id = a.uid ;
</select>
方式2:查询sql的时候,指定字段别名,和实体类的属性名称对应
<select id="findAll" resultType="user">
SELECT id userId, username userName , gender userGender, age userAge , address userAddress FROM USER
</select>
mybatis配置映射关系 (xml配置)
配置映射关系:
mybatis的xml配置方式:
一对多
用户和账户
多对多
用户和角色
角色和权限
u
一对多配置:一个用户,多个账户
<mapper namespace="com.qf.mapper.UserDao">
<resultMap id="baseMap" type="user">
<id column="id" property="userId"></id>
<result column="username" property="userName"></result>
<result column="gender" property="userGender"></result>
<result column="age" property="userAge"></result>
<result column="address" property="userAddress"></result>
<!--一个用户多个账户,需要配置"多的一方",collection标签
property:包含的集合属性的属性名称, private List<Account> accounts ;
javaType:包含集合属性的类型:ArrayList
将数据最终查询出来存储在 accounts集合属性中,里面包含的javabean类型account
column="id" 通过id查询账户,用户的id,关联账户的uid
-->
<collection property="accounts" column="id" javaType="ArrayList" ofType="account">
<!--配置账户信息的一一对应-->
<id property="id" column="aid"></id>
<result property="money" column="money"></result>
<result property="uid" column="uid"></result>
</collection>
</resultMap>
<select id="findAll" resultMap="baseMap">
SELECT u.*,a.id aid, a.`money`, a.uid FROM USER u, account a WHERE u.id = a.uid ;
</select>
当查询表起别名时,查询的表结果的字段名称对应 column的名称
查询 a.id aid column="aid"
一对一:一个账户从属与一个用户
<mapper namespace="com.qf.mapper.AccountDao">
<!--定义resultMap-->
<resultMap id="accountUserMap" type="account">
<!--配置账户实体和账户表中字段一一对应
账户表的主键字段id起的别名它和user表的id一致
-->
<id property="id" column="aid"></id>
<result property="money" column="money"></result>
<result property="uid" column="uid"></result>
<!--配置映射一对一的映射关系
配置"一的一方" 使用association标签
property:当前包含的实体属性
javaType:javabean的实体类型
column:关联查询的时候关联字段名称(账户的uid和用户表id一致),关联查询的时候通过uid查询出用户,账户的uid关联用户的id
-->
<association property="user" javaType="user" column="uid" >
<!--用户信息-->
<id property="userId" column="id"></id>
<!--用户表的字段和实体属性对应-->
<result property="userName" column="username"></result>
<result property="userGender" column="gender"></result>
<result property="userAge" column="age"></result>
<result property="userAddress" column="address"></result>
</association>
</resultMap>
<!--查询所有账户
需要查询出来用户信息有哪些:多表关系(账户维度去用看用户,一对一)
一的一方法,需要配置
-->
<!--<select id="findAllAccount" resultType="account">-->
<select id="findAllAccount" resultMap="accountUserMap">
SELECT a.`id` aid,a.`money`,a.`uid`, u.`id`,u.`username`,u.`address` , u.`gender` , u.`age` FROM account a, USER u WHERE a.`uid` = u.`id` ;
</select>
</mapper>
mybatis延迟加载
mybatis延迟加载的处理方案1:单独处理
<!--查询所有用户-->
<select id="findAll" resultMap="baseMap">
select * from user
</select>
<!-- 延迟加载的处理方案1 单独处理,开启延迟加载,里面不能在配置账户信息
fetchType="lazy" 开启延迟加载
fetchType="eager" 不配置就是默认值,不开启延迟加载
select属性="查询账户接口里面的通过账户id获取账户信息"
-->
<resultMap id="baseMap" type="user">
<id column="id" property="userId"></id>
<result column="username" property="userName"></result>
<result column="gender" property="userGender"></result>
<result column="age" property="userAge"></result>
<result column="address" property="userAddress"></result>
<collection property="accounts" column="id" fetchType="lazy"
select="com.qf.mapper.AccountDao.findAccountById" javaType="ArrayList" ofType="account"> column="id" 用户id,关联账户
</collection>
</resultMap>
select="com.qf.mapper.AccountDao.findAccountById" ----- <select id="findAccountById"...
AccountDao中:
/**
* 通过账户id获取账户信息
* @param id 账户id
* @return 返回账户实体
*/
Account findAccountById(Integer id) ;
}
AccountDao.xml中:
<!--通过账户id查询账户信息-->
<select id="findAccountById" parameterType="java.lang.Integer" resultType="account">
select * from account
<where>
id = #{id}
</where>
</select>
测试:
public void testFindAll(){
List<User> all = userDao.findAll();
if(all!=null || all.size()>0){
System.out.println("用户信息是---->");
for(User user:all){
System.out.println(user);
List<Account> accounts = user.getAccounts();
for(Account account:accounts){
System.out.println("包含的账户信息是--->"+account);
}
}
}
延迟加载的处理方案2:xml全局配置
延迟加载的处理方案2:这块不指定 fetchType="lazy"
在mybatis-config.xml核心配置文件中配置全局加载开关("侵入式延迟加载/深度延迟加载")
<settings>
<!--开启延迟加载开关-->
<setting name="lazyLoadingEnabled" value="true"/>
<!--aggressiveLazyLoading 开启时,任一方法的调用都会加载该对象的所有延迟加载属性
mybatis3.4.1以前:true/现在必须为false
-->
<setting name="aggressiveLazyLoading" value="false"/>
</settings>
开启延迟加载方式:注解
开启延迟加载方式:注解
//配置多的一方法的信息,通过账户id查询账户信息,开启懒加载
@Result(property = "accounts",javaType = List.class,column = "id",
//配置多的一方法的信息,通过账户id查询账户信息,开启懒加载
many = @Many(select = "com.qf.dao.AccountDao.selectAccountById",
fetchType = FetchType.LAZY))}
mybatis的多对多配置
public class User {
private Integer id ; //用户id
private String username ;
private String gender ;
private String address ;
//一个用户包含多个角色信息
private List<Role> roles;
}
public class Role {
private Integer roleId ;
private String roleName ; // 角色名称
private String roleDesc ; //描述
//包含多个用户
private List<User> users ;
}
<mapper namespace="com.qf.dao.UserDao">
<resultMap id="userRoleMap" type="user">
<!--关联配置用户信息-->
<id property="id" column="id"></id>
<result property="username" column="username"></result>
<result property="gender" column="gender"></result>
<result property="address" column="address"></result>
<collection property="roles"
javaType="ArrayList" column="id" ofType="role">
<id column="rid" property="roleId"></id>
<result column="role_name" property="roleName"></result>
<result column="role_desc" property="roleDesc"></result>
</collection>
</resultMap>
<!--
查询所有用户,同时关联查询角色信息,根据中间表user_role建立多对多关系
-->
<select id="findAllUser" resultMap="userRoleMap">
SELECT u.*, r.id rid ,r.role_name, r.role_desc FROM user u, user_role ur, role r
WHERE u.id = ur.uid AND ur.`rid` = r.`id`
</select>
</mapper>
mybatis注解配置
mybatis注解开发,不需要使用接口映射文件,直接在接口上声明直接,里面指定sql语句
@Select:查询注解 代表映射文件中select标签
@Results注解 --xml里面reusltMap
id属性-->代表resultMap标签里面id属性
value属性的--->返回值是 注解类型Result[]
@Result(id = true,column = "id") 在resultMap标签定义的id标签
@Result(column = "",property = ) 在resultMap标签定义result标签
Many many() :many属性,配置"多的关系",---代表xml配置reusltMap里面的collection标签
它的返回结果@Many注解
One one():one属性,配置"一个的一方"---代表xml配置resultMap的assoaction标签
@ResultMap(values="上面注解的id属性内容") 引入上上面的每一个配置信息,单独可以不写value
Select一对多 many
/**
* 查询所用用户
* @return 返回用户列表
*/
@Results(id = "userMap",
value =
{ @Result(id = true,column = "id",property = "userId"),
@Result(column = "username",property ="userName" ),
@Result(column = "gender",property = "userGender"),
@Result(column = "age",property = "userAge"),
@Result(column = "address",property = "userAddress"),
//集合属性
@Result(property = "accounts",javaType = List.class,column = "id",
//配置多的一方法的信息,通过账户id查询账户信息,开启懒加载
many = @Many(select = "com.qf.dao.AccountDao.selectAccountById",
fetchType = FetchType.LAZY))}
)
@Select(value = "select * from user") //xml文件指定reulsetMap
List<User> findAll() ;
/**
* 通过账户id查询账户实体
* @param id 账户id
* @return
*/
@Select("select * from account where id = #{id}")
Account selectAccountById(Integer id);
/**
* 模糊搜索
* @param username
* @return
*/
@Select("select * from user where username like #{userName}")
//引用上面的配置,让实体的属性和表的字段一一对应
@ResultMap("userMap")
List<User> selectUserByUsername(@Param(("userName")) String username) ;
select 一对一
@Results(
id = "accountMap",value = {
@Result(id = true,column = "id",property = "id"),
@Result(column = "uid",property = "uid"),
@Result(column = "money",property = "money"),
//包含用户属性user
@Result(property ="user",column = "uid",
one = @One(select = "com.qf.dao.UserDao.findUserById",fetchType = FetchType.LAZY))
}
)
@Select("select * from user where id = #{userid}")
User selectUserById(@Param("userid") Integer id) ;
mybatis和servlet整合
1.MyBatisUtil工具类
public class MyBatisUtil {
private MyBatisUtil(){}
//声明一个静态变量
private static SqlSession sqlSession ;
private static SqlSessionFactory sqlSessionFactory ;
//创建一个静态实例
//每一个线程使用自己的SqlSession,连接数据库进行操作
private static ThreadLocal<SqlSession> tl = new ThreadLocal<>() ;
//静态代码块---获取到SqlSession (mybatis一级缓存:默认就是sqlSession)
static{
//1)读取mybatis-config.xml文件
try {
InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
//创建SqlSessionFactoryBuilder---它创建工厂对象
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder() ;
sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream) ;
//创建SqlSession
sqlSession = sqlSessionFactory.openSession();
} catch (IOException e) {
e.printStackTrace();
}
}
//2)定义一个获取SqlSession
public static SqlSession openSession(){
//从当前线程先获取
SqlSession sqlSession = tl.get();
if(sqlSession==null){
//说明当前正在执行的线程没有SqlSession
//从连接池获取SqlSession(SqlSessionFactory获取sqlSession)
sqlSession = sqlSessionFactory.openSession();
//将当前这个sqlSession绑定到线程上
tl.set(sqlSession) ;
}
return sqlSession;
}
//3)提交事务
public static void commitAndClose(){
SqlSession sqlSession = openSession();
sqlSession.commit();
sqlSession.close() ;
}
//4)事务回滚
public static void rollbackAndClose(){
SqlSession sqlSession = openSession();
sqlSession.rollback();
sqlSession.close();
}
//5)定义一个方法:获取任意接口类型的子实现类对象(mybatis动态代理实现)
//将泛型定义在方法上 -->方法返回值上<T>
//方法的形式参数:任意java类型的字节码文件对象
public static <T extends Object> T getMapper(Class<T> clazz){
return sqlSession.getMapper(clazz) ;
}
}
2.业务接口实现
public class UserServiceImpl implements UserService {
//声明UserDao类型变量
private UserDao userDao ;
@Override
public BaseResult checkUser(String username) {
//调用dao层接口---mybatis实现
SqlSession sqlSession = MyBatisUtil.openSession() ;
userDao = sqlSession.getMapper(UserDao.class);
User user = userDao.selectUserByUsername(username);
//封装BaseResult对象
BaseResult reuslt ;
if(user!=null){
//存在,找到了
return reuslt = new BaseResult(0,"用户名太受欢迎,请更换",null,null) ;
}
return reuslt = new BaseResult(1,"恭喜您,可用",null,null) ;
}
}
3.servlet
@WebServlet("/checkUser")
public class CheckUserServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//mybatis_02_war_exploded/checkUser?username="+username
//接收参数
String username = request.getParameter("username") ;
//调用业务接口
UserService userService = new UserServiceImpl() ;
BaseResult baseResult = userService.checkUser(username) ;
//通过fastjson解析工具解析json
JSONObject jsonObject = new JSONObject() ;
String jsonString = jsonObject.toJSONString(baseResult);
//设置解决响应json的中文乱码
response.setContentType("application/json;charset=utf-8");
System.out.println(jsonString);
//响应
response.getWriter().write(jsonString);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request,response);
}
4.druid配置
<environments default="mysql">
<!--可以配置多个环境-->
<environment id="mysql">
<transactionManager type="JDBC"/>
<!--启用mybatis自带的连接池-->
<!--
启用druid连接池
-->
<!-- <dataSource type="POOLED">-->
<dataSource type="com.qf.datasource.MyDruidDataSourceFactory">
<property name="driverClassName" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<!--登录密码-->
<property name="password" value="${jdbc.password}"/>
<!-- <property name="maxActive" value="${jdbc.maxActive}"/>-->
</dataSource>
</environment>
</environments>
public class MyDruidDataSourceFactory extends PooledDataSourceFactory {
public MyDruidDataSourceFactory(){
this.dataSource = new DruidDataSource() ;
}
5.前端页面
<html lang="en">
<head>
<meta charset="UTF-8">
<title>注册页面</title>
<script src="/mybatis_02_war_exploded/js/jquery-3.4.1.min.js"></script>
<script>
//Jqeury的页面载入事件
$(function(){
//用户名失去焦点事件
$("#username").blur(function(){
//通过jquery的方式获取用户名的内容
var username = $("#username").val() ;
alert(username) ;
//获取id="tip"的jq标签对象
var span = $("#tip") ;
//发送ajax
$.ajax({
url:"/mybatis_02_war_exploded/checkUser?username="+username+"",
type: "get",
success:function (data){ //服务器响应成功的回调函数
if(data.code==0){ //{"code":1,"msg":"消息内容"}
//不可用
//span标签设置文本
span.html(data.msg) ;
span.css("color","red") ;
}
if(data.code==1){ //{"code":0,"msg":"消息内容"}
//不可用
//span标签设置文本
span.html(data.msg) ;
span.css("color","green") ;
}
},
dataType:"json"
}) ;
}) ;
}) ;
</script>
</head>
<body>
<form>
用户名:<input type="text" id="username" placeholder="请输入用户名"/>
<span id="tip"></span><br/>
密码:<input type="password" placeholder="请输入密码"/><br/>
邮箱:<input type="text" placeholder="请输入邮箱"/><br/>
<input type="submit" value="注册"/>
</form>
</body>
</html>
mybatis逆序工程
<!--在依赖下面加入指定的插件配置-->
<build>
<plugins>
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>1.3.2</version>
<!--覆盖工程并配置指定的逆向工程配置文件-->
<configuration>
<verbose>true</verbose>
<overwrite>true</overwrite>
<configurationFile>${project.basedir}/src/main/resources/generator-config.xml</configurationFile>
<!--文件/src/main/resources/下生成generator-config.xml文件-->
</configuration>
<dependencies>
<!--引入mysql驱动,版本不能太高-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.25</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
配置好jdbc.properties文件内容(driverClassName,url,username,password)
添加 mybatis-generator 配置文件 generatorCong.xml文件
mybatis逆序工程xxxExample的使用
public class MyBatisTest {
private UserMapper userMapper ;
private SqlSession sqlSession ;
// private AccountDao accountDao ;
@Before//执行单元测试方法之前执行
public void init() throws IOException {
InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
//2)创建一个对象SqlSessionFactoryBuilder
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder() ;
//3)创建SqlSessionFactory
SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);//加载流对象 获取到工厂对象
//4)创建 SqlSession---就是执行对象--底层就是PreparedStatement
sqlSession = sqlSessionFactory.openSession(true);//自动提交
userMapper = sqlSession.getMapper(UserMapper.class) ;
// accountDao = sqlSession.getMapper(AccountDao.class) ;
}
@Test
public void test1(){
//逆序工程生成实体类中xxxExample都是设置设置条件参数,相当于where后面的哪些
//创建user条件对象 UserExample
UserExample userExample = new UserExample() ;
//创建实际条件的参数--->xxExample里面的方法
//public Criteria createCriteria()
//通过id查询 :设置id是某个值
//Criteria是xxxExample的内部类
//通过id查询∶设置id是某个值
//userExample.createCriteria().andIdEqualTo( value: 2) ;
UserExample.Criteria criteria = userExample.createCriteria();
criteria.andUsernameEqualTo("张三丰") ;
//创建User对象
User user = new User() ;
user.setUsername("李国栋") ;
user.setAge(23);
//update user set username = "值",age= 23 where username = "张三丰" ;
//逆序工程里面的自带的api方法
int count = userMapper.updateByExampleSelective(user, userExample);
System.out.println(count);
}
@Test
public void test2(){
//通过主键,不需要设置条件xxxExample进行修改
//int updateByPrimaryKey(User user):自己设置你的参数信息
//int updateByPrimaryKeySelective(User record); 通过主键修改,自定义参数
User user = new User() ;
user.setUsername("李四") ;
user.setAge(25) ;
user.setGender("女") ;
user.setId(4);
int count = userMapper.updateByPrimaryKey(user);
System.out.println(count);
}
}
自定义工厂_解析xml文件
1.导包
<!--dom4j解析xml文件的-->
<dependency>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>1.6.1</version>
</dependency>
<!--dom4j里面依赖包-->
<dependency>
<groupId>jaxen</groupId>
<artifactId>jaxen</artifactId>
<version>1.1-beta-6</version>
</dependency>
2.自定义工厂
public class BeanFactory {
private BeanFactory(){}//外界不能new
//对外提供公共的访问方法
/**
* 解析bean.xml文件的方法
* @param id bean标签里面 id标识
* @return 返回实例对象
*/
public static Object getBean(String id) {
Object obj = null;
try {
//设置工厂实现类(dom4j的版本原因)
System.setProperty("javax.xml.parsers.DocumentBuilderFactory",
"com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl");
//解析xml文件
//使用dom4j--pom文件中引入 核心的dom4j的jar包
//创建dom4j解析器 SAXReader
SAXReader saxReader = new SAXReader() ;
//读取文件
InputStream inputStream = BeanFactory.class.getClassLoader().getResourceAsStream("bean.xml");
//bean.xml文档对象Document
Document doc = saxReader.read(inputStream);
//获取到根标签 beans标签对象
Element beansElement = doc.getRootElement();
System.out.println(beansElement );
//使用dom4j里面技术---xpath技术:快递定位到某个标签
//不分层级选中bena标签--指定id属性的标签
// xpath表达式 "//bean[@id='"+id+"']" //里面id传进去的变量
Element beanElem = (Element) doc.selectSingleNode("//bean[@id='" + id + "']"); //Node节点对象--->指定Element对象
//通过bena标签对象获取class属性的内容
String className = beanElem.attributeValue("class");
System.out.println(className) ;//接口实现类的完全限定名称
//通过反射:创建这个类的实例
Class clazz = Class.forName(className);
//直接创建实例
obj = clazz.newInstance();
return obj ;
} catch (DocumentException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return null ;
}
public static void main(String[] args) throws
DocumentException, ClassNotFoundException, InstantiationException, IllegalAccessException {
UserService userService = (UserService) BeanFactory.getBean("userService");
System.out.println(userService) ;
}
}
3.bean.xml文件
<beans>
<!--
管理service层:业务层
定义子标签bean
id标签:代表当前唯一标识 起名字:"业务层接口名,首字母小写"
class标签:指定接口实现类的完全限定名称
-->
<bean id="userService" class="com.qf.service.impl.UserServiceImpl"></bean>
<bean id="userDao" class="com.qf.dao.impl.UserDaoImpl"></bean>
<!--很多很多bean标签-->
<!--<bean id="ProductService" class="com.qf.service.impl.UserServiceImpl"></bean>
<bean id="userService" class="com.qf.service.impl.UserServiceImpl"></bean>
</beans>
4.service层实现
public class UserServiceImpl implements UserService {
//声明UserDao类型 变量
private UserDao userDao ;
@Override
public BaseResult checkUser(String username) {
//调用dao层接口---mybatis实现
SqlSession sqlSession = MyBatisUtil.openSession() ;
userDao = sqlSession.getMapper(UserDao.class);
User user = userDao.selectUserByUsername(username);
//封装BaseResult对象
BaseResult reuslt ;
if(user!=null){
//存在,找到了
return reuslt = new BaseResult(0,"用户名太受欢迎,请更换",null,null) ;
}
return reuslt = new BaseResult(1,"恭喜您,可用",null,null) ;
}
}
5.servlet层实现
@WebServlet("/checkUser")
public class CheckUserServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//mybatis_02_war_exploded/checkUser?username="+username
//接收参数
String username = request.getParameter("username") ;
//调用业务接口
//存在耦合性(开发原则:低耦合,高内均)
//UserService userService = new UserServiceImpl() ;
//自定义工厂,解析bean.xml --解耦
UserService userService = (UserService) BeanFactory.getBean("userService");
BaseResult baseResult = userService.checkUser(username) ;
//通过fastjson解析工具解析json
JSONObject jsonObject = new JSONObject() ;
String jsonString = jsonObject.toJSONString(baseResult);
//设置解决响应json的中文乱码
response.setContentType("application/json;charset=utf-8");
System.out.println(jsonString);
//响应
response.getWriter().write(jsonString);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request,response);
}
}
Spring
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-r823GSq4-1683856101497)(C:\Users\15399\AppData\Roaming\Typora\typora-user-images\image-20230512094736532.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yBMvSS0z-1683856101497)(C:\Users\15399\AppData\Roaming\Typora\typora-user-images\image-20230512094751699.png)]
导包
<!--spring的全局的jar包-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.5.RELEASE</version>
</dependency>
spring-congig配置
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context" 注解开启
xmlns:p="http://www.springframework.org/schema/p" p标签使用
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context 注解开启
https://www.springframework.org/schema/context/spring-context.xsd"> 注解开启
<bean>xxxx</bean>
<bean>xxxx</bean>
<bean>xxxx</bean>
</beans>
依赖注入xml配置方式
1.set方法
<!--通过引入的spring配置文件,通过bean标签管理指定的类
id="这个类(bean)唯一标识",你自己可以定义,默认当前这个类或者接口名的首字母小写
class="这个类的完全限定名称 包名.类名"
SpringIOC:控制反转 ,通过spring容器管理多个bean,以及管理bean的一些数据的注入
(依赖注入DI:Dependency Injection)
给com.qf.pojo.TabUser注入它的属性数据 -->
实体类
public class TabUser {
private int id ; //用户编号
private String name ; //用户名
private int age ;//年龄
private String gender ;//性别
public void setTabUserInfo(TabUserInfo tabUserInfo) { //另一个引用类型
this.tabUserInfo = tabUserInfo;
}
//包含另一个用户详情属性
private TabUserInfo tabUserInfo ;
public TabUser() {
}
//有参构造方法
public TabUser(int id, String name, int age, String gender,TabUserInfo tabUserInfo) {
this.id = id;
this.name = name;
this.age = age;
this.gender = gender;
this.tabUserInfo = tabUserInfo ;
}
// private TabUserInfo tabUserInfo ;
//提供set方法
public void setId(int id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public void setGender(String gender) {
this.gender = gender;
}
实体类关联
public class TabUserInfo {
private String address ; //用户家庭住址
private String cardId ;// 用户身份id
private String hobby ; //爱好
public void setAddress(String address) {
this.address = address;
}
public void setCardId(String cardId) {
this.cardId = cardId;
}
public void setHobby(String hobby) {
this.hobby = hobby;
}
public TabUserInfo() {
}
public TabUserInfo(String address, String cardId, String hobby) {
this.address = address;
this.cardId = cardId;
this.hobby = hobby;
}
方式1:setXXX注入(set方法注入)
bean标签
property标签:
name:属性名
value:属性值 (属性的类型都是基本类型或者是String)
ref:关联另一个引用数据类型的id值(bean的id)
<bean id="tabUser" class="com.qf.pojo.TabUser">
<property name="id" value="1"></property>
<property name="name" value="高圆圆"></property>
<property name="age" value="44"></property>
<property name="gender" value="女"></property>
<!--日期格式: value="xxxx/xx/xx"-->
<!--关联另一个引用数据类型-->
<property name="tabUserInfo" ref="tabUserInfo"></property>
</bean>
<bean id="tabUserInfo" class="com.qf.pojo.TabUserInfo">
<property name="address" value="南窑国际92排"></property>
<property name="cardId" value="61012519980707007X"></property>
<property name="hobby" value="跑步"></property>
</bean>
//使用spring方式给tabUser进行数据的注入
//1)创建Spring容器
//public ClassPathXmlApplicationContext(String configLocation) :读取spring的核心配置文件
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-config.xml") ;
//直接从类路径上读取配置文件(resource目录)
//获取bean的实例
//getBean(当前类的字节码文件/字符串标识),返回任意java对象Object
TabUser mytabuser = (TabUser) applicationContext.getBean("tabUser");//参数:是spring核心配置文件中的bean的id
System.out.println(mytabuser);
2.构造器注入
当前类中有构造方法
<!--springIOC依赖注入方式2:构造器注入
constructor-arg
name:属性名称
value:基本数据类型或者String类型:实际值
ref:关联另一个引用类型的bean标签id值
-->
<bean id="tabUser" class="com.qf.pojo.TabUser">
<constructor-arg name="id" value="2"></constructor-arg>
<constructor-arg name="name" value="宜三宝"></constructor-arg>
<constructor-arg name="age" value="24"></constructor-arg>
<constructor-arg name="gender" value="男"></constructor-arg>
<!--构造器注入:关联另一个引用数据类型 -->
<constructor-arg name="tabUserInfo" ref="tabUserInfo"></constructor-arg>
</bean>
3.p标签
前提:实体类中有set方法
xmlns:p="http://www.springframework.org/schema/p" p标签使用
<!--依赖注入的第三种方式:p标签注入
1)需要配置文件中引入约束文件 p标签
xmlns:p="http://www.springframework.org/schema/p"放在头文件上
2)在当前类中必须有set方法...
p:属性名称= 值 除过String特殊引用类型/基本类型
p:属性名称-ref="当前这个属性的返回值是其他引用类型"
-->
<bean id="tabUser" class="com.qf.pojo.TabUser" p:id="3" p:name="张三丰" p:age="50" p:gender="男" p:tabUserInfo-ref="tabUserInfo" >
</bean>
<bean id="tabUserInfo" class="com.qf.pojo.TabUserInfo" p:address="西安市丈八四路陕西大会堂" p:cardId="61012519980707009X" p:hobby="马拉松"></bean>-->
依赖注入: 数组\set集合\map集合\Properties:属性集合列表\list集合
@Data//setXXX/getxXX()/toString()
@NoArgsConstructor//Student()
@AllArgsConstructor //Student(所有参数)
public class Student {
//private int sId ; //sid
//private String sName ; //sname
//属性名字母小写
private int sid ;
private String sname;
private String sgender ;
private int sage ;
private Date sbirthDay ;
//数组类型
private String hobby[] ;
//set集合集合类型
private Set<String> addresses ;
//Map集合
private Map<String,String> map ;
//属性列表java.util.Properties 没有泛型,本质是map ,键和值都是String
private Properties properties;
private List<String> list ;
}
<bean id="student" class="com.qf.pojo.Student">
<property name="sid" value="5"></property>
<property name="sname" value="李国栋"></property>
<property name="sgender" value="男"></property>
<property name="sage" value="25"></property>
<property name="sbirthDay" value="1994/05/30"></property>
<!--数组类型-->
<property name="hobby">
<array>
<value>跑步</value>
<value>健身</value>
<value>敲代码</value>
<value>看电影</value>
</array>
</property>
<!--set集合类型-->
<property name="addresses">
<set>
<value>立人科技B座</value>
<value>南窑国际</value>
</set>
</property>
<!--map集合类型-->
<property name="map">
<map>
<!--指定键值对的内容-->
<entry key="id" value="1"></entry>
<entry key="name" value="王五"></entry>
<entry key="gender" value="女"></entry>
</map>
</property>
<!--java.util.Properties:属性集合列表-->
<property name="properties">
<!--存储多个属性名称和内容-->
<props>
<prop key="zhangsan" >30</prop>
<prop key="lisi" >40</prop>
<prop key="wangwu" >25</prop>
</props>
</property>
<!--list集合类型-->
<property name="list">
<list>
<value>hello</value>
<value>world</value>
<value>javaee</value>
<value>Spring</value>
</list>
</property>
</bean>
依赖注入:注解方式
Spring开启注解
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context" 注解开启
xmlns:p="http://www.springframework.org/schema/p" p标签使用
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context 注解开启
https://www.springframework.org/schema/context/spring-context.xsd"> 注解开启
<!--上面引入约束文件
spring-beans.xsd约束文件
开启spring的注解:在配置文件配置注解的开启
-->
<!--扫描com.qf包下的所有的注解 -->
<context:component-scan base-package="com.qf"/>
注解的使用
Spring提供很多注解
一.创建对象的注解: Spring通过解析xml文件,通过class属性内容创建对象
@Component:通用的注解: <bean id="标识" class="完全限定名称"></bean>
@Service :在业务接口实现中使用的,管理业务层对象(xxxServceImpl...)
@Controller:在Servlet里面创建对象,交给spring来创建
@Repository:在dao层实现类出创建对象,交个Spring
二.注入的注解
@AutoWired:自动装配:默认是按照类型注入(如果注入的这个类型只有一个类型,可以直接自动注入)
如果注入的类型:有多个(举例:UserDaoImpl2/UserDaoImpl都是实现同一个接口);
不能使用@AutoWired:,必须结合下面这个注解Qualifier
@Qualifier("指定注入的名称") ---类似于bean的id (注入的名称:默认当前类名首字母小写)
//单独使用
@Resource:name属性
type属性,当前内名.class字节码文件
1.创建对象的注解:
当接口只有一个实现类时,在对应实现类上注解@Service 或者@Repository ,可以通过接口的字节码文件直接获取接口的实现子类
applicationContext.getBean(接口的字节码文件,接口名.class)
@Service
public class UserServiceImpl implements UserService {
public UserDaoImpl({
System.out.println( "UserService层对象被创建了");
}
}
@Repository("userDao")
public class UserDaoImpl implements UserDao{
public UserDaoImpl({
System.out.println( "dao层对象被创建了");
}
@Test
public void testUserService(){
//测试dao层
UserDao userDao = (UserDao) applicationContext.getBean("userDao");//通过标识获取
System.out.println(userDao);
System.out.println("--------------------------");
UserService userService2 = applicationContext.getBean(UserService.class);//直接指定接口字节码文件
System.out.println(userService2); //获取到UserServiceImpl对象
}
2.注入的注解
1) @Autowired
private UserDao userDao ; 自动装配:默认是按照类型注入(如果注入的这个类型只有一个类型,可以直接自动注入)
2) @Resource(name=“userDAO”,type=UserDaoImpl.class)
private UserDao userDao ;
3) @Autowired
@Qualifier(value = "userDaoImpl") 如果当前接口有两个实现类注解均没写标识,则默认使用当前类名首字母小写注入,进行区分
private UserDao userDao;
@Repository 没写标识,则默认使用当前类名首字母小写userDaoImpl
public class UserDaoImpl implements UserDao{
@Repository 没写标识,则默认使用当前类名首字母小写userDaoImpl2
public class UserDaoImpl2 implements UserDao{
Spring整合juint
Spring整合junit单元测试
1)导包:spring-test.jar包(版本必须和spring-context.jar包版本一致/或者比它的版本低)
2)使用spring-test注解:读取到类路径下的spring-config.xml文件
@ContextConfiguration: location :指定资源文件
3)单元测试类上面加入@RunWith:启用Spring单元测试的启动器 SpringJUnit4ClassRunner这个类
Class<? extends Runner> value(); value属性返回就是指定spring启动类
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:spring-config.xml") //这个过程---加载spring核心配置文件,创建Srping容器了
public class MyTest {
//注入XxxService
@Autowired //自动注入
private UserService userService ; //声明变量
@Test//junit的单元测试
public void test1(){
String message = userService.getMessage();
System.out.println(message);
}
1. xml配置文件方式注入:
<bean id="userSerivce" class="com.qf.service.impl.UserServiceImpl">
<property name="userDao" ref="userDao"></property>
</bean>
<bean id="userDao" class="com.qf.dao.impl.UserDaoImpl"></bean>
public class UserServiceImpl implements UserService {
//set注入
private UserDao userDao ;
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
public String getMessage() {
//调用dao层
return userDao.selectMesage();
}
}
public class UserDaoImpl implements UserDao {
@Override
public String selectMesage() {
return "hello,SpringIOC!!" ;
}
2.注解方式
@Service //<bean id="userSerivce" class="com.qf.service.impl.UserServiceImpl">
public class UserServiceImpl implements UserService {
//自动装配
@Autowired
private UserDao userDao ;
@Override
public String getMessage() {
//调用dao层
return userDao.selectMesage();
}
}
@Repository
public class UserDaoImpl implements UserDao {
@Override
public String selectMesage() {
return "hello,SpringIOC!!" ;
}
}
SpringIOC管理bean对象的生命周期
spring生命周期
bean标签提供一些属性
init-method:指定初始化方法(对象的初始化操作)
destroy-method:指定销毁方法
scope="singleton",bean的依赖范围:默认的单例 singleton
(在内存中始终只有一个对象-关联到单例设计模式:饿汉/懒汉式)
prototype:多例模式 (多线程环境下,每一个用户都要发送请求)
内存中创建多个对象,地址值不一样
lazy-init:指定true/false,是否懒加载初始化
<bean id="tabUser"
init-method="init"
scope="singleton"
destroy-method="destroy" //容器关闭后执行
class="com.qf.pojo.TabUser "/>
//给类配置@Scope依赖范围,
@Scope(value = "singleton")//默认单例
@Component//通用的spring创建对象的注解
public class TabUser {
//无参构造方法
public TabUser(){
System.out.println("tabUser被Spring容器创建了");
}
//初始化方法
public void init(){
System.out.println("init方法被调用了...");
}
//销毁方法
public void destroy(){
System.out.println("destroy方法被调用了...");
}
}
@Test
public void test2(){
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext(
"spring-config.xml");
TabUser tabUser = (TabUser) applicationContext.getBean("tabUser") ;
System.out.println(tabUser) ;
//第二次获取
TabUser tabUser2= (TabUser) applicationContext.getBean("tabUser") ;
System.out.println(tabUser2) ;
System.out.println(tabUser==tabUser2) ;
applicationContext.close(); //关闭容器了
}
注解方式使用Spring生命周期
@Scope(value = "singleton")//默认单例
@Component//通用的spring创建对象的注解
public class TabUser {
//无参构造方法
public TabUser(){
System.out.println("tabUser被Spring容器创建了");
}
//初始化方法
@PostConstruct
public void init(){
System.out.println("init方法被调用了...");
}
//销毁方法
@PreDestroy
public void destroy(){
System.out.println("destroy方法被调用了...");
}
Spring_mybatis_servlet整合
1.spring整合包
<!--spring-context的核心包-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.5.RELEASE</version>
</dependency>
<!--mybatis整合spring的jar包-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.4</version>
</dependency>
<!--spring-jdbc.jar包 配置数据源,代替mybatis事务管理器-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.5.RELEASE</version>
</dependency>
<!--spring里面的单元测试:和junit进行整合-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.2.5.RELEASE</version>
</dependency>
2.spring_config配置
<!--开启spring注解,扫描指定包下下的spring注解-->
<context:component-scan base-package="com.qf"/>
<!--配置数据源来自于 Spring-jdbc.jar包
DriverManagerDataSource:驱动管理器,可以配置数据库连接信息
-->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<!--set注入连接信息-->
<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql://localhost:3306/myee2302_db_2"></property>
<property name="username" value="root"></property>
<property name="password" value="123456"></property>
</bean>
<!--mybatis和spring整合包提供,配置SqlSessionFactoryBean-->
<bean id="sqlSessionFactoryBean" class="org.mybatis.spring.SqlSessionFactoryBean">
<!--配置数据源-->
<property name="dataSource" ref="dataSource"></property>
<!--配置实体类的包名,实体类的别名就是当前类名,不区分大小写-->
<property name="typeAliasesPackage" value="com.qf.pojo"></property>
<!--配置dao层映射文件的加载-->
<property name="mapperLocations" value="classpath:mapper/*Mapper.xml"></property>
</bean>
<!--mybatis和spring整合包里面,配置mapper/dao层的包扫描
id名称必须="mapperScannerConfigurer"
-->
<bean id="mapperScannerConfigurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!--配置basepackage,扫描dao层接口的包-->
<property name="basePackage" value="com.qf.mapper"></property>
<!--配置指定sqlSessionFactoryBeanName,指定上面org.mybatis.spring.SqlSessionFactoryBean它的id-->
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactoryBean"></property>
</bean>
</beans>
3.servlet
@WebServlet("/findAll")
public class FindAllServlet extends HttpServlet {
private ProductService productService ;
//当前在访问"/findAll"通过web容器创建Servlet对象
//执行无参构造方法
public FindAllServlet(){
//读取spring-config.xml核心配置文件
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-config.xml");
productService = applicationContext.getBean(ProductService.class);
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//调用业务接口
List<Product> allProducts = productService.getAllProducts();
//Fastjson
JSONObject object = new JSONObject() ;
String str = object.toJSONString(allProducts);
//设置响应乱码
response.setContentType("application/json;charset=utf-8");
response.getWriter().write(str);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request,response);
}
}
4.service
@Service
public class ProductServiceImpl implements ProductService {
//注入ProductMapper
@Autowired
private ProductMapper productMapper ;
@Override
public List<Product> getAllProducts() {
List<Product> products = productMapper.selectAllProducts();
if(products!=null || products.size()>0){
return products ;
}
return null ;
}
}